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