private static float MeasureClearance(out bool skip, Ray2 sideLine, Vector2 point, LineSegment2 edgeSeg, Vector2 edgeDir) { var startSegPoint = edgeSeg.ClosestPoint(point); var sidePoint = new Ray2(startSegPoint, edgeDir.Perpendicular()).Intersects(sideLine); if (!sidePoint.HasValue) { skip = true; return(0); } skip = false; return(sidePoint.Value.DistanceAlongA); }
public static IEnumerable <Section> Sections(this IReadOnlyList <Vector2> outer, float width, out Vector2[] innerArr, out IReadOnlyList <IReadOnlyList <Vector2> > corners) { Contract.Requires(outer != null); Contract.Requires(width > 0); Contract.Ensures(Contract.Result <IEnumerable <Section> >() != null); innerArr = outer.Shrink(width, 1).ToArray(); //Sanity check if shrinking has deleted the room! if (innerArr.Length == 0) { corners = new IReadOnlyList <Vector2> [0]; return(Array.Empty <Section>()); } //Create a place to put the results var results = new List <Section>(innerArr.Length * 2); //loop over segments of inner array //inner array length is always <= outer array length for (var i = 0; i < innerArr.Length; i++) { var a = innerArr[i]; var b = innerArr[(i + 1) % innerArr.Length]; var innerSegment = new LineSegment2(a, b); //find a parallel segment which we can project the inner segment onto completely float aT; float bT; var outerSegmentIndex = FindOuterSegment(innerSegment, width, outer, out aT, out bT); if (outerSegmentIndex == -1) { continue; } var outerSegment = new LineSegment2(outer[outerSegmentIndex], outer[(outerSegmentIndex + 1) % outer.Count]); //Clamp into the valid range var adjustedAT = aT.Clamp(0, 1); var adjustedBT = bT.Clamp(0, 1); //Calculate the locations of the adjusted points var aP = outerSegment.LongLine.PointAlongLine(adjustedAT); var bP = outerSegment.LongLine.PointAlongLine(adjustedBT); //Now adjust the inner points to match the adjusted outer points var innerStart = innerSegment.Start; if (Math.Abs(adjustedAT - aT) > float.Epsilon) { innerStart = innerSegment.ClosestPoint(aP); } var innerEnd = innerSegment.End; if (Math.Abs(adjustedBT - bT) > float.Epsilon) { innerEnd = innerSegment.ClosestPoint(bP); } results.Add(new Section(innerEnd, innerStart, aP, bP)); } //Calculate corner sections corners = CalculateCorners(outer, width, results); return(results); }