1 /**
2 *
3 */
4
5 package math.geom3d;
6
7 import math.geom3d.transform.AffineTransform3D;
8
9 /**
10 * Define a vector in 3 Dimensions. Provides methods to compute cross product
11 * and dot product, addition and subtraction of vectors.
12 */
13 public class Vector3D {
14
15 // ===================================================================
16 // class variables
17
18 protected double x = 1;
19 protected double y = 0;
20 protected double z = 0;
21
22 // ===================================================================
23 // static methods
24
25 /**
26 * Computes the dot product of the two vectors, defined by :
27 * <p>
28 * <code> x1*x2 + y1*y2 + z1*z2</code>
29 * <p>
30 * Dot product is zero if the vectors defined by the 2 vectors are
31 * orthogonal. It is positive if vectors are in the same direction, and
32 * negative if they are in opposite direction.
33 */
34 public final static double dotProduct(Vector3D v1, Vector3D v2) {
35 return v1.getX()*v2.getX()+v1.getY()*v2.getY()+v1.getZ()*v2.getZ();
36 }
37
38 /**
39 * Computes the cross product of the two vectors. Cross product is zero for
40 * colinear vectors. It is positive if angle between vector 1 and vector 2
41 * is comprised between 0 and PI, and negative otherwise.
42 */
43 public final static Vector3D crossProduct(Vector3D v1, Vector3D v2) {
44 return new Vector3D(v1.y*v2.z-v1.z*v2.y, v1.z*v2.x-v1.x*v2.z, v1.x*v2.y
45 -v1.y*v2.x);
46 }
47
48 /**
49 * test if the two vectors are colinear
50 *
51 * @return true if the vectors are colinear
52 */
53 public final static boolean isColinear(Vector3D v1, Vector3D v2) {
54 return Vector3D.crossProduct(v1.getNormalizedVector(),
55 v2.getNormalizedVector()).getNorm()<Shape3D.ACCURACY;
56 }
57
58 /**
59 * test if the two vectors are orthogonal
60 *
61 * @return true if the vectors are orthogonal
62 */
63 public final static boolean isOrthogonal(Vector3D v1, Vector3D v2) {
64 return Vector3D.dotProduct(v1.getNormalizedVector(), v2
65 .getNormalizedVector())<Shape3D.ACCURACY;
66 }
67
68 // ===================================================================
69 // constructors
70
71 /** Constructs a new Vector3D initialized with x=1, y=0 and z=0. */
72 public Vector3D() {
73 this(1, 0, 0);
74 }
75
76 /** Base constructor, using coordinates in each direction. */
77 public Vector3D(double x, double y, double z) {
78 this.x = x;
79 this.y = y;
80 this.z = z;
81 }
82
83 /**
84 * Construct a new vector between origin and a 3D point.
85 */
86 public Vector3D(Point3D point) {
87 this(point.getX(), point.getY(), point.getZ());
88 }
89
90 /**
91 * construct a new vector between two points, the vector is leading from the 'point1' to 'point2'.
92 */
93 public Vector3D(Point3D point1, Point3D point2) {
94 this(point2.getX()-point1.getX(), point2.getY()-point1.getY(), point2.getZ()-point1.getZ());
95 }
96
97 // ===================================================================
98 // inner fields management
99
100 public double getX() {
101 return x;
102 }
103
104 public void setX(double x) {
105 this.x = x;
106 }
107
108 public double getY() {
109 return y;
110 }
111
112 public void setY(double y) {
113 this.y = y;
114 }
115
116 public double getZ() {
117 return z;
118 }
119
120 public void setZ(double z) {
121 this.z = z;
122 }
123
124 public void setVector(double x, double y, double z) {
125 this.x = x;
126 this.y = y;
127 this.z = z;
128 }
129
130 // ===================================================================
131 // basic arithmetic on vectors
132
133 /**
134 * Return the sum of current vector with vector given as parameter. Inner
135 * fields are not modified.
136 */
137 public Vector3D plus(Vector3D v) {
138 return new Vector3D(x+v.x, y+v.y, z+v.z);
139 }
140
141 /**
142 * Return the subtraction of current vector with vector given as parameter.
143 * Inner fields are not modified.
144 */
145 public Vector3D minus(Vector3D v) {
146 return new Vector3D(x-v.x, y-v.y, z-v.z);
147 }
148
149 /**
150 * Multiplies this vector by a constant.
151 */
152 public Vector3D times(double k) {
153 return new Vector3D(k*x, k*y, k*z);
154 }
155
156 // ===================================================================
157 // general operations on vectors
158
159 /**
160 * Returns the opposite vector v2 of this, such that the sum of this and v2
161 * equals the null vector.
162 *
163 * @return the vector opposite to <code>this</code>.
164 */
165 public Vector3D getOpposite() {
166 return new Vector3D(-x, -y, -z);
167 }
168
169 /**
170 * Computes the norm of the vector
171 *
172 * @return the euclidean norm of the vector
173 */
174 public double getNorm() {
175 return Math.hypot(Math.hypot(x, y), z);
176 }
177
178 /**
179 * Alias for {@link Vector3D#getNorm()}.
180 * @return
181 */
182 public double getLength() {
183 return getNorm();
184 }
185
186 /**
187 * Computes the square of the norm of the vector. This avoids to compute the
188 * square root.
189 *
190 * @return the euclidean norm of the vector
191 */
192 public double getNormSq() {
193 return x*x+y*y+z*z;
194 }
195
196 /**
197 * Normalizes the vector, such that its norms becomes 1.
198 */
199 public void normalize() {
200 double r = this.getNorm();
201 this.x = this.x/r;
202 this.y = this.y/r;
203 this.z = this.z/r;
204 }
205
206 /**
207 * Returns the vector with same direction as this one, but with norm equal
208 * to 1.
209 */
210 public Vector3D getNormalizedVector() {
211 double r = this.getNorm();
212 return new Vector3D(this.x/r, this.y/r, this.z/r);
213 }
214
215 /**
216 * Transform the vector, by using only the first 4 parameters of the
217 * transform. Translation of a vector returns the same vector.
218 *
219 * @param trans an affine transform
220 * @return the transformed vector.
221 */
222 public Vector3D transform(AffineTransform3D trans) {
223 double[] tab = trans.getCoefficients();
224 return new Vector3D(x*tab[0]+y*tab[1]+z*tab[2], x*tab[4]+y*tab[5]+z
225 *tab[6], x*tab[8]+y*tab[9]+z*tab[10]);
226 }
227
228 // ===================================================================
229 // methods implementing Object interface
230
231 @Override
232 public boolean equals(Object obj) {
233 if (!(obj instanceof Vector3D))
234 return false;
235
236 Vector3D v = (Vector3D) obj;
237 if (Math.abs(x-v.x)>Shape3D.ACCURACY)
238 return false;
239 if (Math.abs(y-v.y)>Shape3D.ACCURACY)
240 return false;
241 if (Math.abs(z-v.z)>Shape3D.ACCURACY)
242 return false;
243 return true;
244 }
245
246 }