Beispiel #1
0
        public static DenseMatrixQuaternion operator *(DenseMatrixQuaternion left, SparseMatrixQuaternion right)
        {
            //Make sure matrix dimensions are equal
            if (left.columnCount != right.RowCount)
            {
                throw new Exception("The dimension of two matrix must be equal");
            }
            DenseMatrixQuaternion resultMatrix = new DenseMatrixQuaternion(left.RowCount, right.ColumnCount);

            Quaternion[,] result = resultMatrix.datas;

            for (int i = 0; i < left.rowCount; i++)
            {
                foreach (KeyValuePair <Pair, Quaternion> item in right.Datas)
                {
                    Pair       pair  = item.Key;
                    Quaternion value = item.Value;

                    int m = pair.Key;
                    int n = pair.Value;

                    //M: mutiply index N: vector store index
                    result[i, n] += left[i, m] * value;
                }
            }

            return(resultMatrix);
        }
Beispiel #2
0
        DenseMatrixQuaternion ReadLambda(String path)
        {
            FileStream   fs   = new FileStream(path, FileMode.Open);
            StreamReader sr   = new StreamReader(fs);
            String       line = null;

            DenseMatrixQuaternion qt = new DenseMatrixQuaternion(mesh.Vertices.Count, 1);

            char[] splitChar = new char[] { ' ' };
            int    row       = 0;

            while ((line = sr.ReadLine()) != null)
            {
                String[] token = line.Split(splitChar);

                double w = double.Parse(token[0]);
                double x = double.Parse(token[1]);
                double y = double.Parse(token[2]);
                double z = double.Parse(token[3]);

                Quaternion q = new Quaternion(x, y, z, w);

                qt[row, 0] = q;

                row++;
            }

            return(qt);
        }
Beispiel #3
0
        public Quaternion Dot(DenseMatrixQuaternion right)
        {
            DenseMatrixQuaternion x      = this.Transpose() * right;
            Quaternion            result = x[0, 0];

            return(result);
        }
Beispiel #4
0
 void UpdatePosition(ref DenseMatrixQuaternion newVertices)
 {
     for (int i = 0; i < newVertices.RowCount; i++)
     {
         Quaternion v           = newVertices[i, 0];
         Vector3D   newPosition = new Vector3D(v.x, v.y, v.z);
         mesh.Vertices[i].Traits.Position = newPosition;
     }
 }
Beispiel #5
0
        public static DenseMatrixQuaternion Copy(ref DenseMatrixQuaternion B)
        {
            DenseMatrixQuaternion newMatrix = new DenseMatrixQuaternion();

            newMatrix.rowCount    = B.rowCount;
            newMatrix.columnCount = B.columnCount;
            Array.Copy(B.datas, newMatrix.datas, B.datas.Length);
            return(newMatrix);
        }
        public static DenseMatrixQuaternion Identity(int N)
        {
            DenseMatrixQuaternion identity = new DenseMatrixQuaternion(N, N);

            for (int i = 0; i < N; i++)
            {
                identity.datas[i, i] = Quaternion.Identity;
            }

            return identity;
        }
Beispiel #7
0
        public static DenseMatrixQuaternion Identity(int N)
        {
            DenseMatrixQuaternion identity = new DenseMatrixQuaternion(N, N);

            for (int i = 0; i < N; i++)
            {
                identity.datas[i, i] = Quaternion.Identity;
            }

            return(identity);
        }
