예제 #1
0
        private double CalculateError(int i0, int i1, out Vector3d result)
        {
            // compute interpolated vertex
            var             vertices = this.vertices.Data;
            Vertex          v0       = vertices[i0];
            Vertex          v1       = vertices[i1];
            SymmetricMatrix q        = v0.q + v1.q;
            bool            border   = (v0.border & v1.border);
            double          error    = 0.0;
            double          det      = q.Determinant1();

            if (det != 0.0 && !border)
            {
                // q_delta is invertible
                result = new Vector3d(
                    -1.0 / det * q.Determinant2(),  // vx = A41/det(q_delta)
                    1.0 / det * q.Determinant3(),   // vy = A42/det(q_delta)
                    -1.0 / det * q.Determinant4()); // vz = A43/det(q_delta)
                error = VertexError(ref q, result.x, result.y, result.z);
            }
            else
            {
                // det = 0 -> try to find best result
                Vector3d p1     = v0.p;
                Vector3d p2     = v1.p;
                Vector3d p3     = (p1 + p2) * 0.5f;
                double   error1 = VertexError(ref q, p1.x, p1.y, p1.z);
                double   error2 = VertexError(ref q, p2.x, p2.y, p2.z);
                double   error3 = VertexError(ref q, p3.x, p3.y, p3.z);
                error = MathHelper.Min(error1, error2, error3);
                if (error == error3)
                {
                    result = p3;
                }
                else if (error == error2)
                {
                    result = p2;
                }
                else if (error == error1)
                {
                    result = p1;
                }
                else
                {
                    result = p3;
                }
            }
            return(error);
        }
예제 #2
0
        // Error for one edge
        private double CalculateError(int id_v1, int id_v2, ref Vector3d result, ref Vector3d vbuff, ref SymmetricMatrix smbuff)
        {
            // compute interpolated vertex
            SymmetricMatrix.Add(ref vertices.Data[id_v1].q, ref vertices.Data[id_v2].q, ref smbuff);
            double error = 0;
            double det   = smbuff.Determinant1();

            if (Math.Abs(det) > 1.0e-10)
            {
                // q_delta is invertible
                result.X = -1.0 / det * smbuff.Determinant2(); // vx = A41/det(q_delta)
                result.Y = +1.0 / det * smbuff.Determinant3(); // vy = A42/det(q_delta)
                result.Z = -1.0 / det * smbuff.Determinant4(); // vz = A43/det(q_delta)
                error    = VertexError(ref smbuff, ref result);
            }
            else
            {
                // det = 0 -> try to find best result
                Vector3d p1 = vertices.Data[id_v1].p;
                Vector3d p2 = vertices.Data[id_v2].p;
                Vector3d.Average(ref p1, ref p2, ref vbuff);
                double error1 = VertexError(ref smbuff, ref p1);
                double error2 = VertexError(ref smbuff, ref p2);
                double error3 = VertexError(ref smbuff, ref vbuff);
                error = Math.Min(error1, Math.Min(error2, error3));
                if (error1 == error)
                {
                    result = p1;
                }
                else if (error2 == error)
                {
                    result = p2;
                }
                else
                {
                    result = vbuff;
                    vbuff  = new Vector3d();
                }
            }

            return(error);
        }