public static int FindClosestPointTo(Stroke stroke, Point p, int start, int finish) { StrokeGeometry sg = new StrokeGeometry(stroke); return sg.FindClosestPointTo(p,start,finish); }
public static void AnalyzeClosedness(Stroke stroke, double tolerance, out bool closed, out Point[] vertices) // out double tAB, out double tPQ) { closed = false; vertices = null; // Formulate closure gap-tolerance, based on stroke length (but clipped to <= 500isu). double len = StrokeGeometry.IntegrateLength(stroke); double segtol = Math.Max(50, Math.Min(tolerance, len / 20.0)); double gaptol = Math.Max(150, Math.Min(tolerance, len / 7.0)); dbg.WriteLine(String.Format("length: {0}", len)); dbg.WriteLine(String.Format("segtol: {0}", segtol)); dbg.WriteLine(String.Format("gaptol: {0}", gaptol)); // Break the stroke down into indices. int[] indices; vertices = SegmentizeStroke(stroke, segtol, out indices); int nv = vertices.Length; // Do the head/tail segments intersect? Are they close? if (nv >= 4) { Point headA = (Point)vertices[0]; Point headB = (Point)vertices[1]; Point tailP = (Point)vertices[nv - 2]; Point tailQ = (Point)vertices[nv - 1]; double tAB, tPQ; SegmentCollision.HitTest(headA, headB, tailP, tailQ, out tAB, out tPQ); Point virtualIntersectH = Geometry.Interpolate(headA, headB, tAB); Point virtualIntersectT = Geometry.Interpolate(tailP, tailQ, tPQ); Point virtualIntersect = Geometry.Interpolate(virtualIntersectH, virtualIntersectT, 0.5); double dh2i = Geometry.DistanceBetween(headA, virtualIntersect); double dt2i = Geometry.DistanceBetween(tailQ, virtualIntersect); #if DEBUG dbg.WriteLine(String.Format("numV: {0}", nv)); dbg.WriteLine(String.Format("tAB: {0}", tAB)); dbg.WriteLine(String.Format("tPQ: {0}", tPQ)); dbg.WriteLine(String.Format("isct: {0}", virtualIntersect)); dbg.WriteLine(String.Format("dh2i: {0}", dh2i)); dbg.WriteLine(String.Format("dt2i: {0}", dt2i)); #endif if (dh2i < gaptol && dt2i < gaptol) { closed = true; // Adjust the head point to the actual intersection. vertices[0] = virtualIntersect; dbg.WriteLine("Closed! Why? dh/t2i < gaptol"); } else if ((-0.3 < tAB && tAB < 0.3) && (0.7 < tPQ && tPQ < 1.3)) { closed = true; // Adjust the head point to the actual intersection. vertices[0] = virtualIntersect; dbg.WriteLine("Closed! Why? |t*| < 0.3"); } else { // Last chance: measure nearest distance from head to tail segment. int closeI = StrokeGeometry.FindClosestPointTo( stroke, headA, indices[nv - 2], indices[nv - 1]); Point close = stroke.GetPoint(closeI); double d = Geometry.DistanceBetween(headA, close); if (d < gaptol) { closed = true; // Keep the head point; discard the tail point below. dbg.WriteLine("Closed! Why? Last chance head/tail distance < gaptol"); } } // Remove the last point as redundant if it's closed. if (closed) { Point[] verticesX = new Point[nv - 1]; Array.Copy(vertices, verticesX, nv - 1); vertices = verticesX; } } }
public static int FindClosestPointTo(Stroke stroke, Point p, int start, int finish) { StrokeGeometry sg = new StrokeGeometry(stroke); return(sg.FindClosestPointTo(p, start, finish)); }