001/* 002 * Renderer 9. The MIT License. 003 * Copyright (c) 2022 rlkraft@pnw.edu 004 * See LICENSE for details. 005*/ 006 007package renderer.scene; 008 009/** 010 A {@code Vector} object holds four doubles, which makes it a vector 011 in 4-dimensional space. 012<p> 013 In computer graphics, we use 4-dimensional homogeneous coordinates 014 to represent vectors (and points) in 3-dimensional space. 015<p> 016 Unlike a homogeneous {@link Vertex}, a homogeneous {@code Vector} usually 017 has its fourth coordinate set to 0. 018*/ 019public final class Vector 020{ 021 public final double x, y, z, w; // a vector in homogenous coordinates 022 023 /** 024 Construct a new {@code Vector} using the given x, y, and z coordinates. 025 026 @param x x-coordinate of the new {@code Vector} 027 @param y y-coordinate of the new {@code Vector} 028 @param z z-coordinate of the new {@code Vector} 029 */ 030 public Vector(final double x, final double y, final double z) 031 { 032 this(x, y, z, 0.0); 033 } 034 035 036 /** 037 Construct a new {@code Vector} using the given x, y, z, and w coordinates. 038 <p> 039 This constructor is used to create the column vectors in a 4-by-4 040 homogeneous {@link Matrix}. 041 042 @param x x-coordinate of the new {@code Vector} 043 @param y y-coordinate of the new {@code Vector} 044 @param z z-coordinate of the new {@code Vector} 045 @param w w-coordinate of the new {@code Vector} 046 */ 047 public Vector(final double x, final double y, final double z, final double w) 048 { 049 this.x = x; 050 this.y = y; 051 this.z = z; 052 this.w = w; 053 } 054 055 056 /** 057 Construct a new {@code Vector} from a {@link Vertex}. 058 059 @param v {@link Vertex} object to convert into a {@code Vector} 060 */ 061 public Vector(final Vertex v) 062 { 063 this(v.x, v.y, v.z, v.w); 064 } 065 066 067 /** 068 The dot-product of two {@code Vector}s returns a scalar. 069 070 @param v {@code Vector} object to multiply with this {@code Vector} 071 @return a double that is the dot-product of this {@code Vector} and {@code v} 072 */ 073 public double dotProduct(final Vector v) 074 { 075 return (x * v.x) + (y * v.y) + (z * v.z); 076 } 077 078 079 /** 080 The cross-product of two {@code Vector}s returns a (new) {@code Vector}. 081 082 @param v {@code Vector} object to multiply with this {@code Vector} 083 @return a new {@code Vector} object that is the cross-product of this {@code Vector} and {@code v} 084 */ 085 public Vector crossProduct(final Vector v) 086 { 087 return new Vector(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); 088 } 089 090 091 /** 092 A scalar times a {@code Vector} returns a (new) {@code Vector}. 093 094 @param s number to multiply this {@code Vector} by 095 @return a new {@code Vector} object that is the scalar times this {@code Vector} 096 */ 097 public Vector times(final double s) // return s * this 098 { 099 return new Vector(s*x, s*y, s*z, s*w); 100 } 101 102 103 /** 104 A {@code Vector} plus a {@code Vector} returns a (new) {@code Vector}. 105 106 @param v {@code Vector} object to add to this {@code Vector} 107 @return a new {@code Vector} object that is the sum of this {@code Vector} and {@code v} 108 */ 109 public Vector plus(final Vector v) // return this + v 110 { 111 return new Vector(x + v.x, y + v.y, z + v.z, w + v.w); 112 } 113 114 115 /** 116 A {@code Vector} minus a {@code Vector} returns a (new) {@code Vector}. 117 118 @param v {@code Vector} object to subtract from this {@code Vector} 119 @return a new {@code Vector} object that is this {@code Vector} minus {@code v} 120 */ 121 public Vector minus(final Vector v) // return this - v 122 { 123 return new Vector(x - v.x, y - v.y, z - v.z, w - v.w); 124 } 125 126 127 /** 128 Return the normalized version of this {@code Vector}. 129 <p> 130 That is, return the {@code Vector} with length 1 that 131 points in the same direction as this {@code Vector}. 132 133 @return a new {@code Vector} that has length one and has the same direction as this {@code Vector} 134 */ 135 public Vector normalize() // return this / |this| 136 { 137 final double norm = Math.sqrt( x*x + y*y + z*z ); 138 return new Vector(x/norm, y/norm, z/norm); 139 } 140 141 142 /** 143 A {@code Vector} plus a {@link Vertex} returns a (new) {@link Vertex}. 144 <p> 145 The vector translates the vertex to a new location. 146 147 @param v {@link Vertex} object to add to this {@code Vector} 148 @return a new {@link Vertex} object that is the translation of {@code v} by this {@code Vector} 149 */ 150 public Vertex plus(final Vertex v) 151 { 152 return new Vertex(x + v.x, y + v.y, z + v.z); 153 } 154 155 156 /** 157 For debugging. 158 159 @return {@link String} representation of this {@code Vector} object 160 */ 161 @Override 162 public String toString() 163 { 164 final int precision = 5; // the default precision for the format string 165 return toString(precision); 166 } 167 168 169 /** 170 For debugging. 171 <p> 172 Allow the precision of the formatted output to be specified. 173 174 @param precision precision value for the format string 175 @return {@link String} representation of this {@code Vector} object 176 */ 177 public String toString(final int precision) 178 { 179 final int iWidth = 3; // default width of integer part of the format string 180 return toString(precision, iWidth); 181 } 182 183 184 /** 185 For debugging. 186 <p> 187 Allow the precision and width of the formatted output to be specified. 188 By width, we mean the width of the integer part of each number. 189 190 @param precision precision value for the format string 191 @param iWidth width of the integer part of the format string 192 @return {@link String} representation of this {@code Vector} object 193 */ 194 public String toString(final int precision, final int iWidth) 195 { 196 // Here is one way to get programmable precision and width. 197 final int p = precision; // the precision for the following format string 198 final int t = p + iWidth + 2; // the width for the following format string 199 final String format = "[x,y,z,w] = [% "+t+"."+p+"f % "+t+"."+p+"f % "+t+"."+p+"f % "+t+"."+p+"f]"; 200 return String.format(format, x, y, z, w); 201 } 202}