Beispiel #8
0
        DenseMatrixQuaternion BuildOmega(DenseMatrixQuaternion lamda)
        {
            DenseMatrixQuaternion Omega = new DenseMatrixQuaternion(mesh.Vertices.Count, 1);

            TriMesh.Vertex[] index = new TriMesh.Vertex[3];

            foreach (TriMesh.Face face in mesh.Faces)
            {
                index[0] = face.GetVertex(2);
                index[1] = face.GetVertex(0);
                index[2] = face.GetVertex(1);

                for (int i = 0; i < 3; i++)
                {
                    Quaternion f0 = new Quaternion(index[(i + 0) % 3].Traits.Position, 0);
                    Quaternion f1 = new Quaternion(index[(i + 1) % 3].Traits.Position, 0);
                    Quaternion f2 = new Quaternion(index[(i + 2) % 3].Traits.Position, 0);

                    //Setting Orientation Swap it
                    TriMesh.Vertex aI = index[(i + 1) % 3];
                    TriMesh.Vertex bI = index[(i + 2) % 3];
                    if (aI.Index > bI.Index)
                    {
                        aI = index[(i + 2) % 3];
                        bI = index[(i + 1) % 3];
                    }

                    Quaternion aLamda = lamda[aI.Index, 0];
                    Quaternion bLamda = lamda[bI.Index, 0];
                    Quaternion e      = new Quaternion(bI.Traits.Position, 0) - new Quaternion(aI.Traits.Position, 0);
                    Quaternion conj   = aLamda.Conjugate();
                    Quaternion bconj  = bLamda.Conjugate();
                    Quaternion partA  = conj * e * aLamda;
                    Quaternion eTilde = (1f / 3f) * partA +
                                        (1f / 6f) * aLamda.Conjugate() * e * bLamda +
                                        (1f / 6f) * bLamda.Conjugate() * e * aLamda +
                                        (1f / 3f) * bLamda.Conjugate() * e * bLamda;

                    Vector3D u1 = index[(i + 1) % 3].Traits.Position - index[(i + 0) % 3].Traits.Position;
                    Vector3D u2 = index[(i + 2) % 3].Traits.Position - index[(i + 0) % 3].Traits.Position;

                    double cotAlpha = u1.Dot(u2) / u1.Cross(u2).Length();

                    Quaternion q = cotAlpha * eTilde / 2;

                    Omega[aI.Index, 0] -= q;
                    Omega[bI.Index, 0] += q;
                }
            }

            RemoveMean(ref Omega);
            return(Omega);
        }
Beispiel #9
0
        public double F_Norm()
        {
            DenseMatrixQuaternion tr = this.Transpose() * this;

            double sum = 0;

            for (int i = 0; i < tr.RowCount; i++)
            {
                sum += tr[i, i].Length;
            }

            return(Math.Sqrt(sum));
        }
Beispiel #10
0
        public static DenseMatrixQuaternion operator *(Quaternion left, DenseMatrixQuaternion right)
        {
            DenseMatrixQuaternion result = new DenseMatrixQuaternion(right.rowCount, right.columnCount);

            for (int i = 0; i < right.rowCount; i++)
            {
                for (int j = 0; j < right.columnCount; j++)
                {
                    result.datas[i, j] = right.datas[i, j] * left;
                }
            }

            return(result);
        }
Beispiel #11
0
        public DenseMatrixQuaternion Transpose()
        {
            DenseMatrixQuaternion tr = new DenseMatrixQuaternion(this.columnCount, this.rowCount);

            for (int i = 0; i < rowCount; i++)
            {
                for (int j = 0; j < columnCount; j++)
                {
                    tr.datas[j, i] = datas[i, j];
                }
            }

            return(tr);
        }
Beispiel #12
0
        public DenseMatrixQuaternion Transpose()
        {
            DenseMatrixQuaternion tr = new DenseMatrixQuaternion(this.columnCount, this.rowCount);

            for (int i = 0; i < rowCount; i++)
            {
                for (int j = 0; j < columnCount; j++)
                {
                    tr.datas[j, i] = datas[i, j];
                }
            }

            return tr;
        }
