JAL-1807 test
[jalviewjs.git] / bin / javajs / util / Quat.js
1 Clazz.declarePackage ("javajs.util");
2 Clazz.load (["javajs.util.P4"], "javajs.util.Quat", ["java.lang.Float", "javajs.util.A4", "$.M3", "$.V3"], function () {
3 c$ = Clazz.decorateAsClass (function () {
4 this.q0 = 0;
5 this.q1 = 0;
6 this.q2 = 0;
7 this.q3 = 0;
8 this.mat = null;
9 Clazz.instantialize (this, arguments);
10 }, javajs.util, "Quat");
11 Clazz.makeConstructor (c$, 
12 function () {
13 this.q0 = 1;
14 });
15 c$.newQ = Clazz.defineMethod (c$, "newQ", 
16 function (q) {
17 var q1 =  new javajs.util.Quat ();
18 q1.set (q);
19 return q1;
20 }, "javajs.util.Quat");
21 c$.newVA = Clazz.defineMethod (c$, "newVA", 
22 function (v, theta) {
23 var q =  new javajs.util.Quat ();
24 q.setTA (v, theta);
25 return q;
26 }, "javajs.util.T3,~N");
27 c$.newM = Clazz.defineMethod (c$, "newM", 
28 function (mat) {
29 var q =  new javajs.util.Quat ();
30 q.setM (javajs.util.M3.newM3 (mat));
31 return q;
32 }, "javajs.util.M3");
33 c$.newAA = Clazz.defineMethod (c$, "newAA", 
34 function (a) {
35 var q =  new javajs.util.Quat ();
36 q.setAA (a);
37 return q;
38 }, "javajs.util.A4");
39 c$.newP4 = Clazz.defineMethod (c$, "newP4", 
40 function (pt) {
41 var q =  new javajs.util.Quat ();
42 q.setP4 (pt);
43 return q;
44 }, "javajs.util.P4");
45 c$.new4 = Clazz.defineMethod (c$, "new4", 
46 function (q1, q2, q3, q0) {
47 var q =  new javajs.util.Quat ();
48 if (q0 < -1) {
49 q.q0 = -1;
50 return q;
51 }if (q0 > 1) {
52 q.q0 = 1;
53 return q;
54 }q.q0 = q0;
55 q.q1 = q1;
56 q.q2 = q2;
57 q.q3 = q3;
58 return q;
59 }, "~N,~N,~N,~N");
60 Clazz.defineMethod (c$, "set", 
61 function (q) {
62 this.q0 = q.q0;
63 this.q1 = q.q1;
64 this.q2 = q.q2;
65 this.q3 = q.q3;
66 }, "javajs.util.Quat");
67 Clazz.defineMethod (c$, "setP4", 
68 ($fz = function (pt) {
69 var factor = (pt == null ? 0 : pt.distance4 (javajs.util.Quat.qZero));
70 if (factor == 0) {
71 this.q0 = 1;
72 return;
73 }this.q0 = pt.w / factor;
74 this.q1 = pt.x / factor;
75 this.q2 = pt.y / factor;
76 this.q3 = pt.z / factor;
77 }, $fz.isPrivate = true, $fz), "javajs.util.P4");
78 Clazz.defineMethod (c$, "setTA", 
79 function (pt, theta) {
80 if (pt.x == 0 && pt.y == 0 && pt.z == 0) {
81 this.q0 = 1;
82 return;
83 }var fact = (Math.sin (theta / 2 * 0.017453292519943295) / Math.sqrt (pt.x * pt.x + pt.y * pt.y + pt.z * pt.z));
84 this.q0 = (Math.cos (theta / 2 * 0.017453292519943295));
85 this.q1 = (pt.x * fact);
86 this.q2 = (pt.y * fact);
87 this.q3 = (pt.z * fact);
88 }, "javajs.util.T3,~N");
89 Clazz.defineMethod (c$, "setAA", 
90 function (a) {
91 var aa = javajs.util.A4.newAA (a);
92 if (aa.angle == 0) aa.y = 1;
93 this.setM ( new javajs.util.M3 ().setAA (aa));
94 }, "javajs.util.A4");
95 Clazz.defineMethod (c$, "setM", 
96 ($fz = function (mat) {
97 this.mat = mat;
98 var trace = mat.m00 + mat.m11 + mat.m22;
99 var temp;
100 var w;
101 var x;
102 var y;
103 var z;
104 if (trace >= 0.5) {
105 w = Math.sqrt (1.0 + trace);
106 x = (mat.m21 - mat.m12) / w;
107 y = (mat.m02 - mat.m20) / w;
108 z = (mat.m10 - mat.m01) / w;
109 } else if ((temp = mat.m00 + mat.m00 - trace) >= 0.5) {
110 x = Math.sqrt (1.0 + temp);
111 w = (mat.m21 - mat.m12) / x;
112 y = (mat.m10 + mat.m01) / x;
113 z = (mat.m20 + mat.m02) / x;
114 } else if ((temp = mat.m11 + mat.m11 - trace) >= 0.5 || mat.m11 > mat.m22) {
115 y = Math.sqrt (1.0 + temp);
116 w = (mat.m02 - mat.m20) / y;
117 x = (mat.m10 + mat.m01) / y;
118 z = (mat.m21 + mat.m12) / y;
119 } else {
120 z = Math.sqrt (1.0 + mat.m22 + mat.m22 - trace);
121 w = (mat.m10 - mat.m01) / z;
122 x = (mat.m20 + mat.m02) / z;
123 y = (mat.m21 + mat.m12) / z;
124 }this.q0 = (w * 0.5);
125 this.q1 = (x * 0.5);
126 this.q2 = (y * 0.5);
127 this.q3 = (z * 0.5);
128 }, $fz.isPrivate = true, $fz), "javajs.util.M3");
129 Clazz.defineMethod (c$, "setRef", 
130 function (qref) {
131 if (qref == null) {
132 this.mul (this.getFixFactor ());
133 return;
134 }if (this.dot (qref) >= 0) return;
135 this.q0 *= -1;
136 this.q1 *= -1;
137 this.q2 *= -1;
138 this.q3 *= -1;
139 }, "javajs.util.Quat");
140 c$.getQuaternionFrame = Clazz.defineMethod (c$, "getQuaternionFrame", 
141 function (center, x, xy) {
142 var vA = javajs.util.V3.newV (x);
143 var vB = javajs.util.V3.newV (xy);
144 if (center != null) {
145 vA.sub (center);
146 vB.sub (center);
147 }return javajs.util.Quat.getQuaternionFrameV (vA, vB, null, false);
148 }, "javajs.util.P3,javajs.util.T3,javajs.util.T3");
149 c$.getQuaternionFrameV = Clazz.defineMethod (c$, "getQuaternionFrameV", 
150 function (vA, vB, vC, yBased) {
151 if (vC == null) {
152 vC =  new javajs.util.V3 ();
153 vC.cross (vA, vB);
154 if (yBased) vA.cross (vB, vC);
155 }var vBprime =  new javajs.util.V3 ();
156 vBprime.cross (vC, vA);
157 vA.normalize ();
158 vBprime.normalize ();
159 vC.normalize ();
160 var mat =  new javajs.util.M3 ();
161 mat.setColumnV (0, vA);
162 mat.setColumnV (1, vBprime);
163 mat.setColumnV (2, vC);
164 var q = javajs.util.Quat.newM (mat);
165 return q;
166 }, "javajs.util.V3,javajs.util.V3,javajs.util.V3,~B");
167 Clazz.defineMethod (c$, "getMatrix", 
168 function () {
169 if (this.mat == null) this.setMatrix ();
170 return this.mat;
171 });
172 Clazz.defineMethod (c$, "setMatrix", 
173 ($fz = function () {
174 this.mat =  new javajs.util.M3 ();
175 this.mat.m00 = this.q0 * this.q0 + this.q1 * this.q1 - this.q2 * this.q2 - this.q3 * this.q3;
176 this.mat.m01 = 2 * this.q1 * this.q2 - 2 * this.q0 * this.q3;
177 this.mat.m02 = 2 * this.q1 * this.q3 + 2 * this.q0 * this.q2;
178 this.mat.m10 = 2 * this.q1 * this.q2 + 2 * this.q0 * this.q3;
179 this.mat.m11 = this.q0 * this.q0 - this.q1 * this.q1 + this.q2 * this.q2 - this.q3 * this.q3;
180 this.mat.m12 = 2 * this.q2 * this.q3 - 2 * this.q0 * this.q1;
181 this.mat.m20 = 2 * this.q1 * this.q3 - 2 * this.q0 * this.q2;
182 this.mat.m21 = 2 * this.q2 * this.q3 + 2 * this.q0 * this.q1;
183 this.mat.m22 = this.q0 * this.q0 - this.q1 * this.q1 - this.q2 * this.q2 + this.q3 * this.q3;
184 }, $fz.isPrivate = true, $fz));
185 Clazz.defineMethod (c$, "add", 
186 function (x) {
187 return javajs.util.Quat.newVA (this.getNormal (), this.getTheta () + x);
188 }, "~N");
189 Clazz.defineMethod (c$, "mul", 
190 function (x) {
191 return (x == 1 ? javajs.util.Quat.new4 (this.q1, this.q2, this.q3, this.q0) : javajs.util.Quat.newVA (this.getNormal (), this.getTheta () * x));
192 }, "~N");
193 Clazz.defineMethod (c$, "mulQ", 
194 function (p) {
195 return javajs.util.Quat.new4 (this.q0 * p.q1 + this.q1 * p.q0 + this.q2 * p.q3 - this.q3 * p.q2, this.q0 * p.q2 + this.q2 * p.q0 + this.q3 * p.q1 - this.q1 * p.q3, this.q0 * p.q3 + this.q3 * p.q0 + this.q1 * p.q2 - this.q2 * p.q1, this.q0 * p.q0 - this.q1 * p.q1 - this.q2 * p.q2 - this.q3 * p.q3);
196 }, "javajs.util.Quat");
197 Clazz.defineMethod (c$, "div", 
198 function (p) {
199 return this.mulQ (p.inv ());
200 }, "javajs.util.Quat");
201 Clazz.defineMethod (c$, "divLeft", 
202 function (p) {
203 return this.inv ().mulQ (p);
204 }, "javajs.util.Quat");
205 Clazz.defineMethod (c$, "dot", 
206 function (q) {
207 return this.q0 * q.q0 + this.q1 * q.q1 + this.q2 * q.q2 + this.q3 * q.q3;
208 }, "javajs.util.Quat");
209 Clazz.defineMethod (c$, "inv", 
210 function () {
211 return javajs.util.Quat.new4 (-this.q1, -this.q2, -this.q3, this.q0);
212 });
213 Clazz.defineMethod (c$, "negate", 
214 function () {
215 return javajs.util.Quat.new4 (-this.q1, -this.q2, -this.q3, -this.q0);
216 });
217 Clazz.defineMethod (c$, "getFixFactor", 
218 ($fz = function () {
219 return (this.q0 < 0 || this.q0 == 0 && (this.q1 < 0 || this.q1 == 0 && (this.q2 < 0 || this.q2 == 0 && this.q3 < 0)) ? -1 : 1);
220 }, $fz.isPrivate = true, $fz));
221 Clazz.defineMethod (c$, "getVector", 
222 function (i) {
223 return this.getVectorScaled (i, 1);
224 }, "~N");
225 Clazz.defineMethod (c$, "getVectorScaled", 
226 function (i, scale) {
227 if (i == -1) {
228 scale *= this.getFixFactor ();
229 return javajs.util.V3.new3 (this.q1 * scale, this.q2 * scale, this.q3 * scale);
230 }if (this.mat == null) this.setMatrix ();
231 var v =  new javajs.util.V3 ();
232 this.mat.getColumnV (i, v);
233 if (scale != 1) v.scale (scale);
234 return v;
235 }, "~N,~N");
236 Clazz.defineMethod (c$, "getNormal", 
237 function () {
238 var v = javajs.util.Quat.getRawNormal (this);
239 v.scale (this.getFixFactor ());
240 return v;
241 });
242 c$.getRawNormal = Clazz.defineMethod (c$, "getRawNormal", 
243 ($fz = function (q) {
244 var v = javajs.util.V3.new3 (q.q1, q.q2, q.q3);
245 if (v.length () == 0) return javajs.util.V3.new3 (0, 0, 1);
246 v.normalize ();
247 return v;
248 }, $fz.isPrivate = true, $fz), "javajs.util.Quat");
249 Clazz.defineMethod (c$, "getTheta", 
250 function () {
251 return (Math.acos (Math.abs (this.q0)) * 2 * 180 / 3.141592653589793);
252 });
253 Clazz.defineMethod (c$, "getThetaRadians", 
254 function () {
255 return (Math.acos (Math.abs (this.q0)) * 2);
256 });
257 Clazz.defineMethod (c$, "getNormalDirected", 
258 function (v0) {
259 var v = this.getNormal ();
260 if (v.x * v0.x + v.y * v0.y + v.z * v0.z < 0) {
261 v.scale (-1);
262 }return v;
263 }, "javajs.util.V3");
264 Clazz.defineMethod (c$, "get3dProjection", 
265 function (v3d) {
266 v3d.set (this.q1, this.q2, this.q3);
267 return v3d;
268 }, "javajs.util.V3");
269 Clazz.defineMethod (c$, "getThetaDirected", 
270 function (axisAngle) {
271 var theta = this.getTheta ();
272 var v = this.getNormal ();
273 if (axisAngle.x * this.q1 + axisAngle.y * this.q2 + axisAngle.z * this.q3 < 0) {
274 v.scale (-1);
275 theta = -theta;
276 }axisAngle.set4 (v.x, v.y, v.z, theta);
277 return axisAngle;
278 }, "javajs.util.P4");
279 Clazz.defineMethod (c$, "getThetaDirectedV", 
280 function (vector) {
281 var theta = this.getTheta ();
282 var v = this.getNormal ();
283 if (vector.x * this.q1 + vector.y * this.q2 + vector.z * this.q3 < 0) {
284 v.scale (-1);
285 theta = -theta;
286 }return theta;
287 }, "javajs.util.V3");
288 Clazz.defineMethod (c$, "toPoint4f", 
289 function () {
290 return javajs.util.P4.new4 (this.q1, this.q2, this.q3, this.q0);
291 });
292 Clazz.defineMethod (c$, "toAxisAngle4f", 
293 function () {
294 var theta = 2 * Math.acos (Math.abs (this.q0));
295 var sinTheta2 = Math.sin (theta / 2);
296 var v = this.getNormal ();
297 if (sinTheta2 < 0) {
298 v.scale (-1);
299 theta = 3.141592653589793 - theta;
300 }return javajs.util.A4.newVA (v, theta);
301 });
302 Clazz.defineMethod (c$, "transform2", 
303 function (pt, ptNew) {
304 if (this.mat == null) this.setMatrix ();
305 this.mat.rotate2 (pt, ptNew);
306 return ptNew;
307 }, "javajs.util.T3,javajs.util.T3");
308 Clazz.defineMethod (c$, "leftDifference", 
309 function (q2) {
310 var q2adjusted = (this.dot (q2) < 0 ? q2.negate () : q2);
311 return this.inv ().mulQ (q2adjusted);
312 }, "javajs.util.Quat");
313 Clazz.defineMethod (c$, "rightDifference", 
314 function (q2) {
315 var q2adjusted = (this.dot (q2) < 0 ? q2.negate () : q2);
316 return this.mulQ (q2adjusted.inv ());
317 }, "javajs.util.Quat");
318 Clazz.overrideMethod (c$, "toString", 
319 function () {
320 return "{" + this.q1 + " " + this.q2 + " " + this.q3 + " " + this.q0 + "}";
321 });
322 c$.div = Clazz.defineMethod (c$, "div", 
323 function (data1, data2, nMax, isRelative) {
324 var n;
325 if (data1 == null || data2 == null || (n = Math.min (data1.length, data2.length)) == 0) return null;
326 if (nMax > 0 && n > nMax) n = nMax;
327 var dqs =  new Array (n);
328 for (var i = 0; i < n; i++) {
329 if (data1[i] == null || data2[i] == null) return null;
330 dqs[i] = (isRelative ? data1[i].divLeft (data2[i]) : data1[i].div (data2[i]));
331 }
332 return dqs;
333 }, "~A,~A,~N,~B");
334 c$.sphereMean = Clazz.defineMethod (c$, "sphereMean", 
335 function (data, retStddev, criterion) {
336 if (data == null || data.length == 0) return  new javajs.util.Quat ();
337 if (retStddev == null) retStddev =  Clazz.newFloatArray (1, 0);
338 if (data.length == 1) {
339 retStddev[0] = 0;
340 return javajs.util.Quat.newQ (data[0]);
341 }var diff = 3.4028235E38;
342 var lastStddev = 3.4028235E38;
343 var qMean = javajs.util.Quat.simpleAverage (data);
344 var maxIter = 100;
345 var iter = 0;
346 while (diff > criterion && lastStddev != 0 && iter < maxIter) {
347 qMean = javajs.util.Quat.newMean (data, qMean);
348 retStddev[0] = javajs.util.Quat.stdDev (data, qMean);
349 diff = Math.abs (retStddev[0] - lastStddev);
350 lastStddev = retStddev[0];
351 }
352 return qMean;
353 }, "~A,~A,~N");
354 c$.simpleAverage = Clazz.defineMethod (c$, "simpleAverage", 
355 ($fz = function (ndata) {
356 var mean = javajs.util.V3.new3 (0, 0, 1);
357 var v = ndata[0].getNormal ();
358 mean.add (v);
359 for (var i = ndata.length; --i >= 0; ) mean.add (ndata[i].getNormalDirected (mean));
360
361 mean.sub (v);
362 mean.normalize ();
363 var f = 0;
364 for (var i = ndata.length; --i >= 0; ) f += Math.abs (ndata[i].get3dProjection (v).dot (mean));
365
366 if (f != 0) mean.scale (f / ndata.length);
367 f = Math.sqrt (1 - mean.lengthSquared ());
368 if (Float.isNaN (f)) f = 0;
369 return javajs.util.Quat.newP4 (javajs.util.P4.new4 (mean.x, mean.y, mean.z, f));
370 }, $fz.isPrivate = true, $fz), "~A");
371 c$.newMean = Clazz.defineMethod (c$, "newMean", 
372 ($fz = function (data, mean) {
373 var sum =  new javajs.util.V3 ();
374 var v;
375 var q;
376 var dq;
377 for (var i = data.length; --i >= 0; ) {
378 q = data[i];
379 dq = q.div (mean);
380 v = dq.getNormal ();
381 v.scale (dq.getTheta ());
382 sum.add (v);
383 }
384 sum.scale (1 / data.length);
385 var dqMean = javajs.util.Quat.newVA (sum, sum.length ());
386 return dqMean.mulQ (mean);
387 }, $fz.isPrivate = true, $fz), "~A,javajs.util.Quat");
388 c$.stdDev = Clazz.defineMethod (c$, "stdDev", 
389 ($fz = function (data, mean) {
390 var sum2 = 0;
391 var n = data.length;
392 for (var i = n; --i >= 0; ) {
393 var theta = data[i].div (mean).getTheta ();
394 sum2 += theta * theta;
395 }
396 return Math.sqrt (sum2 / n);
397 }, $fz.isPrivate = true, $fz), "~A,javajs.util.Quat");
398 Clazz.defineMethod (c$, "getEulerZYZ", 
399 function () {
400 var rA;
401 var rB;
402 var rG;
403 if (this.q1 == 0 && this.q2 == 0) {
404 var theta = this.getTheta ();
405 return  Clazz.newFloatArray (-1, [this.q3 < 0 ? -theta : theta, 0, 0]);
406 }rA = Math.atan2 (2 * (this.q2 * this.q3 + this.q0 * this.q1), 2 * (-this.q1 * this.q3 + this.q0 * this.q2));
407 rB = Math.acos (this.q3 * this.q3 - this.q2 * this.q2 - this.q1 * this.q1 + this.q0 * this.q0);
408 rG = Math.atan2 (2 * (this.q2 * this.q3 - this.q0 * this.q1), 2 * (this.q0 * this.q2 + this.q1 * this.q3));
409 return  Clazz.newFloatArray (-1, [(rA / 0.017453292519943295), (rB / 0.017453292519943295), (rG / 0.017453292519943295)]);
410 });
411 Clazz.defineMethod (c$, "getEulerZXZ", 
412 function () {
413 var rA;
414 var rB;
415 var rG;
416 if (this.q1 == 0 && this.q2 == 0) {
417 var theta = this.getTheta ();
418 return  Clazz.newFloatArray (-1, [this.q3 < 0 ? -theta : theta, 0, 0]);
419 }rA = Math.atan2 (2 * (this.q1 * this.q3 - this.q0 * this.q2), 2 * (this.q0 * this.q1 + this.q2 * this.q3));
420 rB = Math.acos (this.q3 * this.q3 - this.q2 * this.q2 - this.q1 * this.q1 + this.q0 * this.q0);
421 rG = Math.atan2 (2 * (this.q1 * this.q3 + this.q0 * this.q2), 2 * (-this.q2 * this.q3 + this.q0 * this.q1));
422 return  Clazz.newFloatArray (-1, [(rA / 0.017453292519943295), (rB / 0.017453292519943295), (rG / 0.017453292519943295)]);
423 });
424 c$.qZero = c$.prototype.qZero =  new javajs.util.P4 ();
425 Clazz.defineStatics (c$,
426 "RAD_PER_DEG", 0.017453292519943295);
427 });