public GetDistanceToPoint ( Vector3D, inPt ) : double | ||
inPt | Vector3D, | |
Результат | double |
public void TestPlaneDistanceSimple() { Plane3D planeD = new Plane3D(new Vector3D(0, 1, 0), 10); Assert.AreEqual(0, planeD.GetDistanceToPoint(new Vector3D(0, -10, 0))); Assert.AreEqual(20, planeD.GetDistanceToPoint(new Vector3D(0, 10, 0))); }
// return 1 if triangle is larger than splitting plane (in front of) // return 0 if triangle intersect // return -1 if triangle is smaller than splitting plane (begin) // return 2 if triangle is in same plane as triangle (currently assuming that triangle is non intersecting) public IntersectionResult Intersect(Triangle3D newTriangle, double distanceThreshold = 0.000027) { int larger = 0; int equal = 0; int smaller = 0; for (int i = 0; i < 3; i++) { double val = plane.GetDistanceToPoint(newTriangle[i]); double distanceRelativeError = distanceThreshold * System.Math.Abs(plane.distance); if (val > distanceRelativeError) { larger++; } else if (val < -distanceRelativeError) { smaller++; } else { equal++; } } // Debug.Log(string.Format("Larger {0} Equal {1} Smaller {2}",larger, equal, smaller)); if (equal == 3) { return(IntersectionResult.InPlane); } if (larger + equal == 3) { return(IntersectionResult.Larger); } if (smaller + equal == 3) { return(IntersectionResult.Smaller); } return(IntersectionResult.Intersection); // intersection }
Vector3D ProjectToTriangle(Vector3D point) { Plane3D plane = new Plane3D(Normal, points[0]); bool isPointInPlane = System.Math.Abs(plane.GetDistanceToPoint(point)) < 0.0001; if (!isPointInPlane) { double dist; point.y = 0; var ray = new RayD(point, Vector3D.up); plane.Raycast(ray, out dist); point.y = dist; } return(point); }
private static bool IsFacesOnSamePlane(HMesh hmesh, List <Halfedge> hes, int faceLabel = -1) { bool facesAreOnSamePlane = true; Plane3D plane = new Plane3D(Vector3D.zero, 0); foreach (var he in hes) { if (faceLabel != -1 && he.face.label != faceLabel) { continue; } if (!he.face.IsDegenerate()) { plane = he.face.GetPlaneEquation(); break; } } if (plane.normal == Vector3D.zero) { Debug.Assert(false, "Warning - face is degenerate"); return(false); } // allowing the center of the face to move maximum 50% of zeroMagnitudeTreshold (to the plane of an arbitary face double planeDistThreshold = hmesh.zeroMagnitudeTreshold * 0.5; foreach (Halfedge he in hes) { if (faceLabel != -1 && he.face.label != faceLabel) { continue; } if (plane.GetDistanceToPoint(he.GetCenter()) > planeDistThreshold) { facesAreOnSamePlane = false; break; } } return(facesAreOnSamePlane); }
public void TestPlaneDistance() { Random.InitState(123); for (int i = 0; i < 1000; i++) { Vector3 direction = Random.onUnitSphere; float dist = Random.Range(-9999, 9999); Vector3D directionD = new Vector3D(direction); Plane3D planeD = new Plane3D(directionD, dist); Plane plane = new Plane(direction, dist); for (int j = 0; j < 10; j++) { Vector3 pos = Random.insideUnitSphere * 99999; Vector3D posD = new Vector3D(pos); double val1 = plane.GetDistanceToPoint(pos); double val2 = planeD.GetDistanceToPoint(posD); Assert.AreEqual(val1, val2, 0.02, "GetDistanceToPoint " + plane); Assert.AreEqual(plane.GetSide(pos), planeD.GetSide(posD), "GetSide " + plane); } } }
Vector3D ProjectToTriangle(Vector3D point) { Plane3D plane = new Plane3D(Normal, points[0]); bool isPointInPlane = System.Math.Abs(plane.GetDistanceToPoint(point))<0.0001; if (!isPointInPlane) { double dist; point.y = 0; var ray = new RayD(point, Vector3D.up); plane.Raycast(ray, out dist); point.y = dist; } return point; }
public SplitType SplitWithPlane(Plane3D plane, out Polygon3D front, out Polygon3D back, bool veryPrecise) { Vector3D intersection; front = null; back = null; double dist = 0; double maxDist = 0; double minDist = 0; double prevDist; double threshold; VType status; VType prevStatus = VType.Either; // double scale if (veryPrecise) { threshold = 0.01; } else { threshold = 0.25; } for (int i = 0; i < vertices.Count; i++) { dist = plane.GetDistanceToPoint(vertices[i]); if (i == 0 || dist > maxDist) { maxDist = dist; } if (i == 0 || dist < minDist) { minDist = dist; } if (dist > +threshold) { prevStatus = VType.Front; } else if (dist < -threshold) { prevStatus = VType.Back; } } if (maxDist < threshold && minDist > -threshold) { return(SplitType.SP_Coplanar); } else if (maxDist < threshold) { return(SplitType.SP_Back); } else if (minDist > -threshold) { return(SplitType.SP_Front); } else { front = Clone(); front.vertices.Clear(); back = Clone(); back.vertices.Clear(); int j = vertices.Count - 1; for (int i = 0; i < vertices.Count; i++) { prevDist = dist; dist = plane.GetDistanceToPoint(vertices[i]); if (dist > +threshold) { status = VType.Front; } else if (dist < -threshold) { status = VType.Back; } else { status = prevStatus; } if (status != prevStatus) { // Crossing. Either Front-to-Back or Back-To-Front. // Intersection point is naturally on both front and back polys. if ((dist >= -threshold) && (dist < +threshold)) { // This point lies on plane. if (prevStatus == VType.Front) { front.vertices.Add(vertices[i]); back.vertices.Add(vertices[i]); } else { back.vertices.Add(vertices[i]); front.vertices.Add(vertices[i]); } } else if ((prevDist >= -threshold) && (prevDist < +threshold)) { // Previous point lies on plane. if (status == VType.Front) { front.vertices.Add(vertices[j]); front.vertices.Add(vertices[i]); } else { back.vertices.Add(vertices[j]); back.vertices.Add(vertices[i]); } } else { // Intersection point is in between. intersection = plane.LineIntersection(vertices[j], vertices[i]); if (prevStatus == VType.Front) { front.vertices.Add(intersection); back.vertices.Add(intersection); back.vertices.Add(vertices[i]); } else { back.vertices.Add(intersection); front.vertices.Add(intersection); front.vertices.Add(vertices[i]); } } } else { if (status == VType.Front) { front.vertices.Add(vertices[i]); } else { back.vertices.Add(vertices[i]); } } j = i; prevStatus = status; } // Handle possibility of sliver polys due to precision errors. if (front.Fix() < 3) { return(SplitType.SP_Back); } else if (back.Fix() < 3) { return(SplitType.SP_Front); } else { return(SplitType.SP_Split); } } }