Beispiel #13
0
        public DenseMatrixQuaternion SolveByFactorizedLU(ref DenseMatrixQuaternion b)
        {
            if (b.ColumnCount > 1)
            {
                return(null);
            }

            double[][] rhs = new double[4][];   //Arranage By Column
            for (int i = 0; i < 4; i++)
            {
                rhs[i] = new double[4 * b.RowCount];
            }

            double[][] x = new double[4][];
            for (int i = 0; i < 4; i++)
            {
                x[i] = new double[4 * this.n];
            }

            for (int i = 0; i < b.RowCount; i++)
            {
                Quaternion item = b[i, 0];

                Matrix4D mat = item.ToMatrix();

                rhs[0][4 * i]     = mat[0, 0]; rhs[1][4 * i] = mat[0, 1]; rhs[2][4 * i] = mat[0, 2]; rhs[3][4 * i] = mat[0, 3];
                rhs[0][4 * i + 1] = mat[1, 0]; rhs[1][4 * i + 1] = mat[1, 1]; rhs[2][4 * i + 1] = mat[1, 2]; rhs[3][4 * i + 1] = mat[1, 3];
                rhs[0][4 * i + 2] = mat[2, 0]; rhs[1][4 * i + 2] = mat[2, 1]; rhs[2][4 * i + 2] = mat[2, 2]; rhs[3][4 * i + 2] = mat[2, 3];
                rhs[0][4 * i + 3] = mat[3, 0]; rhs[1][4 * i + 3] = mat[3, 1]; rhs[2][4 * i + 3] = mat[3, 2]; rhs[3][4 * i + 3] = mat[3, 3];
            }

            DenseMatrixQuaternion result = new DenseMatrixQuaternion(n, 1);

            //Solve
            for (int i = 0; i < 4; i++)
            {
                SolveLU(ref rhs[i], ref x[i]);
            }

            for (int i = 0; i < this.n; i++)
            {
                result[i, 0] = new Quaternion(x[0][4 * i + 1], x[0][4 * i + 2], x[0][4 * i + 3], x[0][4 * i]);
            }

            x = null;
            GC.Collect();

            return(result);
        }
Beispiel #14
0
        void RemoveMean(ref DenseMatrixQuaternion x)
        {
            Quaternion mean = Quaternion.Zero;

            for (int i = 0; i < x.RowCount; i++)
            {
                mean += x[i, 0];
            }

            mean /= x.RowCount;

            for (int i = 0; i < x.RowCount; i++)
            {
                x[i, 0] -= mean;
            }
        }
Beispiel #15
0
        public static DenseMatrixQuaternion operator /(DenseMatrixQuaternion left, Quaternion right)
        {
            //Make sure matrix dimensions are equal
            DenseMatrixQuaternion matrix = new DenseMatrixQuaternion(left.RowCount, left.ColumnCount);

            // Quaternion rightInv = right.Invert();

            for (int i = 0; i < left.RowCount; i++)
            {
                for (int j = 0; j < left.columnCount; j++)
                {
                    //  matrix.datas[i, j] = left.datas[i, j] * rightInv;
                }
            }

            return(matrix);
        }
Beispiel #16
0
        void NormalizeSolution(ref DenseMatrixQuaternion newVertices)
        {
            RemoveMean(ref newVertices);

            // Infinite Norm
            double r = 0;

            for (int i = 0; i < newVertices.RowCount; i++)
            {
                r = Math.Max(r, newVertices[i, 0].LengthSquared);
            }
            r = Math.Sqrt(r);

            for (int i = 0; i < newVertices.RowCount; i++)
            {
                newVertices[i, 0] /= r;
            }
        }
Beispiel #17
0
        public static DenseMatrixQuaternion operator +(DenseMatrixQuaternion left, DenseMatrixQuaternion right)
        {
            //Make sure matrix dimensions are equal
            if (left.columnCount != right.columnCount)
            {
                throw new Exception("The dimension of two matrix must be equal");
            }

            DenseMatrixQuaternion matrix = new DenseMatrixQuaternion(left.RowCount, left.ColumnCount);

            for (int i = 0; i < left.RowCount; i++)
            {
                for (int j = 0; j < left.columnCount; j++)
                {
                    matrix.datas[i, j] = left.datas[i, j] + right.datas[i, j];
                }
            }

            return(matrix);
        }
Beispiel #18
0
        public void UpdateDeformation(String imagePath, double scale)
        {
            TGAImage image = new TGAImage(imagePath);

            //double[] rho = IOHuiZhao.Instance.ReadVectorFromMatlab("A.vector");
            double[] rho = SetCurvatureChange(image, 10);

            SparseMatrixQuaternion E     = BuildEigenValueProblem(rho);
            DenseMatrixQuaternion  lamda = LinearSystemDEC.Instance.SolveEigen(ref E);

            SparseMatrixQuaternion Laplace = BuildCotLaplace();
            DenseMatrixQuaternion  omega   = BuildOmega(lamda);

            LinearSystemGenericByLib.Instance.FactorizationLU(ref Laplace);
            DenseMatrixQuaternion newV = LinearSystemGenericByLib.Instance.SolveByFactorizedLU(ref omega);

            NormalizeSolution(ref newV);

            UpdatePosition(ref newV);
        }
