// Move a gap start/stop point to a new location. Return the new gap array. The gap array is NOT simplified. public static LegGap[] MoveStartStopPoint(SymPath path, LegGap[] gaps, PointF oldPt, PointF newPt) { LegGap[] newGaps = (LegGap[])gaps.Clone(); float newLengthAlongPath = path.LengthToPoint(newPt); for (int i = 0; i < newGaps.Length; ++i) { PointF startPt = path.PointAtLength(gaps[i].distanceFromStart); PointF endPt = path.PointAtLength(gaps[i].distanceFromStart + gaps[i].length); if (Geometry.Distance(startPt, oldPt) < 0.01) { // Moving start point of the gap. newGaps[i].length -= (newLengthAlongPath - newGaps[i].distanceFromStart); newGaps[i].distanceFromStart = newLengthAlongPath; } else if (Geometry.Distance(endPt, oldPt) < 0.01) { // Moving end point of the gap. newGaps[i].length = newLengthAlongPath - gaps[i].distanceFromStart; } } return(newGaps); }
/* * Static functions that work on arrays of leg gaps. */ // Get the start/stop points of the gaps. Primarily useful for finding where the handles should be. public static PointF[] GapStartStopPoints(SymPath path, LegGap[] gaps) { if (gaps == null || gaps.Length == 0) { return(null); } PointF[] pts = new PointF[gaps.Length * 2]; for (int i = 0; i < gaps.Length; ++i) { pts[i * 2] = path.PointAtLength(gaps[i].distanceFromStart); pts[i * 2 + 1] = path.PointAtLength(gaps[i].distanceFromStart + gaps[i].length); } return(pts); }
// 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)); }
// Split a path into multiple paths based on an array of LegGaps. The gaps might extend beyond the end of the // or the beginning of the path. The gaps array need not be in simplified form. public static SymPath[] SplitPathWithGaps(SymPath pathInitial, LegGap[] gaps) { // Get the length of the path. float pathLength = pathInitial.Length; // Simply and sort the gaps. gaps = SimplifyGaps(gaps, pathLength); // If no gaps length, the entire path is correct. if (gaps == null) { return new SymPath[1] { pathInitial } } ; // Transform into start/stop distances from beginning of path. float[] starts = new float[gaps.Length + 1]; float[] ends = new float[gaps.Length + 1]; starts[0] = 0; ends[gaps.Length] = pathLength; for (int i = 0; i < gaps.Length; ++i) { ends[i] = gaps[i].distanceFromStart; starts[i + 1] = gaps[i].distanceFromStart + gaps[i].length; } // Each 2 points is a new path. List <SymPath> list = new List <SymPath>(starts.Length); for (int i = 0; i < starts.Length; ++i) { SymPath p = pathInitial.Segment(pathInitial.PointAtLength(starts[i]), pathInitial.PointAtLength(ends[i])); if (p != null) { list.Add(p); } } return(list.ToArray()); }
// Split a path into multiple paths based on an array of LegGaps. The gaps might extend beyond the end of the // or the beginning of the path. The gaps array need not be in simplified form. public static SymPath[] SplitPathWithGaps(SymPath pathInitial, LegGap[] gaps) { // Get the length of the path. float pathLength = pathInitial.Length; // Simply and sort the gaps. gaps = SimplifyGaps(gaps, pathLength); // If no gaps length, the entire path is correct. if (gaps == null) return new SymPath[1] { pathInitial }; // Transform into start/stop distances from beginning of path. float[] starts = new float[gaps.Length + 1]; float[] ends = new float[gaps.Length + 1]; starts[0] = 0; ends[gaps.Length] = pathLength; for (int i = 0; i < gaps.Length; ++i) { ends[i] = gaps[i].distanceFromStart; starts[i + 1] = gaps[i].distanceFromStart + gaps[i].length; } // Each 2 points is a new path. List<SymPath> list = new List<SymPath>(starts.Length); for (int i = 0; i < starts.Length; ++i) { SymPath p = pathInitial.Segment(pathInitial.PointAtLength(starts[i]), pathInitial.PointAtLength(ends[i])); if (p != null) list.Add(p); } return list.ToArray(); }
// Move a gap start/stop point to a new location. Return the new gap array. The gap array is NOT simplified. public static LegGap[] MoveStartStopPoint(SymPath path, LegGap[] gaps, PointF oldPt, PointF newPt) { LegGap[] newGaps = (LegGap[]) gaps.Clone(); float newLengthAlongPath = path.LengthToPoint(newPt); for (int i = 0; i < newGaps.Length; ++i) { PointF startPt = path.PointAtLength(gaps[i].distanceFromStart); PointF endPt = path.PointAtLength(gaps[i].distanceFromStart + gaps[i].length); if (Geometry.Distance(startPt, oldPt) < 0.01) { // Moving start point of the gap. newGaps[i].length -= (newLengthAlongPath - newGaps[i].distanceFromStart); newGaps[i].distanceFromStart = newLengthAlongPath; } else if (Geometry.Distance(endPt, oldPt) < 0.01) { // Moving end point of the gap. newGaps[i].length = newLengthAlongPath - gaps[i].distanceFromStart; } } return newGaps; }
// 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); }
/* * Static functions that work on arrays of leg gaps. */ // Get the start/stop points of the gaps. Primarily useful for finding where the handles should be. public static PointF[] GapStartStopPoints(SymPath path, LegGap[] gaps) { if (gaps == null || gaps.Length == 0) return null; PointF[] pts = new PointF[gaps.Length * 2]; for (int i = 0; i < gaps.Length; ++i) { pts[i * 2] = path.PointAtLength(gaps[i].distanceFromStart); pts[i * 2 + 1] = path.PointAtLength(gaps[i].distanceFromStart + gaps[i].length); } return pts; }