public double FindClosestElementToPoint(Vector2d point, out ElementLocation location) { location = new ElementLocation(int.MinValue, 0); double closestDistanceSquared = double.MaxValue; int currentElementIndex = 0; foreach (var element in elements) { // Update results if current element is closer Segment2d seg = element.GetSegment2d(); double currentSegmentClosestDistanceSquared = seg.DistanceSquared(point); // Update results if current element is closer if (currentSegmentClosestDistanceSquared < closestDistanceSquared) { closestDistanceSquared = currentSegmentClosestDistanceSquared; location.Index = currentElementIndex; location.ParameterizedDistance = GetParameterizedDistance(point, seg); } currentElementIndex++; } // For consistency, if the closest point is on a vertex, // give the index of the element after the vertex if (MathUtil.EpsilonEqual(location.ParameterizedDistance, 1, 1e-6)) { location.ParameterizedDistance = 0; location.Index = (location.Index + 1) % elements.Count; } return(Math.Sqrt(closestDistanceSquared)); }
public double Distance(Vector2D point) { double d0 = (Arc1IsSegment) ? Math.Sqrt(Segment1.DistanceSquared(point)) : Arc1.Distance(point); double d1 = (Arc2IsSegment) ? Math.Sqrt(Segment2.DistanceSquared(point)) : Arc2.Distance(point); return(Math.Min(d0, d1)); }
void sanity_check() { if (Quantity == 0) { Util.gDevAssert(Type == IntersectionType.Empty); Util.gDevAssert(Result == IntersectionResult.NoIntersection); } else if (Quantity == 1) { Util.gDevAssert(Type == IntersectionType.Point); Util.gDevAssert(segment1.DistanceSquared(Point0) < math.MathUtil.ZeroTolerance); Util.gDevAssert(segment2.DistanceSquared(Point0) < math.MathUtil.ZeroTolerance); } else if (Quantity == 2) { Util.gDevAssert(Type == IntersectionType.Segment); Util.gDevAssert(segment1.DistanceSquared(Point0) < math.MathUtil.ZeroTolerance); Util.gDevAssert(segment1.DistanceSquared(Point1) < math.MathUtil.ZeroTolerance); Util.gDevAssert(segment2.DistanceSquared(Point0) < math.MathUtil.ZeroTolerance); Util.gDevAssert(segment2.DistanceSquared(Point1) < math.MathUtil.ZeroTolerance); } }
public double DistanceSquared(Vector2D point) { double fNearestSqr = Double.MaxValue; for (int i = 0; i < vertices.Count - 1; ++i) { Segment2d seg = new Segment2d(vertices[i], vertices[i + 1]); double d = seg.DistanceSquared(point); if (d < fNearestSqr) { fNearestSqr = d; } } return(fNearestSqr); }
// Polygon simplification // code adapted from: http://softsurfer.com/Archive/algorithm_0205/algorithm_0205.htm // simplifyDP(): // This is the Douglas-Peucker recursive simplification routine // It just marks vertices that are part of the simplified polyline // for approximating the polyline subchain v[j] to v[k]. // Input: tol = approximation tolerance // v[] = polyline array of vertex points // j,k = indices for the subchain v[j] to v[k] // Output: mk[] = array of markers matching vertex array v[] static void simplifyDP(double tol, Vector2D[] v, int j, int k, bool[] mk) { if (k <= j + 1) // there is nothing to simplify { return; } // check for adequate approximation by segment S from v[j] to v[k] int maxi = j; // index of vertex farthest from S double maxd2 = 0; // distance squared of farthest vertex double tol2 = tol * tol; // tolerance squared Segment2d S = new Segment2d(v[j], v[k]); // segment from v[j] to v[k] // test each vertex v[i] for max distance from S // Note: this works in any dimension (2D, 3D, ...) for (int i = j + 1; i < k; i++) { double dv2 = S.DistanceSquared(v[i]); if (dv2 <= maxd2) { continue; } // v[i] is a new max vertex maxi = i; maxd2 = dv2; } if (maxd2 > tol2) // error is worse than the tolerance // split the polyline at the farthest vertex from S { mk[maxi] = true; // mark v[maxi] for the simplified polyline // recursively simplify the two subpolylines at v[maxi] simplifyDP(tol, v, j, maxi, mk); // polyline v[j] to v[maxi] simplifyDP(tol, v, maxi, k, mk); // polyline v[maxi] to v[k] } // else the approximation is OK, so ignore intermediate vertices return; }