Beispiel #19
0
        public DenseMatrixQuaternion SolveEigen(ref SparseMatrixQuaternion A)
        {
            LinearSystemGenericByLib.Instance.FactorizationLU(ref A);

            DenseMatrixQuaternion b = new DenseMatrixQuaternion(A.ColumnCount, 1);

            b.Fill(Quaternion.Identity);

            for (int i = 0; i < 20; i++)
            {
                b.Normalize();
                DenseMatrixQuaternion x = LinearSystemGenericByLib.Instance.SolveByFactorizedLU(ref b);
                b = null;
                b = x;
            }

            GC.Collect();
            b.Normalize();
            LinearSystemGenericByLib.Instance.FreeSolverLU();
            return(b);
        }
Beispiel #20
0
        public static DenseMatrixQuaternion operator *(DenseMatrixQuaternion left, DenseMatrixQuaternion right)
        {
            //Make sure matrix dimensions are equal
            if (left.columnCount != right.rowCount)
            {
                throw new Exception("The dimension of two matrix must be equal");
            }

            DenseMatrixQuaternion result = new DenseMatrixQuaternion(left.rowCount, right.columnCount);

            for (int i = 0; i < left.rowCount; i++)
            {
                for (int j = 0; j < right.columnCount; j++)
                {
                    for (int z = 0; z < left.columnCount; z++)
                    {
                        result.datas[i, j] += left.datas[i, z] * right.datas[z, j];
                    }
                }
            }

            return(result);
        }
Beispiel #21
0
        public static DenseMatrixQuaternion operator +(DenseMatrixQuaternion left, DenseMatrixQuaternion right)
        {
            //Make sure matrix dimensions are equal
            if (left.columnCount != right.columnCount)
            {
                throw new Exception("The dimension of two matrix must be equal");
            }

            DenseMatrixQuaternion matrix = new DenseMatrixQuaternion(left.RowCount, left.ColumnCount);

            for (int i = 0; i < left.RowCount; i++)
            {
                for (int j = 0; j < left.columnCount; j++)
                {
                    matrix.datas[i, j] = left.datas[i, j] + right.datas[i, j];
                }
            }

            return matrix;
        }
Beispiel #22
0
        public static DenseMatrixQuaternion operator *(DenseMatrixQuaternion left, DenseMatrixQuaternion right)
        {
            //Make sure matrix dimensions are equal
            if (left.columnCount != right.rowCount)
            {
                throw new Exception("The dimension of two matrix must be equal");
            }

            DenseMatrixQuaternion result = new DenseMatrixQuaternion(left.rowCount, right.columnCount);

            for (int i = 0; i < left.rowCount; i++)
            {
                for (int j = 0; j < right.columnCount; j++)
                {
                    for (int z = 0; z < left.columnCount; z++)
                    {
                        result.datas[i, j] += left.datas[i, z] * right.datas[z, j];
                    }
                }
            }

            return result;
        }
Beispiel #23
0
        public static DenseMatrixQuaternion operator /(DenseMatrixQuaternion left, Quaternion right)
        {
            //Make sure matrix dimensions are equal
            DenseMatrixQuaternion matrix = new DenseMatrixQuaternion(left.RowCount, left.ColumnCount);

            // Quaternion rightInv = right.Invert();

            for (int i = 0; i < left.RowCount; i++)
            {
                for (int j = 0; j < left.columnCount; j++)
                {
                    //  matrix.datas[i, j] = left.datas[i, j] * rightInv;
                }
            }

            return matrix;
        }
