public bool PerpendicularTo(Point3d P0, Point3d P1, Point3d P2) { Vector3d V0, V1, V2, N0, N1, N2; V0 = P2 - P1; V1 = P0 - P2; V2 = P1 - P0; N0 = Vector3d.CrossProduct(V1, V2); if (!N0.Unitize()) { return(false); } N1 = Vector3d.CrossProduct(V2, V0); if (!N1.Unitize()) { return(false); } N2 = Vector3d.CrossProduct(V0, V1); if (!N2.Unitize()) { return(false); } double s0 = 1.0 / V0.Length; double s1 = 1.0 / V1.Length; double s2 = 1.0 / V2.Length; double e0 = s0 * Math.Abs(Vector3d.DotProduct(N0, V0)) + s1 * Math.Abs(Vector3d.DotProduct(N0, V1)) + s2 * Math.Abs(Vector3d.DotProduct(N0, V2)); double e1 = s0 * Math.Abs(Vector3d.DotProduct(N1, V0)) + s1 * Math.Abs(Vector3d.DotProduct(N1, V1)) + s2 * Math.Abs(Vector3d.DotProduct(N1, V2)); double e2 = s0 * Math.Abs(Vector3d.DotProduct(N2, V0)) + s1 * Math.Abs(Vector3d.DotProduct(N2, V1)) + s2 * Math.Abs(Vector3d.DotProduct(N2, V2)); if (e0 <= e1) { if (e0 <= e2) { this = N0; } else { this = N2; } } else if (e1 <= e2) { this = N1; } else { this = N2; } return(true); }