]> gerrit.simantics Code Review - simantics/3d.git/blob - javax.vecmath/src/javax/vecmath/AxisAngle4d.java
Included old javax.vecmath 1.5.2 to org.simantics.g3d.feature
[simantics/3d.git] / javax.vecmath / src / javax / vecmath / AxisAngle4d.java
1 /*
2  * $RCSfile: AxisAngle4d.java,v $
3  *
4  * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6  *
7  * This code is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2 only, as
9  * published by the Free Software Foundation.  Sun designates this
10  * particular file as subject to the "Classpath" exception as provided
11  * by Sun in the LICENSE file that accompanied this code.
12  *
13  * This code is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16  * version 2 for more details (a copy is included in the LICENSE file that
17  * accompanied this code).
18  *
19  * You should have received a copy of the GNU General Public License version
20  * 2 along with this work; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22  *
23  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
24  * CA 95054 USA or visit www.sun.com if you need additional information or
25  * have any questions.
26  *
27  * $Revision: 1.9 $
28  * $Date: 2008/02/28 20:18:50 $
29  * $State: Exp $
30  */
31
32 package javax.vecmath;
33
34 /**
35  * A four-element axis angle represented by double-precision floating point 
36  * x,y,z,angle components.  An axis angle is a rotation of angle (radians)
37  * about the vector (x,y,z).
38  *
39  */
40 public class AxisAngle4d implements java.io.Serializable, Cloneable {
41
42
43     // Compatible with 1.1
44     static final long serialVersionUID = 3644296204459140589L;
45
46     /**
47      * The x coordinate.
48      */
49     public      double  x;
50
51     /**
52      * The y coordinate.
53      */
54     public      double  y;
55
56     /**
57      * The z coordinate.
58      */
59     public      double  z;
60
61     /**
62      * The angle of rotation in radians.
63      */
64     public      double  angle;
65
66     // Fixed to issue 538
67     final static double EPS = 1.0e-12;
68     
69     /**
70      * Constructs and initializes an AxisAngle4d from the specified 
71      * x, y, z, and angle.
72      * @param x the x coordinate
73      * @param y the y coordinate
74      * @param z the z coordinate
75      * @param angle the angle of rotation in radians
76      */
77     public AxisAngle4d(double x, double y, double z, double angle)
78     {
79         this.x = x;
80         this.y = y;
81         this.z = z;
82         this.angle = angle;
83     }
84
85
86     /**
87      * Constructs and initializes an AxisAngle4d from the components
88      * contained in the array.  
89      * @param a  the array of length 4 containing x,y,z,angle in order 
90      */ 
91         public AxisAngle4d(double[] a) 
92      { 
93          this.x = a[0]; 
94          this.y = a[1]; 
95          this.z = a[2]; 
96          this.angle = a[3]; 
97      }
98     /**
99      * Constructs and initializes an AxisAngle4d from the specified AxisAngle4d.
100      * @param a1 the AxisAngle4d containing the initialization x y z angle data
101      */
102     public AxisAngle4d(AxisAngle4d a1)
103     {
104         this.x = a1.x;
105         this.y = a1.y;
106         this.z = a1.z;
107         this.angle = a1.angle;
108     }
109
110
111     /**
112      * Constructs and initializes an AxisAngle4d from the specified 
113      * AxisAngle4f.
114      * @param a1 the AxisAngle4f containing the initialization x y z angle data
115      */
116     public AxisAngle4d(AxisAngle4f a1)
117     {
118         this.x = a1.x;
119         this.y = a1.y;
120         this.z = a1.z;
121         this.angle = a1.angle;
122     }
123
124
125     /**
126      * Constructs and initializes an AxisAngle4d from the specified 
127      * axis and angle.
128      * @param axis the axis
129      * @param angle the angle of rotation in radian
130      *
131      * @since vecmath 1.2
132      */
133     public AxisAngle4d(Vector3d axis, double angle) {
134         this.x = axis.x;
135         this.y = axis.y;
136         this.z = axis.z;
137         this.angle = angle;
138     }
139
140
141     /**
142      * Constructs and initializes an AxisAngle4d to (0,0,1,0).
143      */
144     public AxisAngle4d()
145     {
146         this.x = 0.0;
147         this.y = 0.0;
148         this.z = 1.0;
149         this.angle = 0.0;
150     }
151
152
153     /**
154      * Sets the value of this axis angle to the specified x,y,z,angle.
155      * @param x the x coordinate
156      * @param y the y coordinate
157      * @param z the z coordinate
158      * @param angle  the angle of rotation in radians
159      */
160     public final void set(double x, double y, double z, double angle)
161     {
162         this.x = x;
163         this.y = y;
164         this.z = z;
165         this.angle = angle;
166     }
167
168
169     /**
170      * Sets the value of this axis angle to the specified x,y,z,angle.
171      * @param a  the array of length 4 containing x,y,z,angle in order
172      */
173     public final void set(double[] a)
174     {
175         this.x = a[0];
176         this.y = a[1];
177         this.z = a[2];
178         this.angle = a[3];
179     }
180
181
182     /**
183      * Sets the value of this axis angle to the value of axis angle a1.
184      * @param a1 the axis angle to be copied
185      */
186     public final void set(AxisAngle4d a1)
187     {
188         this.x = a1.x;
189         this.y = a1.y;
190         this.z = a1.z;
191         this.angle = a1.angle;
192     }
193
194
195     /**
196      * Sets the value of this axis angle to the value of axis angle a1.
197      * @param a1 the axis angle to be copied
198      */
199     public final void set(AxisAngle4f a1)
200     {
201         this.x = a1.x;
202         this.y = a1.y;
203         this.z = a1.z;
204         this.angle = a1.angle;
205     }
206
207
208     /**
209      * Sets the value of this AxisAngle4d to the specified 
210      * axis and angle.
211      * @param axis the axis
212      * @param angle the angle of rotation in radians
213      *
214      * @since vecmath 1.2
215      */
216     public final void set(Vector3d axis, double angle) {
217         this.x = axis.x;
218         this.y = axis.y;
219         this.z = axis.z;
220         this.angle = angle;
221     }
222
223
224     /**
225      * Gets the value of this axis angle and places it into the array a of
226      * length four in x,y,z,angle order.
227      * @param a  the array of length four
228      */
229     public final void get(double[] a)
230     {
231         a[0] = this.x;
232         a[1] = this.y;
233         a[2] = this.z;
234         a[3] = this.angle;
235     }
236
237
238     /**
239      * Sets the value of this axis-angle to the rotational component of
240      * the passed matrix.
241      * If the specified matrix has no rotational component, the value
242      * of this AxisAngle4d is set to an angle of 0 about an axis of (0,1,0).
243      *
244      * @param m1 the matrix4f
245      */
246     public final void set(Matrix4f m1)
247     {
248         Matrix3d m3d = new Matrix3d();
249
250         m1.get(m3d);
251
252         x = (float)(m3d.m21 - m3d.m12);
253         y = (float)(m3d.m02 - m3d.m20);
254         z = (float)(m3d.m10 - m3d.m01);
255         double mag = x*x + y*y + z*z;
256
257         if (mag > EPS ) {
258             mag = Math.sqrt(mag);
259             double sin = 0.5*mag;
260             double cos = 0.5*(m3d.m00 + m3d.m11 + m3d.m22 - 1.0);
261             
262             angle = (float)Math.atan2(sin, cos);
263             
264             double invMag = 1.0/mag;
265             x = x*invMag;
266             y = y*invMag;
267             z = z*invMag;
268         } else {
269             x = 0.0f;
270             y = 1.0f;
271             z = 0.0f;
272             angle = 0.0f;
273         }
274     }
275
276
277     /**
278      * Sets the value of this axis-angle to the rotational component of
279      * the passed matrix.
280      * If the specified matrix has no rotational component, the value
281      * of this AxisAngle4d is set to an angle of 0 about an axis of (0,1,0).
282      *
283      * @param m1 the matrix4d
284      */
285     public final void set(Matrix4d m1)
286     {
287         Matrix3d m3d = new Matrix3d();
288
289         m1.get(m3d);
290
291         x = (float)(m3d.m21 - m3d.m12);
292         y = (float)(m3d.m02 - m3d.m20);
293         z = (float)(m3d.m10 - m3d.m01);
294
295         double mag = x*x + y*y + z*z;
296
297         if (mag > EPS ) {
298             mag = Math.sqrt(mag);
299
300             double sin = 0.5*mag;
301             double cos = 0.5*(m3d.m00 + m3d.m11 + m3d.m22 - 1.0);
302             angle = (float)Math.atan2(sin, cos);
303
304             double invMag = 1.0/mag;
305             x = x*invMag;
306             y = y*invMag;
307             z = z*invMag;
308         } else {
309             x = 0.0f;
310             y = 1.0f;
311             z = 0.0f;
312             angle = 0.0f;
313         }
314     }
315
316
317     /**
318      * Sets the value of this axis-angle to the rotational component of
319      * the passed matrix.
320      * If the specified matrix has no rotational component, the value
321      * of this AxisAngle4d is set to an angle of 0 about an axis of (0,1,0).
322      * @param m1 the matrix3f
323      */
324     public final void set(Matrix3f m1)
325     {
326         x = (float)(m1.m21 - m1.m12);
327         y = (float)(m1.m02 - m1.m20);
328         z = (float)(m1.m10 - m1.m01);
329         double mag = x*x + y*y + z*z;
330
331         if (mag > EPS ) {
332             mag = Math.sqrt(mag);
333
334             double sin = 0.5*mag;
335             double cos = 0.5*(m1.m00 + m1.m11 + m1.m22 - 1.0);
336             angle = (float)Math.atan2(sin, cos);
337
338             double invMag = 1.0/mag;
339             x = x*invMag;
340             y = y*invMag;
341             z = z*invMag;
342         } else {
343             x = 0.0f;
344             y = 1.0f;
345             z = 0.0f;
346             angle = 0.0f;
347         }
348     }
349
350
351     /**
352      * Sets the value of this axis-angle to the rotational component of
353      * the passed matrix.
354      * If the specified matrix has no rotational component, the value
355      * of this AxisAngle4d is set to an angle of 0 about an axis of (0,1,0).
356      * @param m1 the matrix3d
357      */
358     public final void set(Matrix3d m1)
359     {
360         x = (float)(m1.m21 - m1.m12);
361         y = (float)(m1.m02 - m1.m20);
362         z = (float)(m1.m10 - m1.m01);
363
364         double mag = x*x + y*y + z*z;
365
366         if (mag > EPS ) {
367             mag = Math.sqrt(mag);
368             
369             double sin = 0.5*mag;
370             double cos = 0.5*(m1.m00 + m1.m11 + m1.m22 - 1.0);
371             
372             angle = (float)Math.atan2(sin, cos);
373
374             double invMag = 1.0/mag;
375             x = x*invMag;
376             y = y*invMag;
377             z = z*invMag;
378         } else {
379             x = 0.0f;
380             y = 1.0f;
381             z = 0.0f;
382             angle = 0.0f;
383         }
384
385     }
386
387
388
389     /**
390       * Sets the value of this axis-angle to the rotational equivalent
391       * of the passed quaternion.
392       * If the specified quaternion has no rotational component, the value
393       * of this AxisAngle4d is set to an angle of 0 about an axis of (0,1,0).
394       * @param q1  the Quat4f
395       */
396     public final void set(Quat4f q1)
397     {
398         double mag = q1.x*q1.x + q1.y*q1.y + q1.z*q1.z;  
399
400         if( mag > EPS ) {
401             mag = Math.sqrt(mag);
402             double invMag = 1.0/mag;
403
404             x = q1.x*invMag;
405             y = q1.y*invMag;
406             z = q1.z*invMag;
407             angle = 2.0*Math.atan2(mag, q1.w); 
408         } else {
409            x = 0.0f;
410            y = 1.0f;
411            z = 0.0f;
412            angle = 0.0f;
413         } 
414   }
415
416
417     /**
418       * Sets the value of this axis-angle to the rotational equivalent
419       * of the passed quaternion.
420       * If the specified quaternion has no rotational component, the value
421       * of this AxisAngle4d is set to an angle of 0 about an axis of (0,1,0).
422       * @param q1  the Quat4d
423       */
424     public final void set(Quat4d q1)
425     {
426         double mag = q1.x*q1.x + q1.y*q1.y + q1.z*q1.z;  
427         
428         if ( mag > EPS ) {
429             mag = Math.sqrt(mag);
430             double invMag = 1.0/mag;
431             
432             x = q1.x*invMag;
433             y = q1.y*invMag;
434             z = q1.z*invMag;
435             angle = 2.0*Math.atan2(mag, q1.w); 
436         } else {
437             x = 0.0f;
438             y = 1.0f;
439             z = 0.0f;
440             angle = 0f;
441         }
442     }
443
444
445    /**
446      * Returns a string that contains the values of this AxisAngle4d.
447      * The form is (x,y,z,angle).
448      * @return the String representation
449      */  
450     public String toString() {
451         return "(" + this.x + ", " + this.y + ", " + this.z + ", " + this.angle + ")";
452     }
453
454
455    /**
456      * Returns true if all of the data members of AxisAngle4d a1 are
457      * equal to the corresponding data members in this AxisAngle4d.
458      * @param a1  the axis-angle with which the comparison is made
459      * @return  true or false
460      */  
461     public boolean equals(AxisAngle4d a1)
462     {
463         try {
464            return(this.x == a1.x && this.y == a1.y && this.z == a1.z
465             && this.angle == a1.angle);
466         }
467         catch (NullPointerException e2) {return false;}
468
469     }
470     /**
471      * Returns true if the Object o1 is of type AxisAngle4d and all of the
472      * data members of o1 are equal to the corresponding data members in
473      * this AxisAngle4d.
474      * @param o1  the object with which the comparison is made
475      * @return  true or false
476       */  
477     public boolean equals(Object o1)
478     {
479         try {
480            AxisAngle4d a2 = (AxisAngle4d) o1;
481            return(this.x == a2.x && this.y == a2.y && this.z == a2.z
482             && this.angle == a2.angle);
483         }
484         catch (NullPointerException e2) {return false;}
485         catch (ClassCastException   e1) {return false;}
486
487     }
488
489
490    /**
491      * Returns true if the L-infinite distance between this axis-angle
492      * and axis-angle a1 is less than or equal to the epsilon parameter, 
493      * otherwise returns false.  The L-infinite
494      * distance is equal to 
495      * MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2), abs(angle1-angle2)].
496      * @param a1  the axis-angle to be compared to this axis-angle 
497      * @param epsilon  the threshold value  
498      */
499     public boolean epsilonEquals(AxisAngle4d a1, double epsilon)
500     {
501        double diff;
502
503        diff = x - a1.x;
504        if((diff<0?-diff:diff) > epsilon) return false;
505
506        diff = y - a1.y;
507        if((diff<0?-diff:diff) > epsilon) return false;
508
509        diff = z - a1.z;
510        if((diff<0?-diff:diff) > epsilon) return false;
511
512        diff = angle - a1.angle;
513        if((diff<0?-diff:diff) > epsilon) return false;
514
515        return true;
516     }
517
518
519     /**
520      * Returns a hash code value based on the data values in this
521      * object.  Two different AxisAngle4d objects with identical data values
522      * (i.e., AxisAngle4d.equals returns true) will return the same hash
523      * code value.  Two objects with different data members may return the
524      * same hash value, although this is not likely.
525      * @return the integer hash code value
526      */  
527     public int hashCode() {
528         long bits = 1L;
529         bits = 31L * bits + VecMathUtil.doubleToLongBits(x);
530         bits = 31L * bits + VecMathUtil.doubleToLongBits(y);
531         bits = 31L * bits + VecMathUtil.doubleToLongBits(z);
532         bits = 31L * bits + VecMathUtil.doubleToLongBits(angle);
533         return (int) (bits ^ (bits >> 32));
534     }
535
536     /**
537      * Creates a new object of the same class as this object.
538      *
539      * @return a clone of this instance.
540      * @exception OutOfMemoryError if there is not enough memory.
541      * @see java.lang.Cloneable
542      * @since vecmath 1.3
543      */
544     public Object clone() {
545         // Since there are no arrays we can just use Object.clone()
546         try {
547             return super.clone();
548         } catch (CloneNotSupportedException e) {
549             // this shouldn't happen, since we are Cloneable
550             throw new InternalError();
551         }
552     }
553
554
555         /**
556          * Get the axis angle, in radians.<br>
557          * An axis angle is a rotation angle about the vector (x,y,z).
558      * 
559          * @return the angle, in radians.
560          * 
561          * @since vecmath 1.5
562          */
563         public final double getAngle() {
564                 return angle;
565         }
566
567
568         /**
569          * Set the axis angle, in radians.<br>
570          * An axis angle is a rotation angle about the vector (x,y,z).
571          * 
572          * @param angle The angle to set, in radians.
573          * 
574          * @since vecmath 1.5
575          */
576         public final void setAngle(double angle) {
577                 this.angle = angle;
578         }
579
580
581         /**
582          * Get value of <i>x</i> coordinate. 
583          * 
584          * @return the <i>x</i> coordinate.
585          * 
586          * @since vecmath 1.5
587          */
588         public double getX() {
589                 return x;
590         }
591
592
593         /**
594          * Set a new value for <i>x</i> coordinate.
595          * 
596          * @param x the <i>x</i> coordinate.
597          * 
598          * @since vecmath 1.5
599          */
600         public final void setX(double x) {
601                 this.x = x;
602         }
603
604
605         /**
606          * Get value of <i>y</i> coordinate.
607          * 
608          * @return the <i>y</i> coordinate. 
609          * 
610          * @since vecmath 1.5
611          */
612         public  final double getY() {
613                 return y;
614         }
615
616
617         /**
618          * Set a new value for <i>y</i> coordinate.
619          * 
620          * @param y the <i>y</i> coordinate.
621          * 
622          * @since vecmath 1.5
623          */
624         public final void setY(double y) {
625                 this.y = y;
626         }
627
628
629         /**
630          * Get  value of <i>z</i> coordinate.
631          * 
632          * @return  the <i>z</i> coordinate.
633          * 
634          * @since vecmath 1.5
635          */
636         public double getZ() {
637                 return z;
638         }
639
640
641         /**
642          * Set a new value for <i>z</i> coordinate.
643          * 
644          * @param z the <i>z</i> coordinate.
645          * 
646          * @since vecmath 1.5
647          */
648         public final void setZ(double z) {
649                 this.z = z;
650         }
651
652 }