Beispiel #24
0
        public static DenseMatrixQuaternion operator *(DenseMatrixQuaternion left, SparseMatrixQuaternion right)
        {
            //Make sure matrix dimensions are equal
            if (left.columnCount != right.RowCount)
            {
                throw new Exception("The dimension of two matrix must be equal");
            }
            DenseMatrixQuaternion resultMatrix = new DenseMatrixQuaternion(left.RowCount, right.ColumnCount);
            Quaternion[,] result = resultMatrix.datas;

            for (int i = 0; i < left.rowCount; i++)
            {
                foreach (KeyValuePair<Pair, Quaternion> item in right.Datas)
                {
                    Pair pair = item.Key;
                    Quaternion value = item.Value;

                    int m = pair.Key;
                    int n = pair.Value;

                    //M: mutiply index N: vector store index
                    result[i, n] += left[i, m] * value;
                }
            }

            return resultMatrix;
        }
Beispiel #25
0
        void NormalizeSolution(ref DenseMatrixQuaternion newVertices)
        {
            RemoveMean(ref newVertices);

            // Infinite Norm
            double r = 0;
            for (int i = 0; i < newVertices.RowCount; i++)
            {
                r = Math.Max(r, newVertices[i, 0].LengthSquared);
            }
            r = Math.Sqrt(r);

            for (int i = 0; i < newVertices.RowCount; i++)
            {
                newVertices[i, 0] /= r;
            }

        }
Beispiel #26
0
        void UpdatePosition(ref DenseMatrixQuaternion newVertices)
        {
            for (int i = 0; i < newVertices.RowCount; i++)
            {
                Quaternion v = newVertices[i, 0];
                Vector3D newPosition = new Vector3D(v.x, v.y, v.z);
                mesh.Vertices[i].Traits.Position = newPosition;
            }

        }
Beispiel #27
0
        DenseMatrixQuaternion ReadLambda(String path)
        {
            FileStream fs = new FileStream(path, FileMode.Open);
            StreamReader sr = new StreamReader(fs);
            String line = null;

            DenseMatrixQuaternion qt = new DenseMatrixQuaternion(mesh.Vertices.Count, 1);
            char[] splitChar = new char[] { ' ' };
            int row = 0;

            while ((line = sr.ReadLine()) != null)
            {
                String[] token = line.Split(splitChar);

                double w = double.Parse(token[0]);
                double x = double.Parse(token[1]);
                double y = double.Parse(token[2]);
                double z = double.Parse(token[3]);

                Quaternion q = new Quaternion(x, y, z, w);

                qt[row, 0] = q;

                row++;
            }

            return qt;
        }
Beispiel #28
0
        void RemoveMean(ref DenseMatrixQuaternion x)
        {
            Quaternion mean = Quaternion.Zero;
            for (int i = 0; i < x.RowCount; i++)
            {
                mean += x[i, 0];
            }

            mean /= x.RowCount;

            for (int i = 0; i < x.RowCount; i++)
            {
                x[i, 0] -= mean;
            }

        }
Beispiel #29
0
        DenseMatrixQuaternion BuildOmega(DenseMatrixQuaternion lamda)
        {
            DenseMatrixQuaternion Omega = new DenseMatrixQuaternion(mesh.Vertices.Count, 1);

            TriMesh.Vertex[] index = new TriMesh.Vertex[3];

            foreach (TriMesh.Face face in mesh.Faces)
            {
                index[0] = face.GetVertex(2);
                index[1] = face.GetVertex(0);
                index[2] = face.GetVertex(1);

                for (int i = 0; i < 3; i++)
                {
                    Quaternion f0 = new Quaternion(index[(i + 0) % 3].Traits.Position, 0);
                    Quaternion f1 = new Quaternion(index[(i + 1) % 3].Traits.Position, 0);
                    Quaternion f2 = new Quaternion(index[(i + 2) % 3].Traits.Position, 0);

                    //Setting Orientation Swap it
                    TriMesh.Vertex aI = index[(i + 1) % 3];
                    TriMesh.Vertex bI = index[(i + 2) % 3];
                    if (aI.Index > bI.Index)
                    {
                        aI = index[(i + 2) % 3];
                        bI = index[(i + 1) % 3];
                    }

                    Quaternion aLamda = lamda[aI.Index, 0];
                    Quaternion bLamda = lamda[bI.Index, 0];
                    Quaternion e = new Quaternion(bI.Traits.Position, 0) - new Quaternion(aI.Traits.Position, 0);
                    Quaternion conj = aLamda.Conjugate();
                    Quaternion bconj = bLamda.Conjugate();
                    Quaternion partA = conj * e * aLamda;
                    Quaternion eTilde = (1f / 3f) * partA +
                                        (1f / 6f) * aLamda.Conjugate() * e * bLamda +
                                        (1f / 6f) * bLamda.Conjugate() * e * aLamda +
                                        (1f / 3f) * bLamda.Conjugate() * e * bLamda;

                    Vector3D u1 = index[(i + 1) % 3].Traits.Position - index[(i + 0) % 3].Traits.Position;
                    Vector3D u2 = index[(i + 2) % 3].Traits.Position - index[(i + 0) % 3].Traits.Position;

                    double cotAlpha = u1.Dot(u2) / u1.Cross(u2).Length();

                    Quaternion q = cotAlpha * eTilde / 2;

                    Omega[aI.Index, 0] -= q;
                    Omega[bI.Index, 0] += q;
                }

            }

            RemoveMean(ref Omega);
            return Omega;
        }
