public static bool DecomposeIntoRotationAndScale(Matrix source, out Matrix rotation, out Vector scale)
        {
            source.OffsetX = 0.0;
            source.OffsetY = 0.0;
            Matrix U;
            Vector S;
            Matrix VTranspose;
            bool   flag    = Matrix3DOperations.SVD(source, out U, out S, out VTranspose);
            Matrix matrix1 = Matrix3DOperations.Transpose(VTranspose);
            Matrix matrix2 = new Matrix()
            {
                M11 = S.X,
                M22 = S.Y
            };

            rotation = U * matrix1;
            Matrix matrix3 = rotation;

            matrix3.Invert();
            Matrix matrix4   = source * matrix3;
            Matrix matrix5   = matrix3 * source;
            double tolerance = 1E-13;

            scale = !Matrix3DOperations.IsDiagonal(matrix4, tolerance) ? new Vector(matrix5.M11, matrix5.M22) : new Vector(matrix4.M11, matrix4.M22);
            return(flag);
        }
        public static bool DecomposeIntoRotationAndScale(Matrix3D source, out Matrix3D rotation, out Vector3D scale)
        {
            source.OffsetX = 0.0;
            source.OffsetY = 0.0;
            source.OffsetZ = 0.0;
            Matrix3D U;
            Vector3D S;
            Matrix3D VTranspose;
            bool     flag      = Matrix3DOperations.SVD(source, out U, out S, out VTranspose);
            Matrix3D matrix3D1 = Matrix3DOperations.Transpose(VTranspose);
            Matrix3D matrix3D2 = new Matrix3D()
            {
                M11 = S.X,
                M22 = S.Y,
                M33 = S.Z,
                M44 = 1.0
            };

            rotation = U * matrix3D1;
            Matrix3D matrix3D3 = rotation;

            matrix3D3.Invert();
            Matrix3D matrix    = source * matrix3D3;
            Matrix3D matrix3D4 = matrix3D3 * source;
            double   tolerance = 1E-13;

            scale = !Matrix3DOperations.IsDiagonal(matrix, tolerance) ? new Vector3D(matrix3D4.M11, matrix3D4.M22, matrix3D4.M33) : new Vector3D(matrix.M11, matrix.M22, matrix.M33);
            return(flag);
        }
        public static bool SVD(Matrix original, out Matrix U, out Vector S, out Matrix VTranspose)
        {
            double[,] U1;
            double[] S1;
            double[,] V;
            bool flag = Matrix3DOperations.Svd(Matrix3DOperations.CreateMatrix2x2(original), out U1, out S1, out V);

            U          = Matrix3DOperations.CreateMatrix(U1);
            VTranspose = Matrix3DOperations.CreateMatrix(V);
            S          = Matrix3DOperations.CreateVector(S1);
            return(flag);
        }
        private void ConvertGenericTransform(Transform3D transform)
        {
            Point3D point3D1 = new Point3D(0.0, 0.0, 0.0);

            this.Initialize();
            ScaleTransform3D scaleTransform3D = transform as ScaleTransform3D;

            if (scaleTransform3D != null)
            {
                this.scale  = new Vector3D(scaleTransform3D.ScaleX, scaleTransform3D.ScaleY, scaleTransform3D.ScaleZ);
                this.center = new Point3D(scaleTransform3D.CenterX, scaleTransform3D.CenterY, scaleTransform3D.CenterZ);
            }
            else
            {
                Point3D point3D2 = point3D1 * transform.Value;
                this.translation = new Vector3D(point3D2.X, point3D2.Y, point3D2.Z);
                Matrix3D rotation;
                Vector3D scale;
                Matrix3DOperations.DecomposeIntoRotationAndScale(transform.Value, out rotation, out scale);
                this.scale          = scale;
                this.RotationAngles = Helper3D.EulerAnglesFromQuaternion(this.MatrixToQuaternion(rotation));
            }
            this.InitializeTransformGroup();
        }
        internal static bool Svd(double[,] M, out double[,] U, out double[] S, out double[,] V)
        {
            double val1   = 0.0;
            double num1   = 0.0;
            double num2   = 0.0;
            int    index1 = 0;
            int    index2 = 0;
            int    length = M.Length == 4 ? 2 : 3;

            double[] numArray = new double[length];
            U = new double[length, length];
            V = new double[length, length];
            S = new double[length];
            for (int index3 = 0; index3 < length; ++index3)
            {
                for (int index4 = 0; index4 < length; ++index4)
                {
                    U[index3, index4] = M[index3, index4];
                }
                S[index3] = 0.0;
            }
            for (int index3 = 0; index3 < length; ++index3)
            {
                index1           = index3 + 1;
                numArray[index3] = num2 * num1;
                double num3;
                double num4 = num3 = 0.0;
                double d1   = num3;
                double num5 = num3;
                for (int index4 = index3; index4 < length; ++index4)
                {
                    num4 += Math.Abs(U[index4, index3]);
                }
                if (num4 != 0.0)
                {
                    for (int index4 = index3; index4 < length; ++index4)
                    {
                        U[index4, index3] /= num4;
                        d1 += U[index4, index3] * U[index4, index3];
                    }
                    double num6 = U[index3, index3];
                    num5 = num6 >= 0.0 ? -Math.Sqrt(d1) : Math.Sqrt(d1);
                    double num7 = num6 * num5 - d1;
                    U[index3, index3] = num6 - num5;
                    for (int index4 = index1; index4 < length; ++index4)
                    {
                        double num8 = 0.0;
                        for (int index5 = index3; index5 < length; ++index5)
                        {
                            num8 += U[index5, index3] * U[index5, index4];
                        }
                        double num9 = num8 / num7;
                        for (int index5 = index3; index5 < length; ++index5)
                        {
                            U[index5, index4] += num9 * U[index5, index3];
                        }
                    }
                    for (int index4 = index3; index4 < length; ++index4)
                    {
                        U[index4, index3] *= num4;
                    }
                }
                S[index3] = num4 * num5;
                double num10;
                num2 = num10 = 0.0;
                double d2 = num10;
                num1 = num10;
                for (int index4 = index1; index4 < length; ++index4)
                {
                    num2 += Math.Abs(U[index3, index4]);
                }
                if (num2 != 0.0)
                {
                    for (int index4 = index1; index4 < length; ++index4)
                    {
                        U[index3, index4] /= num2;
                        d2 += U[index3, index4] * U[index3, index4];
                    }
                    double num6 = U[index3, index1];
                    num1 = num6 >= 0.0 ? -Math.Sqrt(d2) : Math.Sqrt(d2);
                    double num7 = num6 * num1 - d2;
                    U[index3, index1] = num6 - num1;
                    for (int index4 = index1; index4 < length; ++index4)
                    {
                        numArray[index4] = U[index3, index4] / num7;
                    }
                    for (int index4 = index1; index4 < length; ++index4)
                    {
                        double num8 = 0.0;
                        for (int index5 = index1; index5 < length; ++index5)
                        {
                            num8 += U[index4, index5] * U[index3, index5];
                        }
                        for (int index5 = index1; index5 < length; ++index5)
                        {
                            U[index4, index5] += num8 * numArray[index5];
                        }
                    }
                    for (int index4 = index1; index4 < length; ++index4)
                    {
                        U[index3, index4] *= num2;
                    }
                }
                val1 = Math.Max(val1, Math.Abs(S[index3]) + Math.Abs(numArray[index3]));
            }
            int index6 = length;

            while (--index6 >= 0)
            {
                if (num1 != 0.0)
                {
                    for (int index3 = index1; index3 < length; ++index3)
                    {
                        V[index3, index6] = U[index6, index3] / U[index6, index1] / num1;
                    }
                    for (int index3 = index1; index3 < length; ++index3)
                    {
                        double num3 = 0.0;
                        for (int index4 = index1; index4 < length; ++index4)
                        {
                            num3 += U[index6, index4] * V[index4, index3];
                        }
                        for (int index4 = index1; index4 < length; ++index4)
                        {
                            V[index4, index3] += num3 * V[index4, index6];
                        }
                    }
                }
                for (int index3 = index1; index3 < length; ++index3)
                {
                    V[index6, index3] = V[index3, index6] = 0.0;
                }
                V[index6, index6] = 1.0;
                num1   = numArray[index6];
                index1 = index6;
            }
            int index7 = length;

            while (--index7 >= 0)
            {
                int    num3 = index7 + 1;
                double num4 = S[index7];
                for (int index3 = num3; index3 < length; ++index3)
                {
                    U[index7, index3] = 0.0;
                }
                if (num4 != 0.0)
                {
                    double num5 = 1.0 / num4;
                    for (int index3 = num3; index3 < length; ++index3)
                    {
                        double num6 = 0.0;
                        for (int index4 = num3; index4 < length; ++index4)
                        {
                            num6 += U[index4, index7] * U[index4, index3];
                        }
                        double num7 = num6 / U[index7, index7] * num5;
                        for (int index4 = index7; index4 < length; ++index4)
                        {
                            U[index4, index3] += num7 * U[index4, index7];
                        }
                    }
                    for (int index3 = index7; index3 < length; ++index3)
                    {
                        U[index3, index7] *= num5;
                    }
                }
                else
                {
                    for (int index3 = index7; index3 < length; ++index3)
                    {
                        U[index3, index7] = 0.0;
                    }
                }
                ++U[index7, index7];
            }
            int index8 = length;

            while (--index8 >= 0)
            {
                for (int index3 = 1; index3 <= 30; ++index3)
                {
                    bool flag = true;
                    int  index4;
                    for (index4 = index8; index4 >= 0; --index4)
                    {
                        index2 = index4 - 1;
                        if (Math.Abs(numArray[index4]) + val1 == val1)
                        {
                            flag = false;
                            break;
                        }
                        if (index2 < 0)
                        {
                            return(false);
                        }
                        if (Math.Abs(S[index2]) + val1 == val1)
                        {
                            break;
                        }
                    }
                    if (flag)
                    {
                        double num3 = 0.0;
                        double num4 = 1.0;
                        for (int index5 = index4; index5 <= index8; ++index5)
                        {
                            double a = num4 * numArray[index5];
                            numArray[index5] *= num3;
                            if (Math.Abs(a) + val1 != val1)
                            {
                                double b    = S[index5];
                                double num5 = Matrix3DOperations.Hypotenuse(a, b);
                                S[index5] = num5;
                                double num6 = 1.0 / num5;
                                num3 = b * num6;
                                num4 = -a * num6;
                                for (int index9 = 0; index9 < length; ++index9)
                                {
                                    double num7 = U[index9, index2];
                                    double num8 = U[index9, index5];
                                    U[index9, index2] = num7 * num3 + num8 * num4;
                                    U[index9, index5] = num8 * num3 - num7 * num4;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    double num9 = S[index8];
                    if (index4 == index8)
                    {
                        if (num9 < 0.0)
                        {
                            S[index8] = -num9;
                            for (int index5 = 0; index5 < length; ++index5)
                            {
                                V[index5, index8] = -V[index5, index8];
                            }
                            break;
                        }
                        break;
                    }
                    if (index3 == 30)
                    {
                        return(false);
                    }
                    double num10 = S[index4];
                    index2 = index8 - 1;
                    double num11 = S[index2];
                    double num12 = numArray[index2];
                    double num13 = numArray[index8];
                    double a1    = ((num11 - num9) * (num11 + num9) + (num12 - num13) * (num12 + num13)) / (2.0 * num13 * num11);
                    double num14 = Matrix3DOperations.Hypotenuse(a1, 1.0);
                    double a2    = ((num10 - num9) * (num10 + num9) + num13 * (num11 / (a1 + (a1 >= 0.0 ? num14 : -num14)) - num13)) / num10;
                    double num15;
                    double num16 = num15 = 1.0;
                    for (int index5 = index4; index5 <= index2; ++index5)
                    {
                        int    index9 = index5 + 1;
                        double num3   = numArray[index9];
                        double num4   = S[index9];
                        double b1     = num15 * num3;
                        double num5   = num16 * num3;
                        double num6   = Matrix3DOperations.Hypotenuse(a2, b1);
                        numArray[index5] = num6;
                        num16            = a2 / num6;
                        num15            = b1 / num6;
                        double a3   = num10 * num16 + num5 * num15;
                        double num7 = num5 * num16 - num10 * num15;
                        double b2   = num4 * num15;
                        double num8 = num4 * num16;
                        for (int index10 = 0; index10 < length; ++index10)
                        {
                            double num17 = V[index10, index5];
                            double num18 = V[index10, index9];
                            V[index10, index5] = num17 * num16 + num18 * num15;
                            V[index10, index9] = num18 * num16 - num17 * num15;
                        }
                        double num19 = Matrix3DOperations.Hypotenuse(a3, b2);
                        S[index5] = num19;
                        if (num19 != 0.0)
                        {
                            double num17 = 1.0 / num19;
                            num16 = a3 * num17;
                            num15 = b2 * num17;
                        }
                        a2    = num16 * num7 + num15 * num8;
                        num10 = num16 * num8 - num15 * num7;
                        for (int index10 = 0; index10 < length; ++index10)
                        {
                            double num17 = U[index10, index5];
                            double num18 = U[index10, index9];
                            U[index10, index5] = num17 * num16 + num18 * num15;
                            U[index10, index9] = num18 * num16 - num17 * num15;
                        }
                    }
                    numArray[index4] = 0.0;
                    numArray[index8] = a2;
                    S[index8]        = num10;
                }
            }
            return(true);
        }