// Given an array of points that define a path, add a new bend into it at the "right" place where it fits. // The oldPoints array may be null or empty. public static PointF[] AddPointToArray(PointF[] oldPoints, PointF newPoint) { if (oldPoints == null || oldPoints.Length == 0) { // Simple case -- no old path. return(new PointF[1] { newPoint }); } else { // Complex case. We need to figure out where the newPoint goes by finding the closest point // on the path. PointF closestPoint; SymPath path = new SymPath(oldPoints); path.DistanceFromPoint(newPoint, out closestPoint); // On which segment does the closest point lie? int segmentStart, segmentEnd; path.FindSegmentWithPoint(closestPoint, 0.01F, out segmentStart, out segmentEnd); // Insert the point in that segment. List <PointF> list = new List <PointF>(oldPoints); list.Insert(segmentEnd, newPoint); return(list.ToArray()); } }
// Add a new gap an an array of gaps. The resulting array is simplified. The original array may be null. public static LegGap[] AddGap(SymPath path, LegGap[] original, PointF pt1, PointF pt2) { float dist1, dist2; LegGap newGap; LegGap[] newGaps; // map points to closes points on the line. path.DistanceFromPoint(pt1, out pt1); path.DistanceFromPoint(pt2, out pt2); // Map to distances along the line. dist1 = path.LengthToPoint(pt1); dist2 = path.LengthToPoint(pt2); // Create the new gap. if (dist1 < dist2) { newGap = new LegGap(dist1, dist2 - dist1); } else { newGap = new LegGap(dist2, dist1 - dist2); } // Add to the old gaps. if (original == null) { newGaps = new LegGap[1] { newGap } } ; else { newGaps = new LegGap[original.Length + 1]; Array.Copy(original, newGaps, original.Length); newGaps[original.Length] = newGap; } // Simplify return(SimplifyGaps(newGaps, path.Length)); }
// Transform a gap array to a new path, keeping close gaps in the closest position on the new path. Remove far away gaps. public static LegGap[] MoveGapsToNewPath(LegGap[] oldGaps, SymPath oldPath, SymPath newPath) { oldGaps = SimplifyGaps(oldGaps, oldPath.Length); if (oldGaps == null) { return(null); } PointF oldStart, oldEnd, newStart, newEnd; // ends points of the gaps float distanceStart, distanceEnd; // distance between oldStart and newStart, distance between oldEnd and newEnd. List <LegGap> newGaps = new List <LegGap>(); // Move gap to a new gap by converting start and end to point, finding closest points on new path. // If the gap has moved too far, just remove it, else transformit. for (int i = 0; i < oldGaps.Length; ++i) { oldStart = oldPath.PointAtLength(oldGaps[i].distanceFromStart); oldEnd = oldPath.PointAtLength(oldGaps[i].distanceFromStart + oldGaps[i].length); distanceStart = newPath.DistanceFromPoint(oldStart, out newStart); distanceEnd = newPath.DistanceFromPoint(oldEnd, out newEnd); // If the new gap is close enough to the old gap, then add the new gap. if (distanceStart + distanceEnd <= 2 * oldGaps[i].length) { float newDistanceToStart = newPath.LengthToPoint(newStart); float newDistanceToEnd = newPath.LengthToPoint(newEnd); if (newDistanceToStart < newDistanceToEnd) { newGaps.Add(new LegGap(newDistanceToStart, newDistanceToEnd - newDistanceToStart)); } else { newGaps.Add(new LegGap(newDistanceToEnd, newDistanceToStart - newDistanceToEnd)); } } } // Simply the new gap array. return(SimplifyGaps(newGaps.ToArray(), newPath.Length)); }
// Add a new gap an an array of gaps. The resulting array is simplified. The original array may be null. public static LegGap[] AddGap(SymPath path, LegGap[] original, PointF pt1, PointF pt2) { float dist1, dist2; LegGap newGap; LegGap[] newGaps; // map points to closes points on the line. path.DistanceFromPoint(pt1, out pt1); path.DistanceFromPoint(pt2, out pt2); // Map to distances along the line. dist1 = path.LengthToPoint(pt1); dist2 = path.LengthToPoint(pt2); // Create the new gap. if (dist1 < dist2) newGap = new LegGap(dist1, dist2 - dist1); else newGap = new LegGap(dist2, dist1 - dist2); // Add to the old gaps. if (original == null) newGaps = new LegGap[1] { newGap }; else { newGaps = new LegGap[original.Length + 1]; Array.Copy(original, newGaps, original.Length); newGaps[original.Length] = newGap; } // Simplify return SimplifyGaps(newGaps, path.Length); }
// Transform a gap array to a new path, keeping close gaps in the closest position on the new path. Remove far away gaps. public static LegGap[] MoveGapsToNewPath(LegGap[] oldGaps, SymPath oldPath, SymPath newPath) { oldGaps = SimplifyGaps(oldGaps, oldPath.Length); if (oldGaps == null) return null; PointF oldStart, oldEnd, newStart, newEnd; // ends points of the gaps float distanceStart, distanceEnd; // distance between oldStart and newStart, distance between oldEnd and newEnd. List<LegGap> newGaps = new List<LegGap>(); // Move gap to a new gap by converting start and end to point, finding closest points on new path. // If the gap has moved too far, just remove it, else transformit. for (int i = 0; i < oldGaps.Length; ++i) { oldStart = oldPath.PointAtLength(oldGaps[i].distanceFromStart); oldEnd = oldPath.PointAtLength(oldGaps[i].distanceFromStart + oldGaps[i].length); distanceStart = newPath.DistanceFromPoint(oldStart, out newStart); distanceEnd = newPath.DistanceFromPoint(oldEnd, out newEnd); // If the new gap is close enough to the old gap, then add the new gap. if (distanceStart + distanceEnd <= 2 * oldGaps[i].length) { float newDistanceToStart = newPath.LengthToPoint(newStart); float newDistanceToEnd = newPath.LengthToPoint(newEnd); if (newDistanceToStart < newDistanceToEnd) newGaps.Add(new LegGap(newDistanceToStart, newDistanceToEnd - newDistanceToStart)); else newGaps.Add(new LegGap(newDistanceToEnd, newDistanceToStart - newDistanceToEnd)); } } // Simply the new gap array. return SimplifyGaps(newGaps.ToArray(), newPath.Length); }
public override double DistanceFromPoint(PointF pt) { // Is point within the rectangle? RectangleF rect = new RectangleF(new PointF(topLeft.X, topLeft.Y - size.Height), size); if (rect.Contains(pt)) return 0; // Return distance to the border of the rectangle. PointF closestPoint; SymPath path = new SymPath(new PointF[] {new PointF(rect.Left, rect.Top), new PointF(rect.Left, rect.Bottom), new PointF(rect.Right, rect.Bottom), new PointF(rect.Right, rect.Top), new PointF(rect.Left, rect.Top) }, new PointKind[] { PointKind.Normal, PointKind.Normal, PointKind.Normal, PointKind.Normal, PointKind.Normal} ); return path.DistanceFromPoint(pt, out closestPoint); }
// Get the distance of a point from this object, or 0 if the point is covered by the object. public override double DistanceFromPoint(PointF pt) { PointF closestPoint; // Is the point contained inside? if (rect.Contains(pt)) return 0.0; SymPath path = new SymPath(new PointF[5] { new PointF(rect.Left, rect.Top), new PointF(rect.Right, rect.Top), new PointF(rect.Right, rect.Bottom), new PointF(rect.Left, rect.Bottom), new PointF(rect.Left, rect.Top)}); return path.DistanceFromPoint(pt, out closestPoint); }