Beispiel #30
0
        public static DenseMatrixQuaternion operator *(Quaternion left, DenseMatrixQuaternion right)
        {
            DenseMatrixQuaternion result = new DenseMatrixQuaternion(right.rowCount, right.columnCount);

            for (int i = 0; i < right.rowCount; i++)
            {
                for (int j = 0; j < right.columnCount; j++)
                {
                    result.datas[i, j] = right.datas[i, j] * left;
                }
            }

            return result;
        }
        public DenseMatrixQuaternion SolveByFactorizedLU(ref DenseMatrixQuaternion b)
        {
            if (b.ColumnCount > 1)
            {
                return null;
            }

            double[][] rhs = new double[4][];   //Arranage By Column
            for (int i = 0; i < 4; i++)
            {
                rhs[i] = new double[4 * b.RowCount];
            }

            double[][] x = new double[4][];
            for (int i = 0; i < 4; i++)
            {
                x[i] = new double[4 * this.n];
            }

            for (int i = 0; i < b.RowCount; i++)
            {
                Quaternion item = b[i, 0];

                Matrix4D mat = item.ToMatrix();

                rhs[0][4 * i] = mat[0, 0]; rhs[1][4 * i] = mat[0, 1]; rhs[2][4 * i] = mat[0, 2]; rhs[3][4 * i] = mat[0, 3];
                rhs[0][4 * i + 1] = mat[1, 0]; rhs[1][4 * i + 1] = mat[1, 1]; rhs[2][4 * i + 1] = mat[1, 2]; rhs[3][4 * i + 1] = mat[1, 3];
                rhs[0][4 * i + 2] = mat[2, 0]; rhs[1][4 * i + 2] = mat[2, 1]; rhs[2][4 * i + 2] = mat[2, 2]; rhs[3][4 * i + 2] = mat[2, 3];
                rhs[0][4 * i + 3] = mat[3, 0]; rhs[1][4 * i + 3] = mat[3, 1]; rhs[2][4 * i + 3] = mat[3, 2]; rhs[3][4 * i + 3] = mat[3, 3];
            }

            DenseMatrixQuaternion result = new DenseMatrixQuaternion(n, 1);

            //Solve
            for (int i = 0; i < 4; i++)
            {
                SolveLU(ref rhs[i], ref x[i]);
            }

            for (int i = 0; i < this.n; i++)
            {
                result[i, 0] = new Quaternion(x[0][4 * i + 1], x[0][4 * i + 2], x[0][4 * i + 3], x[0][4 * i]);
            }

            x = null;
            GC.Collect();

            return result;
        }
Beispiel #32
0
 public static DenseMatrixQuaternion Copy(ref DenseMatrixQuaternion B)
 {
     DenseMatrixQuaternion newMatrix = new DenseMatrixQuaternion();
     newMatrix.rowCount = B.rowCount;
     newMatrix.columnCount = B.columnCount;
     Array.Copy(B.datas, newMatrix.datas, B.datas.Length);
     return newMatrix;
 }
Beispiel #33
0
 public Quaternion Dot(DenseMatrixQuaternion right)
 {
     DenseMatrixQuaternion x = this.Transpose() * right;
     Quaternion result = x[0, 0];
     return result;
 }