Merge branch 'Jalview-BH/JAL-3026-JAL-3063-JAXB' of
[jalview.git] / srcjar / 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 public class A4 implements JSONEncodable, Serializable {
40
41   /*
42    * I assumed that the length of the axis vector is not significant.
43    */
44
45   /**
46    * The x coordinate.
47    */
48   public float x;
49
50   /**
51    * The y coordinate.
52    */
53   public float y;
54
55   /**
56    * The z coordinate.
57    */
58   public float z;
59
60   /**
61    * The angle.
62    */
63   public float angle;
64
65   /**
66    * Constructs and initializes a AxisAngle4f to (0,0,1,0).
67    */
68   public A4() {
69     z = 1.0f;
70   }
71
72   /**
73    * Constructs and initializes an AxisAngle4f from the specified x, y, z, and
74    * angle.
75    * 
76    * @param x
77    *        the x coordinate
78    * @param y
79    *        the y coordinate
80    * @param z
81    *        the z coordinate
82    * @param angle
83    *        the angle.
84    * @return a
85    */
86   public static A4 new4(float x, float y, float z, float angle) {
87     A4 a = new A4();
88     a.set4(x, y, z, angle);
89     return a;
90   }
91
92   /**
93    * Constructs and initializes a AxisAngle4f from the specified AxisAngle4f.
94    * 
95    * @param a1
96    *        the AxisAngle4f containing the initialization x y z angle data
97    * @return a
98    */
99   public static A4 newAA(A4 a1) {
100     A4 a = new A4();
101     a.set4(a1.x, a1.y, a1.z, a1.angle);
102     return a;
103   }
104
105   /**
106    * Constructs and initializes an AxisAngle4f from the specified axis and
107    * angle.
108    * 
109    * @param axis
110    *        the axis
111    * @param angle
112    *        the angle
113    * @return a
114    */
115   public static A4 newVA(V3 axis, float angle) {
116     A4 a = new A4();
117     a.setVA(axis, angle);
118     return a;
119   }
120
121   /**
122    * Sets the value of this AxisAngle4f to the specified axis and angle.
123    * 
124    * @param axis
125    *        the axis
126    * @param angle
127    *        the angle
128    * @since Java 3D 1.2
129    */
130   public final void setVA(V3 axis, float angle) {
131     x = axis.x;
132     y = axis.y;
133     z = axis.z;
134     this.angle = angle;
135   }
136
137   /**
138    * Sets the value of this axis angle to the specified x,y,z,angle.
139    * 
140    * @param x
141    *        the x coordinate
142    * @param y
143    *        the y coordinate
144    * @param z
145    *        the z coordinate
146    * @param angle
147    *        the angle
148    */
149   public final void set4(float x, float y, float z, float angle) {
150     this.x = x;
151     this.y = y;
152     this.z = z;
153     this.angle = angle;
154   }
155
156   /**
157    * Sets the value of this axis angle to the value of axis angle t1.
158    * 
159    * @param a
160    *        the axis angle to be copied
161    */
162   public final void setAA(A4 a) {
163     x = a.x;
164     y = a.y;
165     z = a.z;
166     angle = a.angle;
167   }
168
169
170   /**
171    * Sets the value of this axis-angle to the rotational component of the passed
172    * matrix.
173    * 
174    * @param m1
175    *        the matrix3f
176    */
177   public final void setM(M3 m1) {
178     setFromMat(m1.m00, m1.m01, m1.m02, m1.m10, m1.m11, m1.m12, m1.m20, m1.m21,
179         m1.m22);
180   }
181
182   // helper method
183   private void setFromMat(double m00, double m01, double m02, double m10,
184                           double m11, double m12, double m20, double m21,
185                           double m22) {
186     // assuming M is normalized.
187
188     double cos = (m00 + m11 + m22 - 1.0) * 0.5;
189     x = (float) (m21 - m12);
190     y = (float) (m02 - m20);
191     z = (float) (m10 - m01);
192     double sin = 0.5 * Math.sqrt(x * x + y * y + z * z);
193     if (sin == 0 && cos == 1) {
194       x = y = 0;
195       z = 1;
196       angle = 0;
197     } else {
198       angle = (float) Math.atan2(sin, cos);
199     }
200
201     // no need to normalize
202     // x /= n;
203     // y /= n;
204     // z /= n;
205   }
206
207   /**
208    * Returns a hash number based on the data values in this object. Two
209    * different AxisAngle4f objects with identical data values (ie, returns true
210    * for equals(AxisAngle4f) ) will return the same hash number. Two vectors
211    * with different data members may return the same hash value, although this
212    * is not likely.
213    */
214   @Override
215   public int hashCode() {
216     return T3.floatToIntBits(x) ^ T3.floatToIntBits(y)
217         ^ T3.floatToIntBits(z) ^ T3.floatToIntBits(angle);
218   }
219
220   /**
221    * Returns true if the Object o is of type AxisAngle4f and all of the data
222    * members of o1 are equal to the corresponding data members in this
223    * AxisAngle4f.
224    * 
225    * @param o
226    *        the object with which the comparison is made.
227    * @return T/F
228    */
229   @Override
230   public boolean equals(Object o) {
231     if (!(o instanceof A4))
232       return false;
233     A4 a1 = (A4) o;
234     return x == a1.x && y == a1.y && z == a1.z && angle == a1.angle;
235   }
236
237   /**
238    * Returns a string that contains the values of this AxisAngle4f. The form is
239    * (x,y,z,angle).
240    * 
241    * @return the String representation
242    */
243   @Override
244   public String toString() {
245     return "(" + x + ", " + y + ", " + z + ", " + angle + ")";
246   }
247
248   @Override
249   public String toJSON() {
250     return "[" + x + "," + y + "," + z + "," + (float) (angle * 180.0 / Math.PI) + "]";
251   }
252 }