// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Matrix3d.java

package vecmath;
import java.io.PrintStream;
import java.io.Serializable;

// Referenced classes of package javax.vecmath:
//            SingularMatrixException, Matrix3f, VecMathI18N, Vector3d, 
//            Quat4d, AxisAngle4d, Quat4f, AxisAngle4f, 
//            Tuple3d

public class Matrix3d
    implements Serializable, Cloneable
{

    public Matrix3d(double d, double d1, double d2, double d3, double d4, double d5, double d6, 
            double d7, double d8)
    {
        m00 = d;
        m01 = d1;
        m02 = d2;
        m10 = d3;
        m11 = d4;
        m12 = d5;
        m20 = d6;
        m21 = d7;
        m22 = d8;
    }

    public Matrix3d(double ad[])
    {
        m00 = ad[0];
        m01 = ad[1];
        m02 = ad[2];
        m10 = ad[3];
        m11 = ad[4];
        m12 = ad[5];
        m20 = ad[6];
        m21 = ad[7];
        m22 = ad[8];
    }

    public Matrix3d(Matrix3d matrix3d)
    {
        m00 = matrix3d.m00;
        m01 = matrix3d.m01;
        m02 = matrix3d.m02;
        m10 = matrix3d.m10;
        m11 = matrix3d.m11;
        m12 = matrix3d.m12;
        m20 = matrix3d.m20;
        m21 = matrix3d.m21;
        m22 = matrix3d.m22;
    }
/*
    public Matrix3d(Matrix3f matrix3f)
    {
        m00 = matrix3f.m00;
        m01 = matrix3f.m01;
        m02 = matrix3f.m02;
        m10 = matrix3f.m10;
        m11 = matrix3f.m11;
        m12 = matrix3f.m12;
        m20 = matrix3f.m20;
        m21 = matrix3f.m21;
        m22 = matrix3f.m22;
    }
*/
    public Matrix3d()
    {
        m00 = 0.0D;
        m01 = 0.0D;
        m02 = 0.0D;
        m10 = 0.0D;
        m11 = 0.0D;
        m12 = 0.0D;
        m20 = 0.0D;
        m21 = 0.0D;
        m22 = 0.0D;
    }

    public String toString()
    {
        return m00 + ", " + m01 + ", " + m02 + "\n" + m10 + ", " + m11 + ", " + m12 + "\n" + m20 + ", " + m21 + ", " + m22 + "\n";
    }

    public final void setIdentity()
    {
        m00 = 1.0D;
        m01 = 0.0D;
        m02 = 0.0D;
        m10 = 0.0D;
        m11 = 1.0D;
        m12 = 0.0D;
        m20 = 0.0D;
        m21 = 0.0D;
        m22 = 1.0D;
    }

    public final void setScale(double d)
    {
        double ad[] = new double[9];
        double ad1[] = new double[3];
        getScaleRotate(ad1, ad);
        m00 = ad[0] * d;
        m01 = ad[1] * d;
        m02 = ad[2] * d;
        m10 = ad[3] * d;
        m11 = ad[4] * d;
        m12 = ad[5] * d;
        m20 = ad[6] * d;
        m21 = ad[7] * d;
        m22 = ad[8] * d;
    }

    public final void setElement(int i, int j, double d)
    {
        switch(i)
        {
        case 0: // '\0'
            switch(j)
            {
            case 0: // '\0'
                m00 = d;
                break;

            case 1: // '\001'
                m01 = d;
                break;

            case 2: // '\002'
                m02 = d;
                break;

            default:
                throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d0"));
            }
            break;

        case 1: // '\001'
            switch(j)
            {
            case 0: // '\0'
                m10 = d;
                break;

            case 1: // '\001'
                m11 = d;
                break;

            case 2: // '\002'
                m12 = d;
                break;

            default:
                throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d0"));
            }
            break;

        case 2: // '\002'
            switch(j)
            {
            case 0: // '\0'
                m20 = d;
                break;

            case 1: // '\001'
                m21 = d;
                break;

            case 2: // '\002'
                m22 = d;
                break;

            default:
                throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d0"));
            }
            break;

        default:
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d0"));
        }
    }

    public final double getElement(int i, int j)
    {
        switch(i)
        {
        default:
            break;

        case 0: // '\0'
            switch(j)
            {
            case 0: // '\0'
                return m00;

            case 1: // '\001'
                return m01;

            case 2: // '\002'
                return m02;
            }
            break;

        case 1: // '\001'
            switch(j)
            {
            case 0: // '\0'
                return m10;

            case 1: // '\001'
                return m11;

            case 2: // '\002'
                return m12;
            }
            break;

        case 2: // '\002'
            switch(j)
            {
            case 0: // '\0'
                return m20;

            case 1: // '\001'
                return m21;

            case 2: // '\002'
                return m22;
            }
            break;
        }
        throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d1"));
    }

    public final void getRow(int i, Vector3d vector3d)
    {
        if(i == 0)
        {
            vector3d.x = m00;
            vector3d.y = m01;
            vector3d.z = m02;
        } else
        if(i == 1)
        {
            vector3d.x = m10;
            vector3d.y = m11;
            vector3d.z = m12;
        } else
        if(i == 2)
        {
            vector3d.x = m20;
            vector3d.y = m21;
            vector3d.z = m22;
        } else
        {
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d2"));
        }
    }

    public final void getRow(int i, double ad[])
    {
        if(i == 0)
        {
            ad[0] = m00;
            ad[1] = m01;
            ad[2] = m02;
        } else
        if(i == 1)
        {
            ad[0] = m10;
            ad[1] = m11;
            ad[2] = m12;
        } else
        if(i == 2)
        {
            ad[0] = m20;
            ad[1] = m21;
            ad[2] = m22;
        } else
        {
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d2"));
        }
    }

    public final void getColumn(int i, Vector3d vector3d)
    {
        if(i == 0)
        {
            vector3d.x = m00;
            vector3d.y = m10;
            vector3d.z = m20;
        } else
        if(i == 1)
        {
            vector3d.x = m01;
            vector3d.y = m11;
            vector3d.z = m21;
        } else
        if(i == 2)
        {
            vector3d.x = m02;
            vector3d.y = m12;
            vector3d.z = m22;
        } else
        {
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d4"));
        }
    }

    public final void getColumn(int i, double ad[])
    {
        if(i == 0)
        {
            ad[0] = m00;
            ad[1] = m10;
            ad[2] = m20;
        } else
        if(i == 1)
        {
            ad[0] = m01;
            ad[1] = m11;
            ad[2] = m21;
        } else
        if(i == 2)
        {
            ad[0] = m02;
            ad[1] = m12;
            ad[2] = m22;
        } else
        {
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d4"));
        }
    }

    public final void setRow(int i, double d, double d1, double d2)
    {
        switch(i)
        {
        case 0: // '\0'
            m00 = d;
            m01 = d1;
            m02 = d2;
            break;

        case 1: // '\001'
            m10 = d;
            m11 = d1;
            m12 = d2;
            break;

        case 2: // '\002'
            m20 = d;
            m21 = d1;
            m22 = d2;
            break;

        default:
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d6"));
        }
    }

    public final void setRow(int i, Vector3d vector3d)
    {
        switch(i)
        {
        case 0: // '\0'
            m00 = vector3d.x;
            m01 = vector3d.y;
            m02 = vector3d.z;
            break;

        case 1: // '\001'
            m10 = vector3d.x;
            m11 = vector3d.y;
            m12 = vector3d.z;
            break;

        case 2: // '\002'
            m20 = vector3d.x;
            m21 = vector3d.y;
            m22 = vector3d.z;
            break;

        default:
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d6"));
        }
    }

    public final void setRow(int i, double ad[])
    {
        switch(i)
        {
        case 0: // '\0'
            m00 = ad[0];
            m01 = ad[1];
            m02 = ad[2];
            break;

        case 1: // '\001'
            m10 = ad[0];
            m11 = ad[1];
            m12 = ad[2];
            break;

        case 2: // '\002'
            m20 = ad[0];
            m21 = ad[1];
            m22 = ad[2];
            break;

        default:
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d6"));
        }
    }

    public final void setColumn(int i, double d, double d1, double d2)
    {
        switch(i)
        {
        case 0: // '\0'
            m00 = d;
            m10 = d1;
            m20 = d2;
            break;

        case 1: // '\001'
            m01 = d;
            m11 = d1;
            m21 = d2;
            break;

        case 2: // '\002'
            m02 = d;
            m12 = d1;
            m22 = d2;
            break;

        default:
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d9"));
        }
    }

    public final void setColumn(int i, Vector3d vector3d)
    {
        switch(i)
        {
        case 0: // '\0'
            m00 = vector3d.x;
            m10 = vector3d.y;
            m20 = vector3d.z;
            break;

        case 1: // '\001'
            m01 = vector3d.x;
            m11 = vector3d.y;
            m21 = vector3d.z;
            break;

        case 2: // '\002'
            m02 = vector3d.x;
            m12 = vector3d.y;
            m22 = vector3d.z;
            break;

        default:
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d9"));
        }
    }

    public final void setColumn(int i, double ad[])
    {
        switch(i)
        {
        case 0: // '\0'
            m00 = ad[0];
            m10 = ad[1];
            m20 = ad[2];
            break;

        case 1: // '\001'
            m01 = ad[0];
            m11 = ad[1];
            m21 = ad[2];
            break;

        case 2: // '\002'
            m02 = ad[0];
            m12 = ad[1];
            m22 = ad[2];
            break;

        default:
            throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d9"));
        }
    }

    public final double getScale()
    {
        double ad[] = new double[3];
        double ad1[] = new double[9];
        getScaleRotate(ad, ad1);
        return max3(ad);
    }

    public final void add(double d)
    {
        m00 += d;
        m01 += d;
        m02 += d;
        m10 += d;
        m11 += d;
        m12 += d;
        m20 += d;
        m21 += d;
        m22 += d;
    }

    public final void add(double d, Matrix3d matrix3d)
    {
        m00 = matrix3d.m00 + d;
        m01 = matrix3d.m01 + d;
        m02 = matrix3d.m02 + d;
        m10 = matrix3d.m10 + d;
        m11 = matrix3d.m11 + d;
        m12 = matrix3d.m12 + d;
        m20 = matrix3d.m20 + d;
        m21 = matrix3d.m21 + d;
        m22 = matrix3d.m22 + d;
    }

    public final void add(Matrix3d matrix3d, Matrix3d matrix3d1)
    {
        m00 = matrix3d.m00 + matrix3d1.m00;
        m01 = matrix3d.m01 + matrix3d1.m01;
        m02 = matrix3d.m02 + matrix3d1.m02;
        m10 = matrix3d.m10 + matrix3d1.m10;
        m11 = matrix3d.m11 + matrix3d1.m11;
        m12 = matrix3d.m12 + matrix3d1.m12;
        m20 = matrix3d.m20 + matrix3d1.m20;
        m21 = matrix3d.m21 + matrix3d1.m21;
        m22 = matrix3d.m22 + matrix3d1.m22;
    }

    public final void add(Matrix3d matrix3d)
    {
        m00 += matrix3d.m00;
        m01 += matrix3d.m01;
        m02 += matrix3d.m02;
        m10 += matrix3d.m10;
        m11 += matrix3d.m11;
        m12 += matrix3d.m12;
        m20 += matrix3d.m20;
        m21 += matrix3d.m21;
        m22 += matrix3d.m22;
    }

    public final void sub(Matrix3d matrix3d, Matrix3d matrix3d1)
    {
        m00 = matrix3d.m00 - matrix3d1.m00;
        m01 = matrix3d.m01 - matrix3d1.m01;
        m02 = matrix3d.m02 - matrix3d1.m02;
        m10 = matrix3d.m10 - matrix3d1.m10;
        m11 = matrix3d.m11 - matrix3d1.m11;
        m12 = matrix3d.m12 - matrix3d1.m12;
        m20 = matrix3d.m20 - matrix3d1.m20;
        m21 = matrix3d.m21 - matrix3d1.m21;
        m22 = matrix3d.m22 - matrix3d1.m22;
    }

    public final void sub(Matrix3d matrix3d)
    {
        m00 -= matrix3d.m00;
        m01 -= matrix3d.m01;
        m02 -= matrix3d.m02;
        m10 -= matrix3d.m10;
        m11 -= matrix3d.m11;
        m12 -= matrix3d.m12;
        m20 -= matrix3d.m20;
        m21 -= matrix3d.m21;
        m22 -= matrix3d.m22;
    }

    public final void transpose()
    {
        double d = m10;
        m10 = m01;
        m01 = d;
        d = m20;
        m20 = m02;
        m02 = d;
        d = m21;
        m21 = m12;
        m12 = d;
    }

    public final void transpose(Matrix3d matrix3d)
    {
        if(this != matrix3d)
        {
            m00 = matrix3d.m00;
            m01 = matrix3d.m10;
            m02 = matrix3d.m20;
            m10 = matrix3d.m01;
            m11 = matrix3d.m11;
            m12 = matrix3d.m21;
            m20 = matrix3d.m02;
            m21 = matrix3d.m12;
            m22 = matrix3d.m22;
        } else
        {
            transpose();
        }
    }
/*
    public final void set(Quat4d quat4d)
    {
        m00 = 1.0D - 2D * quat4d.y * quat4d.y - 2D * quat4d.z * quat4d.z;
        m10 = 2D * (quat4d.x * quat4d.y + quat4d.w * quat4d.z);
        m20 = 2D * (quat4d.x * quat4d.z - quat4d.w * quat4d.y);
        m01 = 2D * (quat4d.x * quat4d.y - quat4d.w * quat4d.z);
        m11 = 1.0D - 2D * quat4d.x * quat4d.x - 2D * quat4d.z * quat4d.z;
        m21 = 2D * (quat4d.y * quat4d.z + quat4d.w * quat4d.x);
        m02 = 2D * (quat4d.x * quat4d.z + quat4d.w * quat4d.y);
        m12 = 2D * (quat4d.y * quat4d.z - quat4d.w * quat4d.x);
        m22 = 1.0D - 2D * quat4d.x * quat4d.x - 2D * quat4d.y * quat4d.y;
    }
*/
//    public final void set(AxisAngle4d axisangle4d)
//    {
//        double d = Math.sqrt(axisangle4d.x * axisangle4d.x + axisangle4d.y * axisangle4d.y + axisangle4d.z * axisangle4d.z);
//        if(d < 1.1102230240000001E-016D)
//        {
//            m00 = 1.0D;
//            m01 = 0.0D;
//            m02 = 0.0D;
//            m10 = 0.0D;
//            m11 = 1.0D;
//            m12 = 0.0D;
//            m20 = 0.0D;
//            m21 = 0.0D;
//            m22 = 1.0D;
//        } else
//        {
//            d = 1.0D / d;
//            double d1 = axisangle4d.x * d;
//            double d2 = axisangle4d.y * d;
//            double d3 = axisangle4d.z * d;
//            double d4 = Math.sin(axisangle4d.angle);
//            double d5 = Math.cos(axisangle4d.angle);
//            double d6 = 1.0D - d5;
//            double d7 = axisangle4d.x * axisangle4d.z;
//            double d8 = axisangle4d.x * axisangle4d.y;
//            double d9 = axisangle4d.y * axisangle4d.z;
//            m00 = d6 * d1 * d1 + d5;
//            m01 = d6 * d8 - d4 * d3;
//            m02 = d6 * d7 + d4 * d2;
//            m10 = d6 * d8 + d4 * d3;
//            m11 = d6 * d2 * d2 + d5;
//            m12 = d6 * d9 - d4 * d1;
//            m20 = d6 * d7 - d4 * d2;
//            m21 = d6 * d9 + d4 * d1;
//            m22 = d6 * d3 * d3 + d5;
//        }
//    }

//    public final void set(Quat4f quat4f)
//    {
//        m00 = 1.0D - 2D * (double)quat4f.y * (double)quat4f.y - 2D * (double)quat4f.z * (double)quat4f.z;
//        m10 = 2D * (double)(quat4f.x * quat4f.y + quat4f.w * quat4f.z);
//        m20 = 2D * (double)(quat4f.x * quat4f.z - quat4f.w * quat4f.y);
//        m01 = 2D * (double)(quat4f.x * quat4f.y - quat4f.w * quat4f.z);
//        m11 = 1.0D - 2D * (double)quat4f.x * (double)quat4f.x - 2D * (double)quat4f.z * (double)quat4f.z;
//        m21 = 2D * (double)(quat4f.y * quat4f.z + quat4f.w * quat4f.x);
//        m02 = 2D * (double)(quat4f.x * quat4f.z + quat4f.w * quat4f.y);
//        m12 = 2D * (double)(quat4f.y * quat4f.z - quat4f.w * quat4f.x);
//        m22 = 1.0D - 2D * (double)quat4f.x * (double)quat4f.x - 2D * (double)quat4f.y * (double)quat4f.y;
//    }

//    public final void set(AxisAngle4f axisangle4f)
//    {
//        double d = Math.sqrt(axisangle4f.x * axisangle4f.x + axisangle4f.y * axisangle4f.y + axisangle4f.z * axisangle4f.z);
//        if(d < 1.1102230240000001E-016D)
//        {
//            m00 = 1.0D;
//            m01 = 0.0D;
//            m02 = 0.0D;
//            m10 = 0.0D;
//            m11 = 1.0D;
//            m12 = 0.0D;
//            m20 = 0.0D;
//            m21 = 0.0D;
//            m22 = 1.0D;
//        } else
//        {
//            d = 1.0D / d;
//            double d1 = (double)axisangle4f.x * d;
//            double d2 = (double)axisangle4f.y * d;
//            double d3 = (double)axisangle4f.z * d;
//            double d4 = Math.sin(axisangle4f.angle);
//            double d5 = Math.cos(axisangle4f.angle);
//            double d6 = 1.0D - d5;
//            double d7 = d1 * d3;
//            double d8 = d1 * d2;
//            double d9 = d2 * d3;
//            m00 = d6 * d1 * d1 + d5;
//            m01 = d6 * d8 - d4 * d3;
//            m02 = d6 * d7 + d4 * d2;
//            m10 = d6 * d8 + d4 * d3;
//            m11 = d6 * d2 * d2 + d5;
//            m12 = d6 * d9 - d4 * d1;
//            m20 = d6 * d7 - d4 * d2;
//            m21 = d6 * d9 + d4 * d1;
//            m22 = d6 * d3 * d3 + d5;
//        }
//    }

//    public final void set(Matrix3f matrix3f)
//    {
//        m00 = matrix3f.m00;
//        m01 = matrix3f.m01;
//        m02 = matrix3f.m02;
//        m10 = matrix3f.m10;
//        m11 = matrix3f.m11;
//        m12 = matrix3f.m12;
//        m20 = matrix3f.m20;
//        m21 = matrix3f.m21;
//        m22 = matrix3f.m22;
//    }

    public final void set(Matrix3d matrix3d)
    {
        m00 = matrix3d.m00;
        m01 = matrix3d.m01;
        m02 = matrix3d.m02;
        m10 = matrix3d.m10;
        m11 = matrix3d.m11;
        m12 = matrix3d.m12;
        m20 = matrix3d.m20;
        m21 = matrix3d.m21;
        m22 = matrix3d.m22;
    }

    public final void set(double ad[])
    {
        m00 = ad[0];
        m01 = ad[1];
        m02 = ad[2];
        m10 = ad[3];
        m11 = ad[4];
        m12 = ad[5];
        m20 = ad[6];
        m21 = ad[7];
        m22 = ad[8];
    }

//    public final void invert(Matrix3d matrix3d)
//    {
//        invertGeneral(matrix3d);
//    }
//
    public final void invert()
    {
        invertGeneral(this);
    }

    private final void invertGeneral(Matrix3d matrix3d)
    {
        double ad[] = new double[9];
        int ai[] = new int[3];
        double ad1[] = new double[9];
        ad1[0] = matrix3d.m00;
        ad1[1] = matrix3d.m01;
        ad1[2] = matrix3d.m02;
        ad1[3] = matrix3d.m10;
        ad1[4] = matrix3d.m11;
        ad1[5] = matrix3d.m12;
        ad1[6] = matrix3d.m20;
        ad1[7] = matrix3d.m21;
        ad1[8] = matrix3d.m22;
        if(!luDecomposition(ad1, ai))
			try {
				throw new SingularMatrixException(VecMathI18N.getString("Matrix3d12"));
			} catch (SingularMatrixException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        for(int i = 0; i < 9; i++)
            ad[i] = 0.0D;

        ad[0] = 1.0D;
        ad[4] = 1.0D;
        ad[8] = 1.0D;
        luBacksubstitution(ad1, ai, ad);
        m00 = ad[0];
        m01 = ad[1];
        m02 = ad[2];
        m10 = ad[3];
        m11 = ad[4];
        m12 = ad[5];
        m20 = ad[6];
        m21 = ad[7];
        m22 = ad[8];
    }

    static boolean luDecomposition(double ad[], int ai[])
    {
        double ad1[] = new double[3];
        int i1 = 0;
        int i2 = 0;
        for(int i = 3; i-- != 0;)
        {
            double d = 0.0D;
            for(int k = 3; k-- != 0;)
            {
                double d1 = ad[i1++];
                d1 = Math.abs(d1);
                if(d1 > d)
                    d = d1;
            }

            if(d == 0.0D)
                return false;
            ad1[i2++] = 1.0D / d;
        }

        int l = 0;
        for(int j = 0; j < 3; j++)
        {
            for(int j1 = 0; j1 < j; j1++)
            {
                int j3 = l + 3 * j1 + j;
                double d2 = ad[j3];
                int k2 = j1;
                int i4 = l + 3 * j1;
                for(int l4 = l + j; k2-- != 0; l4 += 3)
                {
                    d2 -= ad[i4] * ad[l4];
                    i4++;
                }

                ad[j3] = d2;
            }

            double d4 = 0.0D;
            int j2 = -1;
            for(int k1 = j; k1 < 3; k1++)
            {
                int k3 = l + 3 * k1 + j;
                double d3 = ad[k3];
                int l2 = j;
                int j4 = l + 3 * k1;
                for(int i5 = l + j; l2-- != 0; i5 += 3)
                {
                    d3 -= ad[j4] * ad[i5];
                    j4++;
                }

                ad[k3] = d3;
                double d5;
                if((d5 = ad1[k1] * Math.abs(d3)) >= d4)
                {
                    d4 = d5;
                    j2 = k1;
                }
            }

            if(j2 < 0)
                throw new RuntimeException(VecMathI18N.getString("Matrix3d13"));
            if(j != j2)
            {
                int i3 = 3;
                int k4 = l + 3 * j2;
                int j5 = l + 3 * j;
                while(i3-- != 0) 
                {
                    double d6 = ad[k4];
                    ad[k4++] = ad[j5];
                    ad[j5++] = d6;
                }
                ad1[j2] = ad1[j];
            }
            ai[j] = j2;
            if(ad[l + 3 * j + j] == 0.0D)
                return false;
            if(j != 2)
            {
                double d7 = 1.0D / ad[l + 3 * j + j];
                int l3 = l + 3 * (j + 1) + j;
                for(int l1 = 2 - j; l1-- != 0;)
                {
                    ad[l3] *= d7;
                    l3 += 3;
                }

            }
        }

        return true;
    }

    static void luBacksubstitution(double ad[], int ai[], double ad1[])
    {
        int j1 = 0;
        for(int i1 = 0; i1 < 3; i1++)
        {
            int k1 = i1;
            int j = -1;
            for(int i = 0; i < 3; i++)
            {
                int k = ai[j1 + i];
                double d = ad1[k1 + 3 * k];
                ad1[k1 + 3 * k] = ad1[k1 + 3 * i];
                if(j >= 0)
                {
                    int l1 = i * 3;
                    for(int l = j; l <= i - 1; l++)
                        d -= ad[l1 + l] * ad1[k1 + 3 * l];

                } else
                if(d != 0.0D)
                    j = i;
                ad1[k1 + 3 * i] = d;
            }

            int i2 = 6;
            ad1[k1 + 6] /= ad[i2 + 2];
            i2 -= 3;
            ad1[k1 + 3] = (ad1[k1 + 3] - ad[i2 + 2] * ad1[k1 + 6]) / ad[i2 + 1];
            i2 -= 3;
            ad1[k1 + 0] = (ad1[k1 + 0] - ad[i2 + 1] * ad1[k1 + 3] - ad[i2 + 2] * ad1[k1 + 6]) / ad[i2 + 0];
        }

    }

    public final double determinant()
    {
        double d = m00 * (m11 * m22 - m12 * m21) + m01 * (m12 * m20 - m10 * m22) + m02 * (m10 * m21 - m11 * m20);
        return d;
    }

    public final void set(double d)
    {
        m00 = d;
        m01 = 0.0D;
        m02 = 0.0D;
        m10 = 0.0D;
        m11 = d;
        m12 = 0.0D;
        m20 = 0.0D;
        m21 = 0.0D;
        m22 = d;
    }

    public final void rotX(double d)
    {
        double d1 = Math.sin(d);
        double d2 = Math.cos(d);
        m00 = 1.0D;
        m01 = 0.0D;
        m02 = 0.0D;
        m10 = 0.0D;
        m11 = d2;
        m12 = -d1;
        m20 = 0.0D;
        m21 = d1;
        m22 = d2;
    }

    public final void rotY(double d)
    {
        double d1 = Math.sin(d);
        double d2 = Math.cos(d);
        m00 = d2;
        m01 = 0.0D;
        m02 = d1;
        m10 = 0.0D;
        m11 = 1.0D;
        m12 = 0.0D;
        m20 = -d1;
        m21 = 0.0D;
        m22 = d2;
    }

    public final void rotZ(double d)
    {
        double d1 = Math.sin(d);
        double d2 = Math.cos(d);
        m00 = d2;
        m01 = -d1;
        m02 = 0.0D;
        m10 = d1;
        m11 = d2;
        m12 = 0.0D;
        m20 = 0.0D;
        m21 = 0.0D;
        m22 = 1.0D;
    }

    public final void mul(double d)
    {
        m00 *= d;
        m01 *= d;
        m02 *= d;
        m10 *= d;
        m11 *= d;
        m12 *= d;
        m20 *= d;
        m21 *= d;
        m22 *= d;
    }

    public final void mul(double d, Matrix3d matrix3d)
    {
        m00 = d * matrix3d.m00;
        m01 = d * matrix3d.m01;
        m02 = d * matrix3d.m02;
        m10 = d * matrix3d.m10;
        m11 = d * matrix3d.m11;
        m12 = d * matrix3d.m12;
        m20 = d * matrix3d.m20;
        m21 = d * matrix3d.m21;
        m22 = d * matrix3d.m22;
    }

    public final void mul(Matrix3d matrix3d)
    {
        double d = m00 * matrix3d.m00 + m01 * matrix3d.m10 + m02 * matrix3d.m20;
        double d1 = m00 * matrix3d.m01 + m01 * matrix3d.m11 + m02 * matrix3d.m21;
        double d2 = m00 * matrix3d.m02 + m01 * matrix3d.m12 + m02 * matrix3d.m22;
        double d3 = m10 * matrix3d.m00 + m11 * matrix3d.m10 + m12 * matrix3d.m20;
        double d4 = m10 * matrix3d.m01 + m11 * matrix3d.m11 + m12 * matrix3d.m21;
        double d5 = m10 * matrix3d.m02 + m11 * matrix3d.m12 + m12 * matrix3d.m22;
        double d6 = m20 * matrix3d.m00 + m21 * matrix3d.m10 + m22 * matrix3d.m20;
        double d7 = m20 * matrix3d.m01 + m21 * matrix3d.m11 + m22 * matrix3d.m21;
        double d8 = m20 * matrix3d.m02 + m21 * matrix3d.m12 + m22 * matrix3d.m22;
        m00 = d;
        m01 = d1;
        m02 = d2;
        m10 = d3;
        m11 = d4;
        m12 = d5;
        m20 = d6;
        m21 = d7;
        m22 = d8;
    }

    public final void mul(Matrix3d matrix3d, Matrix3d matrix3d1)
    {
        if(this != matrix3d && this != matrix3d1)
        {
            m00 = matrix3d.m00 * matrix3d1.m00 + matrix3d.m01 * matrix3d1.m10 + matrix3d.m02 * matrix3d1.m20;
            m01 = matrix3d.m00 * matrix3d1.m01 + matrix3d.m01 * matrix3d1.m11 + matrix3d.m02 * matrix3d1.m21;
            m02 = matrix3d.m00 * matrix3d1.m02 + matrix3d.m01 * matrix3d1.m12 + matrix3d.m02 * matrix3d1.m22;
            m10 = matrix3d.m10 * matrix3d1.m00 + matrix3d.m11 * matrix3d1.m10 + matrix3d.m12 * matrix3d1.m20;
            m11 = matrix3d.m10 * matrix3d1.m01 + matrix3d.m11 * matrix3d1.m11 + matrix3d.m12 * matrix3d1.m21;
            m12 = matrix3d.m10 * matrix3d1.m02 + matrix3d.m11 * matrix3d1.m12 + matrix3d.m12 * matrix3d1.m22;
            m20 = matrix3d.m20 * matrix3d1.m00 + matrix3d.m21 * matrix3d1.m10 + matrix3d.m22 * matrix3d1.m20;
            m21 = matrix3d.m20 * matrix3d1.m01 + matrix3d.m21 * matrix3d1.m11 + matrix3d.m22 * matrix3d1.m21;
            m22 = matrix3d.m20 * matrix3d1.m02 + matrix3d.m21 * matrix3d1.m12 + matrix3d.m22 * matrix3d1.m22;
        } else
        {
            double d = matrix3d.m00 * matrix3d1.m00 + matrix3d.m01 * matrix3d1.m10 + matrix3d.m02 * matrix3d1.m20;
            double d1 = matrix3d.m00 * matrix3d1.m01 + matrix3d.m01 * matrix3d1.m11 + matrix3d.m02 * matrix3d1.m21;
            double d2 = matrix3d.m00 * matrix3d1.m02 + matrix3d.m01 * matrix3d1.m12 + matrix3d.m02 * matrix3d1.m22;
            double d3 = matrix3d.m10 * matrix3d1.m00 + matrix3d.m11 * matrix3d1.m10 + matrix3d.m12 * matrix3d1.m20;
            double d4 = matrix3d.m10 * matrix3d1.m01 + matrix3d.m11 * matrix3d1.m11 + matrix3d.m12 * matrix3d1.m21;
            double d5 = matrix3d.m10 * matrix3d1.m02 + matrix3d.m11 * matrix3d1.m12 + matrix3d.m12 * matrix3d1.m22;
            double d6 = matrix3d.m20 * matrix3d1.m00 + matrix3d.m21 * matrix3d1.m10 + matrix3d.m22 * matrix3d1.m20;
            double d7 = matrix3d.m20 * matrix3d1.m01 + matrix3d.m21 * matrix3d1.m11 + matrix3d.m22 * matrix3d1.m21;
            double d8 = matrix3d.m20 * matrix3d1.m02 + matrix3d.m21 * matrix3d1.m12 + matrix3d.m22 * matrix3d1.m22;
            m00 = d;
            m01 = d1;
            m02 = d2;
            m10 = d3;
            m11 = d4;
            m12 = d5;
            m20 = d6;
            m21 = d7;
            m22 = d8;
        }
    }

    public final void mulNormalize(Matrix3d matrix3d)
    {
        double ad[] = new double[9];
        double ad1[] = new double[9];
        double ad2[] = new double[3];
        ad[0] = m00 * matrix3d.m00 + m01 * matrix3d.m10 + m02 * matrix3d.m20;
        ad[1] = m00 * matrix3d.m01 + m01 * matrix3d.m11 + m02 * matrix3d.m21;
        ad[2] = m00 * matrix3d.m02 + m01 * matrix3d.m12 + m02 * matrix3d.m22;
        ad[3] = m10 * matrix3d.m00 + m11 * matrix3d.m10 + m12 * matrix3d.m20;
        ad[4] = m10 * matrix3d.m01 + m11 * matrix3d.m11 + m12 * matrix3d.m21;
        ad[5] = m10 * matrix3d.m02 + m11 * matrix3d.m12 + m12 * matrix3d.m22;
        ad[6] = m20 * matrix3d.m00 + m21 * matrix3d.m10 + m22 * matrix3d.m20;
        ad[7] = m20 * matrix3d.m01 + m21 * matrix3d.m11 + m22 * matrix3d.m21;
        ad[8] = m20 * matrix3d.m02 + m21 * matrix3d.m12 + m22 * matrix3d.m22;
        compute_svd(ad, ad2, ad1);
        m00 = ad1[0];
        m01 = ad1[1];
        m02 = ad1[2];
        m10 = ad1[3];
        m11 = ad1[4];
        m12 = ad1[5];
        m20 = ad1[6];
        m21 = ad1[7];
        m22 = ad1[8];
    }

    public final void mulNormalize(Matrix3d matrix3d, Matrix3d matrix3d1)
    {
        double ad[] = new double[9];
        double ad1[] = new double[9];
        double ad2[] = new double[3];
        ad[0] = matrix3d.m00 * matrix3d1.m00 + matrix3d.m01 * matrix3d1.m10 + matrix3d.m02 * matrix3d1.m20;
        ad[1] = matrix3d.m00 * matrix3d1.m01 + matrix3d.m01 * matrix3d1.m11 + matrix3d.m02 * matrix3d1.m21;
        ad[2] = matrix3d.m00 * matrix3d1.m02 + matrix3d.m01 * matrix3d1.m12 + matrix3d.m02 * matrix3d1.m22;
        ad[3] = matrix3d.m10 * matrix3d1.m00 + matrix3d.m11 * matrix3d1.m10 + matrix3d.m12 * matrix3d1.m20;
        ad[4] = matrix3d.m10 * matrix3d1.m01 + matrix3d.m11 * matrix3d1.m11 + matrix3d.m12 * matrix3d1.m21;
        ad[5] = matrix3d.m10 * matrix3d1.m02 + matrix3d.m11 * matrix3d1.m12 + matrix3d.m12 * matrix3d1.m22;
        ad[6] = matrix3d.m20 * matrix3d1.m00 + matrix3d.m21 * matrix3d1.m10 + matrix3d.m22 * matrix3d1.m20;
        ad[7] = matrix3d.m20 * matrix3d1.m01 + matrix3d.m21 * matrix3d1.m11 + matrix3d.m22 * matrix3d1.m21;
        ad[8] = matrix3d.m20 * matrix3d1.m02 + matrix3d.m21 * matrix3d1.m12 + matrix3d.m22 * matrix3d1.m22;
        compute_svd(ad, ad2, ad1);
        m00 = ad1[0];
        m01 = ad1[1];
        m02 = ad1[2];
        m10 = ad1[3];
        m11 = ad1[4];
        m12 = ad1[5];
        m20 = ad1[6];
        m21 = ad1[7];
        m22 = ad1[8];
    }

    public final void mulTransposeBoth(Matrix3d matrix3d, Matrix3d matrix3d1)
    {
        if(this != matrix3d && this != matrix3d1)
        {
            m00 = matrix3d.m00 * matrix3d1.m00 + matrix3d.m10 * matrix3d1.m01 + matrix3d.m20 * matrix3d1.m02;
            m01 = matrix3d.m00 * matrix3d1.m10 + matrix3d.m10 * matrix3d1.m11 + matrix3d.m20 * matrix3d1.m12;
            m02 = matrix3d.m00 * matrix3d1.m20 + matrix3d.m10 * matrix3d1.m21 + matrix3d.m20 * matrix3d1.m22;
            m10 = matrix3d.m01 * matrix3d1.m00 + matrix3d.m11 * matrix3d1.m01 + matrix3d.m21 * matrix3d1.m02;
            m11 = matrix3d.m01 * matrix3d1.m10 + matrix3d.m11 * matrix3d1.m11 + matrix3d.m21 * matrix3d1.m12;
            m12 = matrix3d.m01 * matrix3d1.m20 + matrix3d.m11 * matrix3d1.m21 + matrix3d.m21 * matrix3d1.m22;
            m20 = matrix3d.m02 * matrix3d1.m00 + matrix3d.m12 * matrix3d1.m01 + matrix3d.m22 * matrix3d1.m02;
            m21 = matrix3d.m02 * matrix3d1.m10 + matrix3d.m12 * matrix3d1.m11 + matrix3d.m22 * matrix3d1.m12;
            m22 = matrix3d.m02 * matrix3d1.m20 + matrix3d.m12 * matrix3d1.m21 + matrix3d.m22 * matrix3d1.m22;
        } else
        {
            double d = matrix3d.m00 * matrix3d1.m00 + matrix3d.m10 * matrix3d1.m01 + matrix3d.m20 * matrix3d1.m02;
            double d1 = matrix3d.m00 * matrix3d1.m10 + matrix3d.m10 * matrix3d1.m11 + matrix3d.m20 * matrix3d1.m12;
            double d2 = matrix3d.m00 * matrix3d1.m20 + matrix3d.m10 * matrix3d1.m21 + matrix3d.m20 * matrix3d1.m22;
            double d3 = matrix3d.m01 * matrix3d1.m00 + matrix3d.m11 * matrix3d1.m01 + matrix3d.m21 * matrix3d1.m02;
            double d4 = matrix3d.m01 * matrix3d1.m10 + matrix3d.m11 * matrix3d1.m11 + matrix3d.m21 * matrix3d1.m12;
            double d5 = matrix3d.m01 * matrix3d1.m20 + matrix3d.m11 * matrix3d1.m21 + matrix3d.m21 * matrix3d1.m22;
            double d6 = matrix3d.m02 * matrix3d1.m00 + matrix3d.m12 * matrix3d1.m01 + matrix3d.m22 * matrix3d1.m02;
            double d7 = matrix3d.m02 * matrix3d1.m10 + matrix3d.m12 * matrix3d1.m11 + matrix3d.m22 * matrix3d1.m12;
            double d8 = matrix3d.m02 * matrix3d1.m20 + matrix3d.m12 * matrix3d1.m21 + matrix3d.m22 * matrix3d1.m22;
            m00 = d;
            m01 = d1;
            m02 = d2;
            m10 = d3;
            m11 = d4;
            m12 = d5;
            m20 = d6;
            m21 = d7;
            m22 = d8;
        }
    }

    public final void mulTransposeRight(Matrix3d matrix3d, Matrix3d matrix3d1)
    {
        if(this != matrix3d && this != matrix3d1)
        {
            m00 = matrix3d.m00 * matrix3d1.m00 + matrix3d.m01 * matrix3d1.m01 + matrix3d.m02 * matrix3d1.m02;
            m01 = matrix3d.m00 * matrix3d1.m10 + matrix3d.m01 * matrix3d1.m11 + matrix3d.m02 * matrix3d1.m12;
            m02 = matrix3d.m00 * matrix3d1.m20 + matrix3d.m01 * matrix3d1.m21 + matrix3d.m02 * matrix3d1.m22;
            m10 = matrix3d.m10 * matrix3d1.m00 + matrix3d.m11 * matrix3d1.m01 + matrix3d.m12 * matrix3d1.m02;
            m11 = matrix3d.m10 * matrix3d1.m10 + matrix3d.m11 * matrix3d1.m11 + matrix3d.m12 * matrix3d1.m12;
            m12 = matrix3d.m10 * matrix3d1.m20 + matrix3d.m11 * matrix3d1.m21 + matrix3d.m12 * matrix3d1.m22;
            m20 = matrix3d.m20 * matrix3d1.m00 + matrix3d.m21 * matrix3d1.m01 + matrix3d.m22 * matrix3d1.m02;
            m21 = matrix3d.m20 * matrix3d1.m10 + matrix3d.m21 * matrix3d1.m11 + matrix3d.m22 * matrix3d1.m12;
            m22 = matrix3d.m20 * matrix3d1.m20 + matrix3d.m21 * matrix3d1.m21 + matrix3d.m22 * matrix3d1.m22;
        } else
        {
            double d = matrix3d.m00 * matrix3d1.m00 + matrix3d.m01 * matrix3d1.m01 + matrix3d.m02 * matrix3d1.m02;
            double d1 = matrix3d.m00 * matrix3d1.m10 + matrix3d.m01 * matrix3d1.m11 + matrix3d.m02 * matrix3d1.m12;
            double d2 = matrix3d.m00 * matrix3d1.m20 + matrix3d.m01 * matrix3d1.m21 + matrix3d.m02 * matrix3d1.m22;
            double d3 = matrix3d.m10 * matrix3d1.m00 + matrix3d.m11 * matrix3d1.m01 + matrix3d.m12 * matrix3d1.m02;
            double d4 = matrix3d.m10 * matrix3d1.m10 + matrix3d.m11 * matrix3d1.m11 + matrix3d.m12 * matrix3d1.m12;
            double d5 = matrix3d.m10 * matrix3d1.m20 + matrix3d.m11 * matrix3d1.m21 + matrix3d.m12 * matrix3d1.m22;
            double d6 = matrix3d.m20 * matrix3d1.m00 + matrix3d.m21 * matrix3d1.m01 + matrix3d.m22 * matrix3d1.m02;
            double d7 = matrix3d.m20 * matrix3d1.m10 + matrix3d.m21 * matrix3d1.m11 + matrix3d.m22 * matrix3d1.m12;
            double d8 = matrix3d.m20 * matrix3d1.m20 + matrix3d.m21 * matrix3d1.m21 + matrix3d.m22 * matrix3d1.m22;
            m00 = d;
            m01 = d1;
            m02 = d2;
            m10 = d3;
            m11 = d4;
            m12 = d5;
            m20 = d6;
            m21 = d7;
            m22 = d8;
        }
    }

    public final void mulTransposeLeft(Matrix3d matrix3d, Matrix3d matrix3d1)
    {
        if(this != matrix3d && this != matrix3d1)
        {
            m00 = matrix3d.m00 * matrix3d1.m00 + matrix3d.m10 * matrix3d1.m10 + matrix3d.m20 * matrix3d1.m20;
            m01 = matrix3d.m00 * matrix3d1.m01 + matrix3d.m10 * matrix3d1.m11 + matrix3d.m20 * matrix3d1.m21;
            m02 = matrix3d.m00 * matrix3d1.m02 + matrix3d.m10 * matrix3d1.m12 + matrix3d.m20 * matrix3d1.m22;
            m10 = matrix3d.m01 * matrix3d1.m00 + matrix3d.m11 * matrix3d1.m10 + matrix3d.m21 * matrix3d1.m20;
            m11 = matrix3d.m01 * matrix3d1.m01 + matrix3d.m11 * matrix3d1.m11 + matrix3d.m21 * matrix3d1.m21;
            m12 = matrix3d.m01 * matrix3d1.m02 + matrix3d.m11 * matrix3d1.m12 + matrix3d.m21 * matrix3d1.m22;
            m20 = matrix3d.m02 * matrix3d1.m00 + matrix3d.m12 * matrix3d1.m10 + matrix3d.m22 * matrix3d1.m20;
            m21 = matrix3d.m02 * matrix3d1.m01 + matrix3d.m12 * matrix3d1.m11 + matrix3d.m22 * matrix3d1.m21;
            m22 = matrix3d.m02 * matrix3d1.m02 + matrix3d.m12 * matrix3d1.m12 + matrix3d.m22 * matrix3d1.m22;
        } else
        {
            double d = matrix3d.m00 * matrix3d1.m00 + matrix3d.m10 * matrix3d1.m10 + matrix3d.m20 * matrix3d1.m20;
            double d1 = matrix3d.m00 * matrix3d1.m01 + matrix3d.m10 * matrix3d1.m11 + matrix3d.m20 * matrix3d1.m21;
            double d2 = matrix3d.m00 * matrix3d1.m02 + matrix3d.m10 * matrix3d1.m12 + matrix3d.m20 * matrix3d1.m22;
            double d3 = matrix3d.m01 * matrix3d1.m00 + matrix3d.m11 * matrix3d1.m10 + matrix3d.m21 * matrix3d1.m20;
            double d4 = matrix3d.m01 * matrix3d1.m01 + matrix3d.m11 * matrix3d1.m11 + matrix3d.m21 * matrix3d1.m21;
            double d5 = matrix3d.m01 * matrix3d1.m02 + matrix3d.m11 * matrix3d1.m12 + matrix3d.m21 * matrix3d1.m22;
            double d6 = matrix3d.m02 * matrix3d1.m00 + matrix3d.m12 * matrix3d1.m10 + matrix3d.m22 * matrix3d1.m20;
            double d7 = matrix3d.m02 * matrix3d1.m01 + matrix3d.m12 * matrix3d1.m11 + matrix3d.m22 * matrix3d1.m21;
            double d8 = matrix3d.m02 * matrix3d1.m02 + matrix3d.m12 * matrix3d1.m12 + matrix3d.m22 * matrix3d1.m22;
            m00 = d;
            m01 = d1;
            m02 = d2;
            m10 = d3;
            m11 = d4;
            m12 = d5;
            m20 = d6;
            m21 = d7;
            m22 = d8;
        }
    }

    public final void normalize()
    {
        double ad[] = new double[9];
        double ad1[] = new double[3];
        getScaleRotate(ad1, ad);
        m00 = ad[0];
        m01 = ad[1];
        m02 = ad[2];
        m10 = ad[3];
        m11 = ad[4];
        m12 = ad[5];
        m20 = ad[6];
        m21 = ad[7];
        m22 = ad[8];
    }

    public final void normalize(Matrix3d matrix3d)
    {
        double ad[] = new double[9];
        double ad1[] = new double[9];
        double ad2[] = new double[3];
        ad[0] = matrix3d.m00;
        ad[1] = matrix3d.m01;
        ad[2] = matrix3d.m02;
        ad[3] = matrix3d.m10;
        ad[4] = matrix3d.m11;
        ad[5] = matrix3d.m12;
        ad[6] = matrix3d.m20;
        ad[7] = matrix3d.m21;
        ad[8] = matrix3d.m22;
        compute_svd(ad, ad2, ad1);
        m00 = ad1[0];
        m01 = ad1[1];
        m02 = ad1[2];
        m10 = ad1[3];
        m11 = ad1[4];
        m12 = ad1[5];
        m20 = ad1[6];
        m21 = ad1[7];
        m22 = ad1[8];
    }

    public final void normalizeCP()
    {
        double d = 1.0D / Math.sqrt(m00 * m00 + m10 * m10 + m20 * m20);
        m00 = m00 * d;
        m10 = m10 * d;
        m20 = m20 * d;
        d = 1.0D / Math.sqrt(m01 * m01 + m11 * m11 + m21 * m21);
        m01 = m01 * d;
        m11 = m11 * d;
        m21 = m21 * d;
        m02 = m10 * m21 - m11 * m20;
        m12 = m01 * m20 - m00 * m21;
        m22 = m00 * m11 - m01 * m10;
    }

    public final void normalizeCP(Matrix3d matrix3d)
    {
        double d = 1.0D / Math.sqrt(matrix3d.m00 * matrix3d.m00 + matrix3d.m10 * matrix3d.m10 + matrix3d.m20 * matrix3d.m20);
        m00 = matrix3d.m00 * d;
        m10 = matrix3d.m10 * d;
        m20 = matrix3d.m20 * d;
        d = 1.0D / Math.sqrt(matrix3d.m01 * matrix3d.m01 + matrix3d.m11 * matrix3d.m11 + matrix3d.m21 * matrix3d.m21);
        m01 = matrix3d.m01 * d;
        m11 = matrix3d.m11 * d;
        m21 = matrix3d.m21 * d;
        m02 = m10 * m21 - m11 * m20;
        m12 = m01 * m20 - m00 * m21;
        m22 = m00 * m11 - m01 * m10;
    }

    public boolean equals(Matrix3d matrix3d)
    {
        try
        {
            return m00 == matrix3d.m00 && m01 == matrix3d.m01 && m02 == matrix3d.m02 && m10 == matrix3d.m10 && m11 == matrix3d.m11 && m12 == matrix3d.m12 && m20 == matrix3d.m20 && m21 == matrix3d.m21 && m22 == matrix3d.m22;
        }
        catch(NullPointerException nullpointerexception)
        {
            return false;
        }
    }

    public boolean equals(Object obj)
    {
        try
        {
            Matrix3d matrix3d = (Matrix3d)obj;
            return m00 == matrix3d.m00 && m01 == matrix3d.m01 && m02 == matrix3d.m02 && m10 == matrix3d.m10 && m11 == matrix3d.m11 && m12 == matrix3d.m12 && m20 == matrix3d.m20 && m21 == matrix3d.m21 && m22 == matrix3d.m22;
        }
        catch(ClassCastException classcastexception)
        {
            return false;
        }
        catch(NullPointerException nullpointerexception)
        {
            return false;
        }
    }

    public boolean epsilonEquals(Matrix3d matrix3d, double d)
    {
        double d1 = m00 - matrix3d.m00;
        if((d1 >= 0.0D ? d1 : -d1) > d)
            return false;
        d1 = m01 - matrix3d.m01;
        if((d1 >= 0.0D ? d1 : -d1) > d)
            return false;
        d1 = m02 - matrix3d.m02;
        if((d1 >= 0.0D ? d1 : -d1) > d)
            return false;
        d1 = m10 - matrix3d.m10;
        if((d1 >= 0.0D ? d1 : -d1) > d)
            return false;
        d1 = m11 - matrix3d.m11;
        if((d1 >= 0.0D ? d1 : -d1) > d)
            return false;
        d1 = m12 - matrix3d.m12;
        if((d1 >= 0.0D ? d1 : -d1) > d)
            return false;
        d1 = m20 - matrix3d.m20;
        if((d1 >= 0.0D ? d1 : -d1) > d)
            return false;
        d1 = m21 - matrix3d.m21;
        if((d1 >= 0.0D ? d1 : -d1) > d)
            return false;
        d1 = m22 - matrix3d.m22;
        return (d1 >= 0.0D ? d1 : -d1) <= d;
    }

    public int hashCode()
    {
        long l = 1L;
        l = 31L * l + Double.doubleToLongBits(m00);
        l = 31L * l + Double.doubleToLongBits(m01);
        l = 31L * l + Double.doubleToLongBits(m02);
        l = 31L * l + Double.doubleToLongBits(m10);
        l = 31L * l + Double.doubleToLongBits(m11);
        l = 31L * l + Double.doubleToLongBits(m12);
        l = 31L * l + Double.doubleToLongBits(m20);
        l = 31L * l + Double.doubleToLongBits(m21);
        l = 31L * l + Double.doubleToLongBits(m22);
        return (int)(l ^ l >> 32);
    }

    public final void setZero()
    {
        m00 = 0.0D;
        m01 = 0.0D;
        m02 = 0.0D;
        m10 = 0.0D;
        m11 = 0.0D;
        m12 = 0.0D;
        m20 = 0.0D;
        m21 = 0.0D;
        m22 = 0.0D;
    }

    public final void negate()
    {
        m00 = -m00;
        m01 = -m01;
        m02 = -m02;
        m10 = -m10;
        m11 = -m11;
        m12 = -m12;
        m20 = -m20;
        m21 = -m21;
        m22 = -m22;
    }

    public final void negate(Matrix3d matrix3d)
    {
        m00 = -matrix3d.m00;
        m01 = -matrix3d.m01;
        m02 = -matrix3d.m02;
        m10 = -matrix3d.m10;
        m11 = -matrix3d.m11;
        m12 = -matrix3d.m12;
        m20 = -matrix3d.m20;
        m21 = -matrix3d.m21;
        m22 = -matrix3d.m22;
    }

    public final void transform(Tuple3d tuple3d)
    {
        double d = m00 * tuple3d.x + m01 * tuple3d.y + m02 * tuple3d.z;
        double d1 = m10 * tuple3d.x + m11 * tuple3d.y + m12 * tuple3d.z;
        double d2 = m20 * tuple3d.x + m21 * tuple3d.y + m22 * tuple3d.z;
        tuple3d.set(d, d1, d2);
    }

    public final void transform(Tuple3d tuple3d, Tuple3d tuple3d1)
    {
        double d = m00 * tuple3d.x + m01 * tuple3d.y + m02 * tuple3d.z;
        double d1 = m10 * tuple3d.x + m11 * tuple3d.y + m12 * tuple3d.z;
        tuple3d1.z = m20 * tuple3d.x + m21 * tuple3d.y + m22 * tuple3d.z;
        tuple3d1.x = d;
        tuple3d1.y = d1;
    }

    final void getScaleRotate(double ad[], double ad1[])
    {
        double ad2[] = new double[9];
        ad2[0] = m00;
        ad2[1] = m01;
        ad2[2] = m02;
        ad2[3] = m10;
        ad2[4] = m11;
        ad2[5] = m12;
        ad2[6] = m20;
        ad2[7] = m21;
        ad2[8] = m22;
        compute_svd(ad2, ad, ad1);
    }

    static void compute_svd(double ad[], double ad1[], double ad2[])
    {
        double ad3[] = new double[9];
        double ad4[] = new double[9];
        double ad5[] = new double[9];
        double ad6[] = new double[9];
        double ad7[] = ad5;
        double ad8[] = ad6;
        double ad9[] = new double[9];
        double ad10[] = new double[3];
        double ad11[] = new double[3];
        int l = 0;
        for(int i = 0; i < 9; i++)
            ad9[i] = ad[i];

        if(ad[3] * ad[3] < 1.1102230240000001E-016D)
        {
            ad3[0] = 1.0D;
            ad3[1] = 0.0D;
            ad3[2] = 0.0D;
            ad3[3] = 0.0D;
            ad3[4] = 1.0D;
            ad3[5] = 0.0D;
            ad3[6] = 0.0D;
            ad3[7] = 0.0D;
            ad3[8] = 1.0D;
        } else
        if(ad[0] * ad[0] < 1.1102230240000001E-016D)
        {
            ad7[0] = ad[0];
            ad7[1] = ad[1];
            ad7[2] = ad[2];
            ad[0] = ad[3];
            ad[1] = ad[4];
            ad[2] = ad[5];
            ad[3] = -ad7[0];
            ad[4] = -ad7[1];
            ad[5] = -ad7[2];
            ad3[0] = 0.0D;
            ad3[1] = 1.0D;
            ad3[2] = 0.0D;
            ad3[3] = -1D;
            ad3[4] = 0.0D;
            ad3[5] = 0.0D;
            ad3[6] = 0.0D;
            ad3[7] = 0.0D;
            ad3[8] = 1.0D;
        } else
        {
            double d = 1.0D / Math.sqrt(ad[0] * ad[0] + ad[3] * ad[3]);
            double d4 = ad[0] * d;
            double d8 = ad[3] * d;
            ad7[0] = d4 * ad[0] + d8 * ad[3];
            ad7[1] = d4 * ad[1] + d8 * ad[4];
            ad7[2] = d4 * ad[2] + d8 * ad[5];
            ad[3] = -d8 * ad[0] + d4 * ad[3];
            ad[4] = -d8 * ad[1] + d4 * ad[4];
            ad[5] = -d8 * ad[2] + d4 * ad[5];
            ad[0] = ad7[0];
            ad[1] = ad7[1];
            ad[2] = ad7[2];
            ad3[0] = d4;
            ad3[1] = d8;
            ad3[2] = 0.0D;
            ad3[3] = -d8;
            ad3[4] = d4;
            ad3[5] = 0.0D;
            ad3[6] = 0.0D;
            ad3[7] = 0.0D;
            ad3[8] = 1.0D;
        }
        if(ad[6] * ad[6] >= 1.1102230240000001E-016D)
            if(ad[0] * ad[0] < 1.1102230240000001E-016D)
            {
                ad7[0] = ad[0];
                ad7[1] = ad[1];
                ad7[2] = ad[2];
                ad[0] = ad[6];
                ad[1] = ad[7];
                ad[2] = ad[8];
                ad[6] = -ad7[0];
                ad[7] = -ad7[1];
                ad[8] = -ad7[2];
                ad7[0] = ad3[0];
                ad7[1] = ad3[1];
                ad7[2] = ad3[2];
                ad3[0] = ad3[6];
                ad3[1] = ad3[7];
                ad3[2] = ad3[8];
                ad3[6] = -ad7[0];
                ad3[7] = -ad7[1];
                ad3[8] = -ad7[2];
            } else
            {
                double d1 = 1.0D / Math.sqrt(ad[0] * ad[0] + ad[6] * ad[6]);
                double d5 = ad[0] * d1;
                double d9 = ad[6] * d1;
                ad7[0] = d5 * ad[0] + d9 * ad[6];
                ad7[1] = d5 * ad[1] + d9 * ad[7];
                ad7[2] = d5 * ad[2] + d9 * ad[8];
                ad[6] = -d9 * ad[0] + d5 * ad[6];
                ad[7] = -d9 * ad[1] + d5 * ad[7];
                ad[8] = -d9 * ad[2] + d5 * ad[8];
                ad[0] = ad7[0];
                ad[1] = ad7[1];
                ad[2] = ad7[2];
                ad7[0] = d5 * ad3[0];
                ad7[1] = d5 * ad3[1];
                ad3[2] = d9;
                ad7[6] = -ad3[0] * d9;
                ad7[7] = -ad3[1] * d9;
                ad3[8] = d5;
                ad3[0] = ad7[0];
                ad3[1] = ad7[1];
                ad3[6] = ad7[6];
                ad3[7] = ad7[7];
            }
        if(ad[2] * ad[2] < 1.1102230240000001E-016D)
        {
            ad4[0] = 1.0D;
            ad4[1] = 0.0D;
            ad4[2] = 0.0D;
            ad4[3] = 0.0D;
            ad4[4] = 1.0D;
            ad4[5] = 0.0D;
            ad4[6] = 0.0D;
            ad4[7] = 0.0D;
            ad4[8] = 1.0D;
        } else
        if(ad[1] * ad[1] < 1.1102230240000001E-016D)
        {
            ad7[2] = ad[2];
            ad7[5] = ad[5];
            ad7[8] = ad[8];
            ad[2] = -ad[1];
            ad[5] = -ad[4];
            ad[8] = -ad[7];
            ad[1] = ad7[2];
            ad[4] = ad7[5];
            ad[7] = ad7[8];
            ad4[0] = 1.0D;
            ad4[1] = 0.0D;
            ad4[2] = 0.0D;
            ad4[3] = 0.0D;
            ad4[4] = 0.0D;
            ad4[5] = -1D;
            ad4[6] = 0.0D;
            ad4[7] = 1.0D;
            ad4[8] = 0.0D;
        } else
        {
            double d2 = 1.0D / Math.sqrt(ad[1] * ad[1] + ad[2] * ad[2]);
            double d6 = ad[1] * d2;
            double d10 = ad[2] * d2;
            ad7[1] = d6 * ad[1] + d10 * ad[2];
            ad[2] = -d10 * ad[1] + d6 * ad[2];
            ad[1] = ad7[1];
            ad7[4] = d6 * ad[4] + d10 * ad[5];
            ad[5] = -d10 * ad[4] + d6 * ad[5];
            ad[4] = ad7[4];
            ad7[7] = d6 * ad[7] + d10 * ad[8];
            ad[8] = -d10 * ad[7] + d6 * ad[8];
            ad[7] = ad7[7];
            ad4[0] = 1.0D;
            ad4[1] = 0.0D;
            ad4[2] = 0.0D;
            ad4[3] = 0.0D;
            ad4[4] = d6;
            ad4[5] = -d10;
            ad4[6] = 0.0D;
            ad4[7] = d10;
            ad4[8] = d6;
        }
        if(ad[7] * ad[7] >= 1.1102230240000001E-016D)
            if(ad[4] * ad[4] < 1.1102230240000001E-016D)
            {
                ad7[3] = ad[3];
                ad7[4] = ad[4];
                ad7[5] = ad[5];
                ad[3] = ad[6];
                ad[4] = ad[7];
                ad[5] = ad[8];
                ad[6] = -ad7[3];
                ad[7] = -ad7[4];
                ad[8] = -ad7[5];
                ad7[3] = ad3[3];
                ad7[4] = ad3[4];
                ad7[5] = ad3[5];
                ad3[3] = ad3[6];
                ad3[4] = ad3[7];
                ad3[5] = ad3[8];
                ad3[6] = -ad7[3];
                ad3[7] = -ad7[4];
                ad3[8] = -ad7[5];
            } else
            {
                double d3 = 1.0D / Math.sqrt(ad[4] * ad[4] + ad[7] * ad[7]);
                double d7 = ad[4] * d3;
                double d11 = ad[7] * d3;
                ad7[3] = d7 * ad[3] + d11 * ad[6];
                ad[6] = -d11 * ad[3] + d7 * ad[6];
                ad[3] = ad7[3];
                ad7[4] = d7 * ad[4] + d11 * ad[7];
                ad[7] = -d11 * ad[4] + d7 * ad[7];
                ad[4] = ad7[4];
                ad7[5] = d7 * ad[5] + d11 * ad[8];
                ad[8] = -d11 * ad[5] + d7 * ad[8];
                ad[5] = ad7[5];
                ad7[3] = d7 * ad3[3] + d11 * ad3[6];
                ad3[6] = -d11 * ad3[3] + d7 * ad3[6];
                ad3[3] = ad7[3];
                ad7[4] = d7 * ad3[4] + d11 * ad3[7];
                ad3[7] = -d11 * ad3[4] + d7 * ad3[7];
                ad3[4] = ad7[4];
                ad7[5] = d7 * ad3[5] + d11 * ad3[8];
                ad3[8] = -d11 * ad3[5] + d7 * ad3[8];
                ad3[5] = ad7[5];
            }
        ad8[0] = ad[0];
        ad8[1] = ad[4];
        ad8[2] = ad[8];
        ad10[0] = ad[1];
        ad10[1] = ad[5];
        if(ad10[0] * ad10[0] >= 1.1102230240000001E-016D || ad10[1] * ad10[1] >= 1.1102230240000001E-016D)
            compute_qr(ad8, ad10, ad3, ad4);
        ad11[0] = ad8[0];
        ad11[1] = ad8[1];
        ad11[2] = ad8[2];
        if(almostEqual(Math.abs(ad11[0]), 1.0D) && almostEqual(Math.abs(ad11[1]), 1.0D) && almostEqual(Math.abs(ad11[2]), 1.0D))
        {
            for(int j = 0; j < 3; j++)
                if(ad11[j] < 0.0D)
                    l++;

            if(l == 0 || l == 2)
            {
                ad1[0] = ad1[1] = ad1[2] = 1.0D;
                for(int k = 0; k < 9; k++)
                    ad2[k] = ad9[k];

                return;
            }
        }
        transpose_mat(ad3, ad5);
        transpose_mat(ad4, ad6);
        svdReorder(ad, ad5, ad6, ad11, ad2, ad1);
    }

    static void svdReorder(double ad[], double ad1[], double ad2[], double ad3[], double ad4[], double ad5[])
    {
        int ai[] = new int[3];
        int ai1[] = new int[3];
        double ad6[] = new double[3];
        double ad7[] = new double[9];
        if(ad3[0] < 0.0D)
        {
            ad3[0] = -ad3[0];
            ad2[0] = -ad2[0];
            ad2[1] = -ad2[1];
            ad2[2] = -ad2[2];
        }
        if(ad3[1] < 0.0D)
        {
            ad3[1] = -ad3[1];
            ad2[3] = -ad2[3];
            ad2[4] = -ad2[4];
            ad2[5] = -ad2[5];
        }
        if(ad3[2] < 0.0D)
        {
            ad3[2] = -ad3[2];
            ad2[6] = -ad2[6];
            ad2[7] = -ad2[7];
            ad2[8] = -ad2[8];
        }
        mat_mul(ad1, ad2, ad7);
        if(almostEqual(Math.abs(ad3[0]), Math.abs(ad3[1])) && almostEqual(Math.abs(ad3[1]), Math.abs(ad3[2])))
        {
            for(int j = 0; j < 9; j++)
                ad4[j] = ad7[j];

            for(int k = 0; k < 3; k++)
                ad5[k] = ad3[k];

        } else
        {
            if(ad3[0] > ad3[1])
            {
                if(ad3[0] > ad3[2])
                {
                    if(ad3[2] > ad3[1])
                    {
                        ai[0] = 0;
                        ai[1] = 2;
                        ai[2] = 1;
                    } else
                    {
                        ai[0] = 0;
                        ai[1] = 1;
                        ai[2] = 2;
                    }
                } else
                {
                    ai[0] = 2;
                    ai[1] = 0;
                    ai[2] = 1;
                }
            } else
            if(ad3[1] > ad3[2])
            {
                if(ad3[2] > ad3[0])
                {
                    ai[0] = 1;
                    ai[1] = 2;
                    ai[2] = 0;
                } else
                {
                    ai[0] = 1;
                    ai[1] = 0;
                    ai[2] = 2;
                }
            } else
            {
                ai[0] = 2;
                ai[1] = 1;
                ai[2] = 0;
            }
            ad6[0] = ad[0] * ad[0] + ad[1] * ad[1] + ad[2] * ad[2];
            ad6[1] = ad[3] * ad[3] + ad[4] * ad[4] + ad[5] * ad[5];
            ad6[2] = ad[6] * ad[6] + ad[7] * ad[7] + ad[8] * ad[8];
            byte byte0;
            byte byte1;
            byte byte2;
            if(ad6[0] > ad6[1])
            {
                if(ad6[0] > ad6[2])
                {
                    if(ad6[2] > ad6[1])
                    {
                        byte0 = 0;
                        byte2 = 1;
                        byte1 = 2;
                    } else
                    {
                        byte0 = 0;
                        byte1 = 1;
                        byte2 = 2;
                    }
                } else
                {
                    byte2 = 0;
                    byte0 = 1;
                    byte1 = 2;
                }
            } else
            if(ad6[1] > ad6[2])
            {
                if(ad6[2] > ad6[0])
                {
                    byte1 = 0;
                    byte2 = 1;
                    byte0 = 2;
                } else
                {
                    byte1 = 0;
                    byte0 = 1;
                    byte2 = 2;
                }
            } else
            {
                byte2 = 0;
                byte1 = 1;
                byte0 = 2;
            }
            int i = ai[byte0];
            ad5[0] = ad3[i];
            i = ai[byte1];
            ad5[1] = ad3[i];
            i = ai[byte2];
            ad5[2] = ad3[i];
            i = ai[byte0];
            ad4[0] = ad7[i];
            i = ai[byte0] + 3;
            ad4[3] = ad7[i];
            i = ai[byte0] + 6;
            ad4[6] = ad7[i];
            i = ai[byte1];
            ad4[1] = ad7[i];
            i = ai[byte1] + 3;
            ad4[4] = ad7[i];
            i = ai[byte1] + 6;
            ad4[7] = ad7[i];
            i = ai[byte2];
            ad4[2] = ad7[i];
            i = ai[byte2] + 3;
            ad4[5] = ad7[i];
            i = ai[byte2] + 6;
            ad4[8] = ad7[i];
        }
    }

    static int compute_qr(double ad[], double ad1[], double ad2[], double ad3[])
    {
        double ad4[] = new double[2];
        double ad5[] = new double[2];
        double ad6[] = new double[2];
        double ad7[] = new double[2];
        double ad8[] = new double[9];
        double d10 = 1.0D;
        double d11 = -1D;
        boolean flag = false;
        int j = 1;
        if(Math.abs(ad1[1]) < 4.8900000000000002E-015D || Math.abs(ad1[0]) < 4.8900000000000002E-015D)
            flag = true;
        for(int i = 0; i < 10 && !flag; i++)
        {
            double d = compute_shift(ad[1], ad1[1], ad[2]);
            double d8 = (Math.abs(ad[0]) - d) * (d_sign(d10, ad[0]) + d / ad[0]);
            double d9 = ad1[0];
            double d1 = compute_rot(d8, d9, ad7, ad5, 0, j);
            d8 = ad5[0] * ad[0] + ad7[0] * ad1[0];
            ad1[0] = ad5[0] * ad1[0] - ad7[0] * ad[0];
            d9 = ad7[0] * ad[1];
            ad[1] = ad5[0] * ad[1];
            d1 = compute_rot(d8, d9, ad6, ad4, 0, j);
            j = 0;
            ad[0] = d1;
            d8 = ad4[0] * ad1[0] + ad6[0] * ad[1];
            ad[1] = ad4[0] * ad[1] - ad6[0] * ad1[0];
            d9 = ad6[0] * ad1[1];
            ad1[1] = ad4[0] * ad1[1];
            d1 = compute_rot(d8, d9, ad7, ad5, 1, j);
            ad1[0] = d1;
            d8 = ad5[1] * ad[1] + ad7[1] * ad1[1];
            ad1[1] = ad5[1] * ad1[1] - ad7[1] * ad[1];
            d9 = ad7[1] * ad[2];
            ad[2] = ad5[1] * ad[2];
            d1 = compute_rot(d8, d9, ad6, ad4, 1, j);
            ad[1] = d1;
            d8 = ad4[1] * ad1[1] + ad6[1] * ad[2];
            ad[2] = ad4[1] * ad[2] - ad6[1] * ad1[1];
            ad1[1] = d8;
            double d2 = ad2[0];
            ad2[0] = ad4[0] * d2 + ad6[0] * ad2[3];
            ad2[3] = -ad6[0] * d2 + ad4[0] * ad2[3];
            d2 = ad2[1];
            ad2[1] = ad4[0] * d2 + ad6[0] * ad2[4];
            ad2[4] = -ad6[0] * d2 + ad4[0] * ad2[4];
            d2 = ad2[2];
            ad2[2] = ad4[0] * d2 + ad6[0] * ad2[5];
            ad2[5] = -ad6[0] * d2 + ad4[0] * ad2[5];
            d2 = ad2[3];
            ad2[3] = ad4[1] * d2 + ad6[1] * ad2[6];
            ad2[6] = -ad6[1] * d2 + ad4[1] * ad2[6];
            d2 = ad2[4];
            ad2[4] = ad4[1] * d2 + ad6[1] * ad2[7];
            ad2[7] = -ad6[1] * d2 + ad4[1] * ad2[7];
            d2 = ad2[5];
            ad2[5] = ad4[1] * d2 + ad6[1] * ad2[8];
            ad2[8] = -ad6[1] * d2 + ad4[1] * ad2[8];
            double d5 = ad3[0];
            ad3[0] = ad5[0] * d5 + ad7[0] * ad3[1];
            ad3[1] = -ad7[0] * d5 + ad5[0] * ad3[1];
            d5 = ad3[3];
            ad3[3] = ad5[0] * d5 + ad7[0] * ad3[4];
            ad3[4] = -ad7[0] * d5 + ad5[0] * ad3[4];
            d5 = ad3[6];
            ad3[6] = ad5[0] * d5 + ad7[0] * ad3[7];
            ad3[7] = -ad7[0] * d5 + ad5[0] * ad3[7];
            d5 = ad3[1];
            ad3[1] = ad5[1] * d5 + ad7[1] * ad3[2];
            ad3[2] = -ad7[1] * d5 + ad5[1] * ad3[2];
            d5 = ad3[4];
            ad3[4] = ad5[1] * d5 + ad7[1] * ad3[5];
            ad3[5] = -ad7[1] * d5 + ad5[1] * ad3[5];
            d5 = ad3[7];
            ad3[7] = ad5[1] * d5 + ad7[1] * ad3[8];
            ad3[8] = -ad7[1] * d5 + ad5[1] * ad3[8];
            ad8[0] = ad[0];
            ad8[1] = ad1[0];
            ad8[2] = 0.0D;
            ad8[3] = 0.0D;
            ad8[4] = ad[1];
            ad8[5] = ad1[1];
            ad8[6] = 0.0D;
            ad8[7] = 0.0D;
            ad8[8] = ad[2];
            if(Math.abs(ad1[1]) < 4.8900000000000002E-015D || Math.abs(ad1[0]) < 4.8900000000000002E-015D)
                flag = true;
        }

        if(Math.abs(ad1[1]) < 4.8900000000000002E-015D)
        {
            compute_2X2(ad[0], ad1[0], ad[1], ad, ad6, ad4, ad7, ad5, 0);
            double d3 = ad2[0];
            ad2[0] = ad4[0] * d3 + ad6[0] * ad2[3];
            ad2[3] = -ad6[0] * d3 + ad4[0] * ad2[3];
            d3 = ad2[1];
            ad2[1] = ad4[0] * d3 + ad6[0] * ad2[4];
            ad2[4] = -ad6[0] * d3 + ad4[0] * ad2[4];
            d3 = ad2[2];
            ad2[2] = ad4[0] * d3 + ad6[0] * ad2[5];
            ad2[5] = -ad6[0] * d3 + ad4[0] * ad2[5];
            double d6 = ad3[0];
            ad3[0] = ad5[0] * d6 + ad7[0] * ad3[1];
            ad3[1] = -ad7[0] * d6 + ad5[0] * ad3[1];
            d6 = ad3[3];
            ad3[3] = ad5[0] * d6 + ad7[0] * ad3[4];
            ad3[4] = -ad7[0] * d6 + ad5[0] * ad3[4];
            d6 = ad3[6];
            ad3[6] = ad5[0] * d6 + ad7[0] * ad3[7];
            ad3[7] = -ad7[0] * d6 + ad5[0] * ad3[7];
        } else
        {
            compute_2X2(ad[1], ad1[1], ad[2], ad, ad6, ad4, ad7, ad5, 1);
            double d4 = ad2[3];
            ad2[3] = ad4[0] * d4 + ad6[0] * ad2[6];
            ad2[6] = -ad6[0] * d4 + ad4[0] * ad2[6];
            d4 = ad2[4];
            ad2[4] = ad4[0] * d4 + ad6[0] * ad2[7];
            ad2[7] = -ad6[0] * d4 + ad4[0] * ad2[7];
            d4 = ad2[5];
            ad2[5] = ad4[0] * d4 + ad6[0] * ad2[8];
            ad2[8] = -ad6[0] * d4 + ad4[0] * ad2[8];
            double d7 = ad3[1];
            ad3[1] = ad5[0] * d7 + ad7[0] * ad3[2];
            ad3[2] = -ad7[0] * d7 + ad5[0] * ad3[2];
            d7 = ad3[4];
            ad3[4] = ad5[0] * d7 + ad7[0] * ad3[5];
            ad3[5] = -ad7[0] * d7 + ad5[0] * ad3[5];
            d7 = ad3[7];
            ad3[7] = ad5[0] * d7 + ad7[0] * ad3[8];
            ad3[8] = -ad7[0] * d7 + ad5[0] * ad3[8];
        }
        return 0;
    }

    static double max(double d, double d1)
    {
        if(d > d1)
            return d;
        else
            return d1;
    }

    static double min(double d, double d1)
    {
        if(d < d1)
            return d;
        else
            return d1;
    }

    static double d_sign(double d, double d1)
    {
        double d2 = d < 0.0D ? -d : d;
        return d1 < 0.0D ? -d2 : d2;
    }

    static double compute_shift(double d, double d1, double d2)
    {
        double d11 = Math.abs(d);
        double d12 = Math.abs(d1);
        double d13 = Math.abs(d2);
        double d7 = min(d11, d13);
        double d8 = max(d11, d13);
        double d20;
        if(d7 == 0.0D)
        {
            d20 = 0.0D;
            double d3;
            if(d8 != 0.0D)
                d3 = min(d8, d12) / max(d8, d12);
        } else
        if(d12 < d8)
        {
            double d14 = d7 / d8 + 1.0D;
            double d16 = (d8 - d7) / d8;
            double d4 = d12 / d8;
            double d18 = d4 * d4;
            double d9 = 2D / (Math.sqrt(d14 * d14 + d18) + Math.sqrt(d16 * d16 + d18));
            d20 = d7 * d9;
        } else
        {
            double d19 = d8 / d12;
            if(d19 == 0.0D)
            {
                d20 = (d7 * d8) / d12;
            } else
            {
                double d15 = d7 / d8 + 1.0D;
                double d17 = (d8 - d7) / d8;
                double d5 = d15 * d19;
                double d6 = d17 * d19;
                double d10 = 1.0D / (Math.sqrt(d5 * d5 + 1.0D) + Math.sqrt(d6 * d6 + 1.0D));
                d20 = d7 * d10 * d19;
                d20 += d20;
            }
        }
        return d20;
    }

    static int compute_2X2(double d, double d1, double d2, double ad[], double ad1[], 
            double ad2[], double ad3[], double ad4[], int i)
    {
        double d3 = 2D;
        double d4 = 1.0D;
        double d37 = ad[0];
        double d36 = ad[1];
        double d32 = 0.0D;
        double d33 = 0.0D;
        double d34 = 0.0D;
        double d35 = 0.0D;
        double d21 = 0.0D;
        double d25 = d;
        double d22 = Math.abs(d25);
        double d27 = d2;
        double d24 = Math.abs(d2);
        byte byte0 = 1;
        boolean flag;
        if(d24 > d22)
            flag = true;
        else
            flag = false;
        if(flag)
        {
            byte0 = 3;
            double d6 = d25;
            d25 = d27;
            d27 = d6;
            d6 = d22;
            d22 = d24;
            d24 = d6;
        }
        double d26 = d1;
        double d23 = Math.abs(d26);
        if(d23 == 0.0D)
        {
            ad[1] = d24;
            ad[0] = d22;
            d32 = 1.0D;
            d33 = 1.0D;
            d34 = 0.0D;
            d35 = 0.0D;
        } else
        {
            boolean flag1 = true;
            if(d23 > d22)
            {
                byte0 = 2;
                if(d22 / d23 < 1.1102230240000001E-016D)
                {
                    flag1 = false;
                    d37 = d23;
                    if(d24 > 1.0D)
                        d36 = d22 / (d23 / d24);
                    else
                        d36 = (d22 / d23) * d24;
                    d32 = 1.0D;
                    d34 = d27 / d26;
                    d35 = 1.0D;
                    d33 = d25 / d26;
                }
            }
            if(flag1)
            {
                double d9 = d22 - d24;
                double d11;
                if(d9 == d22)
                    d11 = 1.0D;
                else
                    d11 = d9 / d22;
                double d13 = d26 / d25;
                double d19 = 2D - d11;
                double d28 = d13 * d13;
                double d30 = d19 * d19;
                double d17 = Math.sqrt(d30 + d28);
                double d15;
                if(d11 == 0.0D)
                    d15 = Math.abs(d13);
                else
                    d15 = Math.sqrt(d11 * d11 + d28);
                double d7 = (d17 + d15) * 0.5D;
                if(d23 > d22)
                {
                    byte0 = 2;
                    if(d22 / d23 < 1.1102230240000001E-016D)
                    {
                        flag1 = false;
                        d37 = d23;
                        if(d24 > 1.0D)
                            d36 = d22 / (d23 / d24);
                        else
                            d36 = (d22 / d23) * d24;
                        d32 = 1.0D;
                        d34 = d27 / d26;
                        d35 = 1.0D;
                        d33 = d25 / d26;
                    }
                }
                if(flag1)
                {
                    double d10 = d22 - d24;
                    double d12;
                    if(d10 == d22)
                        d12 = 1.0D;
                    else
                        d12 = d10 / d22;
                    double d14 = d26 / d25;
                    double d20 = 2D - d12;
                    double d29 = d14 * d14;
                    double d31 = d20 * d20;
                    double d18 = Math.sqrt(d31 + d29);
                    double d16;
                    if(d12 == 0.0D)
                        d16 = Math.abs(d14);
                    else
                        d16 = Math.sqrt(d12 * d12 + d29);
                    double d8 = (d18 + d16) * 0.5D;
                    d36 = d24 / d8;
                    d37 = d22 * d8;
                    if(d29 == 0.0D)
                    {
                        if(d12 == 0.0D)
                            d20 = d_sign(d3, d25) * d_sign(d4, d26);
                        else
                            d20 = d26 / d_sign(d10, d25) + d14 / d20;
                    } else
                    {
                        d20 = (d14 / (d18 + d20) + d14 / (d16 + d12)) * (d8 + 1.0D);
                    }
                    d12 = Math.sqrt(d20 * d20 + 4D);
                    d33 = 2D / d12;
                    d35 = d20 / d12;
                    d32 = (d33 + d35 * d14) / d8;
                    d34 = ((d27 / d25) * d35) / d8;
                }
            }
            if(flag)
            {
                ad2[0] = d35;
                ad1[0] = d33;
                ad4[0] = d34;
                ad3[0] = d32;
            } else
            {
                ad2[0] = d32;
                ad1[0] = d34;
                ad4[0] = d33;
                ad3[0] = d35;
            }
            if(byte0 == 1)
                d21 = d_sign(d4, ad4[0]) * d_sign(d4, ad2[0]) * d_sign(d4, d);
            if(byte0 == 2)
                d21 = d_sign(d4, ad3[0]) * d_sign(d4, ad2[0]) * d_sign(d4, d1);
            if(byte0 == 3)
                d21 = d_sign(d4, ad3[0]) * d_sign(d4, ad1[0]) * d_sign(d4, d2);
            ad[i] = d_sign(d37, d21);
            double d5 = d21 * d_sign(d4, d) * d_sign(d4, d2);
            ad[i + 1] = d_sign(d36, d5);
        }
        return 0;
    }

    static double compute_rot(double d, double d1, double ad[], double ad1[], int i, int j)
    {
        double d2;
        double d3;
        double d7;
        if(d1 == 0.0D)
        {
            d2 = 1.0D;
            d3 = 0.0D;
            d7 = d;
        } else
        if(d == 0.0D)
        {
            d2 = 0.0D;
            d3 = 1.0D;
            d7 = d1;
        } else
        {
            double d5 = d;
            double d6 = d1;
            double d4 = max(Math.abs(d5), Math.abs(d6));
            if(d4 >= 4.9947976805055876E+145D)
            {
                int k1 = 0;
                for(; d4 >= 4.9947976805055876E+145D; d4 = max(Math.abs(d5), Math.abs(d6)))
                {
                    k1++;
                    d5 *= 2.0020830951831009E-146D;
                    d6 *= 2.0020830951831009E-146D;
                }

                d7 = Math.sqrt(d5 * d5 + d6 * d6);
                d2 = d5 / d7;
                d3 = d6 / d7;
                int k = k1;
                for(int i1 = 1; i1 <= k1; i1++)
                    d7 *= 4.9947976805055876E+145D;

            } else
            if(d4 <= 2.0020830951831009E-146D)
            {
                int l1 = 0;
                for(; d4 <= 2.0020830951831009E-146D; d4 = max(Math.abs(d5), Math.abs(d6)))
                {
                    l1++;
                    d5 *= 4.9947976805055876E+145D;
                    d6 *= 4.9947976805055876E+145D;
                }

                d7 = Math.sqrt(d5 * d5 + d6 * d6);
                d2 = d5 / d7;
                d3 = d6 / d7;
                int l = l1;
                for(int j1 = 1; j1 <= l1; j1++)
                    d7 *= 2.0020830951831009E-146D;

            } else
            {
                d7 = Math.sqrt(d5 * d5 + d6 * d6);
                d2 = d5 / d7;
                d3 = d6 / d7;
            }
            if(Math.abs(d) > Math.abs(d1) && d2 < 0.0D)
            {
                d2 = -d2;
                d3 = -d3;
                d7 = -d7;
            }
        }
        ad[i] = d3;
        ad1[i] = d2;
        return d7;
    }

    static void print_mat(double ad[])
    {
        for(int i = 0; i < 3; i++)
            System.out.println(ad[i * 3 + 0] + " " + ad[i * 3 + 1] + " " + ad[i * 3 + 2] + "\n");

    }

    static void print_det(double ad[])
    {
        double d = (ad[0] * ad[4] * ad[8] + ad[1] * ad[5] * ad[6] + ad[2] * ad[3] * ad[7]) - ad[2] * ad[4] * ad[6] - ad[0] * ad[5] * ad[7] - ad[1] * ad[3] * ad[8];
        System.out.println("det= " + d);
    }

    static void mat_mul(double ad[], double ad1[], double ad2[])
    {
        double ad3[] = new double[9];
        ad3[0] = ad[0] * ad1[0] + ad[1] * ad1[3] + ad[2] * ad1[6];
        ad3[1] = ad[0] * ad1[1] + ad[1] * ad1[4] + ad[2] * ad1[7];
        ad3[2] = ad[0] * ad1[2] + ad[1] * ad1[5] + ad[2] * ad1[8];
        ad3[3] = ad[3] * ad1[0] + ad[4] * ad1[3] + ad[5] * ad1[6];
        ad3[4] = ad[3] * ad1[1] + ad[4] * ad1[4] + ad[5] * ad1[7];
        ad3[5] = ad[3] * ad1[2] + ad[4] * ad1[5] + ad[5] * ad1[8];
        ad3[6] = ad[6] * ad1[0] + ad[7] * ad1[3] + ad[8] * ad1[6];
        ad3[7] = ad[6] * ad1[1] + ad[7] * ad1[4] + ad[8] * ad1[7];
        ad3[8] = ad[6] * ad1[2] + ad[7] * ad1[5] + ad[8] * ad1[8];
        for(int i = 0; i < 9; i++)
            ad2[i] = ad3[i];

    }

    static void transpose_mat(double ad[], double ad1[])
    {
        ad1[0] = ad[0];
        ad1[1] = ad[3];
        ad1[2] = ad[6];
        ad1[3] = ad[1];
        ad1[4] = ad[4];
        ad1[5] = ad[7];
        ad1[6] = ad[2];
        ad1[7] = ad[5];
        ad1[8] = ad[8];
    }

    static double max3(double ad[])
    {
        if(ad[0] > ad[1])
            if(ad[0] > ad[2])
                return ad[0];
            else
                return ad[2];
        if(ad[1] > ad[2])
            return ad[1];
        else
            return ad[2];
    }

    private static final boolean almostEqual(double d, double d1)
    {
        if(d == d1)
            return true;
        double d2 = Math.abs(d - d1);
        double d3 = Math.abs(d);
        double d4 = Math.abs(d1);
        double d5 = d3 < d4 ? d4 : d3;
        if(d2 < 9.9999999999999995E-007D)
            return true;
        return d2 / d5 < 0.0001D;
    }

    public Object clone()
    {
        Matrix3d matrix3d = null;
        try
        {
            matrix3d = (Matrix3d)super.clone();
        }
        catch(CloneNotSupportedException clonenotsupportedexception)
        {
            throw new InternalError();
        }
        return matrix3d;
    }

    static final long serialVersionUID = 0x5ee3cf78d011e116L;
    public double m00;
    public double m01;
    public double m02;
    public double m10;
    public double m11;
    public double m12;
    public double m20;
    public double m21;
    public double m22;
    private static final double EPS = 1.1102230240000001E-016D;
    private static final double ERR_EPS = 1E-008D;
    private static double xin;
    private static double yin;
    private static double zin;
    private static double xout;
    private static double yout;
    private static double zout;
}
