View Javadoc

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 }