// Error for one edge double Calculate_error(int id_v1, int id_v2, ref Vector3 p_result) { // compute interpolated vertex SymetricMatrix q = vertices[id_v1].q + vertices[id_v2].q; bool border = vertices[id_v1].border != 0 && vertices[id_v2].border != 0; double error = 0; double det = q.Det(0, 1, 2, 1, 4, 5, 2, 5, 7); if (det != 0 && !border) { // q_delta is invertible p_result.X = -1 / det * (q.Det(1, 2, 3, 4, 5, 6, 5, 7, 8)); // vx = A41/det(q_delta) p_result.Y = 1 / det * (q.Det(0, 2, 3, 1, 5, 6, 2, 7, 8)); // vy = A42/det(q_delta) p_result.Z = -1 / det * (q.Det(0, 1, 3, 1, 4, 6, 2, 5, 8)); // vz = A43/det(q_delta) error = Vertex_error(q, p_result.X, p_result.Y, p_result.Z); } else { // det = 0 -> try to find best result Vector3 p1 = vertices[id_v1].p; Vector3 p2 = vertices[id_v2].p; Vector3 p3 = (p1 + p2) / 2; double error1 = Vertex_error(q, p1.X, p1.Y, p1.Z); double error2 = Vertex_error(q, p2.X, p2.Y, p2.Z); double error3 = Vertex_error(q, p3.X, p3.Y, p3.Z); error = Math.Min(error1, Math.Min(error2, error3)); if (error1 == error) { p_result = p1; } if (error2 == error) { p_result = p2; } if (error3 == error) { p_result = p3; } } return(error); }
// Error between vertex and Quadric double Vertex_error(SymetricMatrix q, double x, double y, double z) { return(q[0] * x * x + 2 * q[1] * x * y + 2 * q[2] * x * z + 2 * q[3] * x + q[4] * y * y + 2 * q[5] * y * z + 2 * q[6] * y + q[7] * z * z + 2 * q[8] * z + q[9]); }