> Date:         Thu, 19 Sep 2002 10:20:05 -0400
> From: Josh Richmond <[EMAIL PROTECTED]>
>
> Run the attached program to see, but it looks like (at least using my initial
> values), the 3x3 matrix returned is not the 3x3 rotation matrix of the 4x4
> matrix, even with no affine transformation.
>
> E:\temp>java -cp . MatrixTest
> 4x4:
> 0.996823, 0.036243, 0.070927, -0.245034
> -0.036412, 0.997481, 0.001096, 0.034035
> -0.07084, -0.003675, 0.999336, 0.036529
> 0.0, 0.0, 0.0, 1.0
>
> 3x3:
> 0.03627668530489642, 0.9968262981253496, 0.07086136795886099
> 0.9993350269113018, -0.03644589019989963, 0.0010959360038394175
> -0.0036750634657327997, -0.0707744901306144, 0.997485571552428

As Mark Whitehorn <[EMAIL PROTECTED]> demonstrated, there appears to be
a problem with the general SVD implementation in vecmath.

For your particular case, the SVD *is* returning a correct result, but
the version of the SVD algorithm Java 3D uses sorts the columns in
descending order of scales.  This is useful for several types of
problems but is inappropriate for the purpose of normalizing rotations.

I've submitted bug 4751283
"Transform3D.normalize() and Matrix4d.get(Matrix3d) permute matrix columns."

Note that this only a problem when the matrix contains non-uniform scales.

Possible workarounds:

1) If you just want the upper 3x3 matrix components, use
   Transform3D.getRotationScale(Matrix3d) or
   Matrix4d.getRotationScale(Matrix3d)

2) If you only need to make the matrix orthogonal, use
   Transform3D.normalizeCP() to get a cross-product normalization.

3) If you need to make the matrix congruent (uniform scale), you can
   normalize the columns yourself with something like this:

    void conditionScale(double[] m) {
        double[] s = new double[3] ;

        s[0] = m[0]*m[0] + m[4]*m[4] + m[8]*m[8] ;
        s[1] = m[1]*m[1] + m[5]*m[5] + m[9]*m[9] ;
        s[2] = m[2]*m[2] + m[6]*m[6] + m[10]*m[10] ;

        if (s[0] == s[1] && s[0] == s[2])
            return ;

        s[0] = Math.sqrt(s[0]) ;
        s[1] = Math.sqrt(s[1]) ;
        s[2] = Math.sqrt(s[2]) ;

        int closestToOne = 0 ;
        if (Math.abs(s[1] - 1.0) < Math.abs(s[0] - 1.0))
            closestToOne = 1 ;
        if (Math.abs(s[2] - 1.0) < Math.abs(s[closestToOne] - 1.0))
            closestToOne = 2 ;

        double scale ;
        for (int i = 0 ; i < 3 ; i++) {
            if (i == closestToOne) continue ;
            scale = s[closestToOne] / s[i] ;
            m[i+0] *= scale ;
            m[i+4] *= scale ;
            m[i+8] *= scale ;
        }
    }

-- Mark Hood

Required disclaimer for code snippet above:

 * Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistribution in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any
 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
 * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
 * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
 * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
 * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that Software is not designed,licensed or intended
 * for use in the design, construction, operation or maintenance of
 * any nuclear facility.

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to