protected virtual Index3i find_nearest(Vector2d pt, HashSet <Index2i> remaining) { double nearest = double.MaxValue; Index3i nearest_idx = Index3i.Max; foreach (Index2i idx in remaining) { if (idx.a == 0) // loop { PathLoop loop = Loops[idx.b]; double distance = GetLoopEntryPoint(pt, loop, out var location); if (distance < nearest) { nearest = distance; nearest_idx = new Index3i(idx.a, idx.b, location.Index); } } else // span { PathSpan span = Spans[idx.b]; double distance = GetSpanEntryPoint(pt, span, out bool flip); if (distance < nearest) { nearest = distance; nearest_idx = new Index3i(idx.a, idx.b, flip ? 1 : 0); } } } return(nearest_idx); }
public void SortAndAppendTo(Vector2d startPoint, IFillPathScheduler2d scheduler) { var saveHint = scheduler.SpeedHint; OutPoint = startPoint; List <Index3i> sorted = find_short_path_v1(startPoint); foreach (Index3i idx in sorted) { FillCurveSet2d paths = new FillCurveSet2d(); SchedulerSpeedHint pathHint = SchedulerSpeedHint.Default; if (idx.a == 0) // loop { PathLoop loop = Loops[idx.b]; pathHint = loop.speedHint; if (idx.c != 0) { int iStart = idx.c; FillPolygon2d o = new FillPolygon2d(); int N = loop.curve.VertexCount; for (int i = 0; i < N; ++i) { o.AppendVertex(loop.curve[(i + iStart) % N]); } o.TypeFlags = loop.curve.TypeFlags; paths.Append(o); OutPoint = o.Vertices[0]; } else { paths.Append(loop.curve); OutPoint = loop.curve.Vertices[0]; } } else // span { PathSpan span = Spans[idx.b]; if (idx.c == 1) { span.curve.Reverse(); } paths.Append(span.curve); OutPoint = span.curve.End; pathHint = span.speedHint; } scheduler.SpeedHint = pathHint; scheduler.AppendCurveSets(new List <FillCurveSet2d>() { paths }); } scheduler.SpeedHint = saveHint; }
protected virtual double GetLoopEntryPoint(Vector2d startPoint, PathLoop loop, out ElementLocation location) { if (loop.loop.FillType.IsEntryLocationSpecified()) { location = new ElementLocation(0, 0); return(loop.loop.Entry.Distance(startPoint)); } return(loop.loop.FindClosestElementToPoint(startPoint, out location)); }
Vector2d get_point(Index3i idx) { if (idx.a == 0) // loop { PathLoop loop = Loops[idx.b]; return(loop.curve.Segment(idx.c).Center); } else // span { PathSpan span = Spans[idx.b]; return((idx.c == 0) ? span.curve.Start : span.curve.End); } }
public virtual void SortAndAppendTo(Vector2d startPoint, IFillPathScheduler2d scheduler) { var saveHint = scheduler.SpeedHint; CurrentPosition = startPoint; List <Index3i> sorted = find_short_path_v1(startPoint); foreach (Index3i idx in sorted) { FillCurveSet2d paths = new FillCurveSet2d(); SpeedHint pathHint = SpeedHint.Default; if (idx.a == 0) { // loop PathLoop loop = Loops[idx.b]; pathHint = loop.speedHint; if (idx.c != 0) { var rolled = loop.loop.RollToVertex(idx.c); paths.Append(rolled); CurrentPosition = rolled.Entry; } else { paths.Append(loop.loop); CurrentPosition = loop.loop.Entry; } } else { // span PathSpan span = Spans[idx.b]; if (idx.c == 1) { span.curve = span.curve.Reversed(); } paths.Append(span.curve); CurrentPosition = span.curve.Exit; pathHint = span.speedHint; } scheduler.SpeedHint = pathHint; scheduler.AppendCurveSets(new List <FillCurveSet2d>() { paths }); } scheduler.SpeedHint = saveHint; }
protected virtual Vector2d get_point(Index3i idx) { if (idx.a == 0) { // loop PathLoop loop = Loops[idx.b]; return(loop.loop.GetSegment2d(idx.c).Center); } else { // span PathSpan span = Spans[idx.b]; // [GDM] Reversed this logic 2019.10.23; by my thinking: // - if the curve ISN'T reversed, the exit point should be the end // - if the curve IS reversed, the exit point should be the start return((idx.c == 0) ? span.curve.Entry : span.curve.Exit); } }
Index3i find_nearest(Index3i from, HashSet <Index2i> remaining) { Vector2d pt = get_point(from); double nearest_sqr = double.MaxValue; Index3i nearest_idx = Index3i.Max; foreach (Index2i idx in remaining) { if (idx.a == 0) // loop { PathLoop loop = Loops[idx.b]; int iNearSeg; double nearSegT; double d_sqr = loop.curve.DistanceSquared(pt, out iNearSeg, out nearSegT); if (d_sqr < nearest_sqr) { nearest_sqr = d_sqr; nearest_idx = new Index3i(idx.a, idx.b, iNearSeg); } } else // span { PathSpan span = Spans[idx.b]; double start_d = span.curve.Start.DistanceSquared(pt); if (start_d < nearest_sqr) { nearest_sqr = start_d; nearest_idx = new Index3i(idx.a, idx.b, 0); } double end_d = span.curve.End.DistanceSquared(pt); if (end_d < nearest_sqr) { nearest_sqr = end_d; nearest_idx = new Index3i(idx.a, idx.b, 1); } } } return(nearest_idx); }
protected virtual Index3i find_nearest(Index3i from, HashSet <Index2i> remaining) { Vector2d pt = get_point(from); double nearest_sqr = double.MaxValue; Index3i nearest_idx = Index3i.Max; foreach (Index2i idx in remaining) { if (idx.a == 0) { // loop PathLoop loop = Loops[idx.b]; double d_sqr = loop.loop.FindClosestElementToPoint(pt, out var location); if (d_sqr < nearest_sqr) { nearest_sqr = d_sqr; nearest_idx = new Index3i(idx.a, idx.b, location.Index); } } else { // span PathSpan span = Spans[idx.b]; double start_d = span.curve.Entry.DistanceSquared(pt); if (start_d < nearest_sqr) { nearest_sqr = start_d; nearest_idx = new Index3i(idx.a, idx.b, 0); } double end_d = span.curve.Exit.DistanceSquared(pt); if (end_d < nearest_sqr) { nearest_sqr = end_d; nearest_idx = new Index3i(idx.a, idx.b, 1); } } } return(nearest_idx); }