001: /*
002: * Copyright (c) 2001 Silvere Martin_michiellot All Rights Reserved.
003: *
004: * Silv?re Martin_michiellot grants you ("Licensee")
005: * a non-exclusive, royalty free, license to use,
006: * modify and redistribute this software in source and binary code form,
007: * provided that i) this copyright notice and license appear on all copies of
008: * the software; and ii) Licensee does not utilize the software in a manner
009: * which is disparaging to Silv?re Martin_michiellot.
010: *
011: * This software is provided "AS IS," without a warranty of any kind. ALL
012: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
013: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
014: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. Silv?re Martin_michiellot
015: * AND ITS LICENSORS SHALL NOT BE
016: * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
017: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
018: * Silv?re Martin_michiellot OR ITS
019: * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
020: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
021: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
022: * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
023: * POSSIBILITY OF SUCH DAMAGES.
024: *
025: * This software is not designed or intended for use in on-line control of
026: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
027: * the design, construction, operation or maintenance of any nuclear
028: * facility. Licensee represents and warrants that it will not use or
029: * redistribute the Software for such purposes.
030: */
031:
032: package com.db.utils;
033:
034: import javax.media.j3d.*;
035: import javax.vecmath.*;
036:
037: /*
038: FROM Roland Holm <rholm@FAW.UNI-LINZ.AC.AT>
039:
040: Quat4d rotQuat = new Quat4d();
041: transform.get(rotQuat);
042: AxisAngle4d rotation= new AxisAngle4d();
043: rotation.set(rotQuat);
044:
045: or
046:
047: Quat4d rotQuat = new Quat4d();
048: Vector3d anyTranslation = new Vector3d();
049: transform.get(rotQuat, anyTranslation);
050: AxisAngle4d rotation= new AxisAngle4d();
051: rotation.set(rotQuat);
052:
053: However, under certain circumstances the resulting rotation in the
054: AxisAngle4d is a null rotation (0.0 1.0 0.0 0.0), even though there is
055: a non-null rotation in the transformation matrix.
056:
057: Extracting the rotation with the following rough method works correctly:
058:
059: */
060:
061: public class Transformation {
062:
063: public Transformation() {
064:
065: super ();
066:
067: }
068:
069: public static AxisAngle4d extractRotation(Transform3D trans) {
070:
071: AxisAngle4d a = new AxisAngle4d();
072: Matrix3d r = new Matrix3d();
073: trans.get(r);
074: // calculate angle
075: double calc = (r.m00 + r.m11 + r.m22 - 1) / 2;
076: if (calc > 1.0)
077: calc = 1.0;
078: else if (calc < -1.0)
079: calc = -1.0;
080: a.angle = Math.acos(calc);
081:
082: // No angle equals no rotation, so we are done
083: if (a.angle == 0.0)
084: return new AxisAngle4d(0, 1, 0, 0);
085:
086: // calculate axis (note that we have to handle the case of angle==PI seperately!)
087: double delta = 0.01; // accuracy of the equality check
088:
089: if (a.angle <= Math.PI + delta && a.angle >= Math.PI - delta) {
090: if (r.m00 >= r.m11 && r.m00 >= r.m22) {
091: a.x = (Math.sqrt(r.m00 - r.m11 - r.m22 + 1)) / 2.0;
092: a.y = r.m01 / (2 * a.x);
093: a.z = r.m02 / (2 * a.x);
094: } else if (r.m11 >= r.m00 && r.m11 >= r.m22) {
095: a.y = (Math.sqrt(r.m11 - r.m00 - r.m22 + 1)) / 2.0;
096: a.x = r.m01 / (2 * a.y);
097: a.z = r.m12 / (2 * a.y);
098: } else if (r.m22 >= r.m11 && r.m22 >= r.m00) {
099: a.z = (Math.sqrt(r.m22 - r.m00 - r.m11 + 1)) / 2.0;
100: a.x = r.m02 / (2 * a.z);
101: a.y = r.m12 / (2 * a.z);
102: }
103: } else {
104: Vector3d v = new Vector3d(r.m21 - r.m12, r.m02 - r.m20,
105: r.m10 - r.m01);
106: double len = v.length();
107: Vector3d u = new Vector3d(v.x / len, v.y / len, v.z / len);
108: a.x = u.x;
109: a.y = u.y;
110: a.z = u.z;
111: }
112: return a;
113: }
114:
115: }
|