JAL-3026 adding javajs package
[jalview.git] / src / javajs / util / A4.java
1 /*
2    Copyright (C) 1997,1998,1999
3    Kenji Hiranabe, Eiwa System Management, Inc.
4
5    This program is free software.
6    Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
7    conforming to the Java(TM) 3D API specification by Sun Microsystems.
8
9    Permission to use, copy, modify, distribute and sell this software
10    and its documentation for any purpose is hereby granted without fee,
11    provided that the above copyright notice appear in all copies and
12    that both that copyright notice and this permission notice appear
13    in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
14    makes no representations about the suitability of this software for any
15    purpose.  It is provided "AS IS" with NO WARRANTY.
16 */
17 package javajs.util;
18
19 import java.io.Serializable;
20
21 import javajs.api.JSONEncodable;
22 import javajs.util.T3;
23
24
25
26 /**
27  * A 4 element axis angle represented by single precision floating point
28  * x,y,z,angle components. An axis angle is a rotation of angle (radians) about
29  * the vector (x,y,z).
30  * 
31  * @version specification 1.1, implementation $Revision: 1.9 $, $Date:
32  *          2006/07/28 17:01:32 $
33  * @author Kenji hiranabe
34  * 
35  * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012
36  * for unique constructor and method names
37  * for the optimization of compiled JavaScript using Java2Script.
38  *
39  */
40 public class A4 implements JSONEncodable, Serializable {
41
42   /*
43    * I assumed that the length of the axis vector is not significant.
44    */
45
46   /**
47          * 
48          */
49         private static final long serialVersionUID = 1L;
50
51 /**
52    * The x coordinate.
53    */
54   public float x;
55
56   /**
57    * The y coordinate.
58    */
59   public float y;
60
61   /**
62    * The z coordinate.
63    */
64   public float z;
65
66   /**
67    * The angle.
68    */
69   public float angle;
70
71   /**
72    * Constructs and initializes a AxisAngle4f to (0,0,1,0).
73    */
74   public A4() {
75     z = 1.0f;
76   }
77
78   /**
79    * Constructs and initializes an AxisAngle4f from the specified x, y, z, and
80    * angle.
81    * 
82    * @param x
83    *        the x coordinate
84    * @param y
85    *        the y coordinate
86    * @param z
87    *        the z coordinate
88    * @param angle
89    *        the angle.
90    * @return a
91    */
92   public static A4 new4(float x, float y, float z, float angle) {
93     A4 a = new A4();
94     a.set4(x, y, z, angle);
95     return a;
96   }
97
98   /**
99    * Constructs and initializes a AxisAngle4f from the specified AxisAngle4f.
100    * 
101    * @param a1
102    *        the AxisAngle4f containing the initialization x y z angle data
103    * @return a
104    */
105   public static A4 newAA(A4 a1) {
106     A4 a = new A4();
107     a.set4(a1.x, a1.y, a1.z, a1.angle);
108     return a;
109   }
110
111   /**
112    * Constructs and initializes an AxisAngle4f from the specified axis and
113    * angle.
114    * 
115    * @param axis
116    *        the axis
117    * @param angle
118    *        the angle
119    * @return a
120    */
121   public static A4 newVA(V3 axis, float angle) {
122     A4 a = new A4();
123     a.setVA(axis, angle);
124     return a;
125   }
126
127   /**
128    * Sets the value of this AxisAngle4f to the specified axis and angle.
129    * 
130    * @param axis
131    *        the axis
132    * @param angle
133    *        the angle
134    * @since Java 3D 1.2
135    */
136   public final void setVA(V3 axis, float angle) {
137     x = axis.x;
138     y = axis.y;
139     z = axis.z;
140     this.angle = angle;
141   }
142
143   /**
144    * Sets the value of this axis angle to the specified x,y,z,angle.
145    * 
146    * @param x
147    *        the x coordinate
148    * @param y
149    *        the y coordinate
150    * @param z
151    *        the z coordinate
152    * @param angle
153    *        the angle
154    */
155   public final void set4(float x, float y, float z, float angle) {
156     this.x = x;
157     this.y = y;
158     this.z = z;
159     this.angle = angle;
160   }
161
162   /**
163    * Sets the value of this axis angle to the value of axis angle t1.
164    * 
165    * @param a
166    *        the axis angle to be copied
167    */
168   public final void setAA(A4 a) {
169     x = a.x;
170     y = a.y;
171     z = a.z;
172     angle = a.angle;
173   }
174
175
176   /**
177    * Sets the value of this axis-angle to the rotational component of the passed
178    * matrix.
179    * 
180    * @param m1
181    *        the matrix3f
182    */
183   public final void setM(M3 m1) {
184     setFromMat(m1.m00, m1.m01, m1.m02, m1.m10, m1.m11, m1.m12, m1.m20, m1.m21,
185         m1.m22);
186   }
187
188   // helper method
189   private void setFromMat(double m00, double m01, double m02, double m10,
190                           double m11, double m12, double m20, double m21,
191                           double m22) {
192     // assuming M is normalized.
193
194     double cos = (m00 + m11 + m22 - 1.0) * 0.5;
195     x = (float) (m21 - m12);
196     y = (float) (m02 - m20);
197     z = (float) (m10 - m01);
198     double sin = 0.5 * Math.sqrt(x * x + y * y + z * z);
199     if (sin == 0 && cos == 1) {
200       x = y = 0;
201       z = 1;
202       angle = 0;
203     } else {
204       angle = (float) Math.atan2(sin, cos);
205     }
206
207     // no need to normalize
208     // x /= n;
209     // y /= n;
210     // z /= n;
211   }
212
213   /**
214    * Returns a hash number based on the data values in this object. Two
215    * different AxisAngle4f objects with identical data values (ie, returns true
216    * for equals(AxisAngle4f) ) will return the same hash number. Two vectors
217    * with different data members may return the same hash value, although this
218    * is not likely.
219    */
220   @Override
221   public int hashCode() {
222     return T3.floatToIntBits(x) ^ T3.floatToIntBits(y)
223         ^ T3.floatToIntBits(z) ^ T3.floatToIntBits(angle);
224   }
225
226   /**
227    * Returns true if the Object o is of type AxisAngle4f and all of the data
228    * members of o1 are equal to the corresponding data members in this
229    * AxisAngle4f.
230    * 
231    * @param o
232    *        the object with which the comparison is made.
233    * @return T/F
234    */
235   @Override
236   public boolean equals(Object o) {
237     if (!(o instanceof A4))
238       return false;
239     A4 a1 = (A4) o;
240     return x == a1.x && y == a1.y && z == a1.z && angle == a1.angle;
241   }
242
243   /**
244    * Returns a string that contains the values of this AxisAngle4f. The form is
245    * (x,y,z,angle).
246    * 
247    * @return the String representation
248    */
249   @Override
250   public String toString() {
251     return "(" + x + ", " + y + ", " + z + ", " + angle + ")";
252   }
253
254   @Override
255   public String toJSON() {
256     return "[" + x + "," + y + "," + z + "," + (float) (angle * 180.0 / Math.PI) + "]";
257   }
258 }