public static List <Vector2> Generate2DPolyBorderPointsCW(List <Vector2> cwPolyPoints, PolyBorderDirection borderDirection, float borderThickness, bool isClosed) { int numSegments = cwPolyPoints.Count - 1; if (isClosed && numSegments < 3) { return(new List <Vector2>()); } if (!isClosed && numSegments < 2) { return(new List <Vector2>()); } float borderWidth = borderThickness * PolyBorderDirToSign(borderDirection); List <Vector2> outputPoints = new List <Vector2>(cwPolyPoints.Count); if (isClosed) { Vector2 start0 = cwPolyPoints[0]; Vector2 end0 = cwPolyPoints[1]; Vector2 normal0 = (end0 - start0).GetNormal(); Vector2 start1 = cwPolyPoints[cwPolyPoints.Count - 2]; Vector2 end1 = cwPolyPoints[cwPolyPoints.Count - 1]; Vector2 normal1 = (end1 - start1).GetNormal(); float t; Vector2 rayDir = (end1 - start1).normalized; Vector2 rayOrigin = start1 + normal1 * borderWidth; if (PlaneMath.Raycast2D(rayOrigin, rayDir, normal0, start0 + normal0 * borderWidth, out t)) { outputPoints.Add(rayOrigin + rayDir * t); } else { outputPoints.Add(start0); } for (int segmentIndex = 0; segmentIndex < numSegments - 1; ++segmentIndex) { Vector2 segmentStart = cwPolyPoints[segmentIndex]; Vector2 segmentEnd = cwPolyPoints[segmentIndex + 1]; Vector2 prevOutputPt = outputPoints[segmentIndex]; Vector2 nextSegmentEnd = cwPolyPoints[segmentIndex + 2]; Vector2 nextPlaneNormal = (nextSegmentEnd - segmentEnd).GetNormal(); Vector2 ptOnNextPlane = nextSegmentEnd + nextPlaneNormal * borderWidth; rayDir = (segmentEnd - segmentStart).normalized; if (PlaneMath.Raycast2D(prevOutputPt, rayDir, nextPlaneNormal, ptOnNextPlane, out t)) { outputPoints.Add(prevOutputPt + rayDir * t); } } outputPoints.Add(outputPoints[0]); return(outputPoints); } else { Vector2 start = cwPolyPoints[0]; Vector2 end = cwPolyPoints[1]; Vector2 normal = (end - start).GetNormal(); outputPoints.Add(start + normal * borderWidth); float t; for (int segmentIndex = 0; segmentIndex < numSegments - 1; ++segmentIndex) { Vector2 segmentStart = cwPolyPoints[segmentIndex]; Vector2 segmentEnd = cwPolyPoints[segmentIndex + 1]; Vector2 prevOutputPt = outputPoints[segmentIndex]; Vector2 nextSegmentEnd = cwPolyPoints[segmentIndex + 2]; Vector2 nextPlaneNormal = (nextSegmentEnd - segmentEnd).GetNormal(); Vector2 ptOnNextPlane = nextSegmentEnd + nextPlaneNormal * borderWidth; Vector2 rayDir = (segmentEnd - segmentStart).normalized; if (PlaneMath.Raycast2D(prevOutputPt, rayDir, nextPlaneNormal, ptOnNextPlane, out t)) { outputPoints.Add(prevOutputPt + rayDir * t); } } start = cwPolyPoints[cwPolyPoints.Count - 2]; end = cwPolyPoints[cwPolyPoints.Count - 1]; normal = (end - start).GetNormal(); outputPoints.Add(end + normal * borderWidth); return(outputPoints); } }
public static List <Vector2> Generate2DPolyBorderQuadsCW(List <Vector2> cwPolyPoints, List <Vector2> cwBorderPts, PolyBorderDirection borderDirection, bool isClosed) { if (cwPolyPoints.Count != cwBorderPts.Count) { return(new List <Vector2>()); } int numQuads = cwPolyPoints.Count - 1; if (isClosed && numQuads < 3) { return(new List <Vector2>()); } if (!isClosed && numQuads < 2) { return(new List <Vector2>()); } var quadPoints = new List <Vector2>(numQuads * 4); if (borderDirection == PolyBorderDirection.Outward) { for (int ptIndex = 0; ptIndex < cwPolyPoints.Count - 1; ++ptIndex) { quadPoints.Add(cwPolyPoints[ptIndex]); quadPoints.Add(cwBorderPts[ptIndex]); quadPoints.Add(cwBorderPts[ptIndex + 1]); quadPoints.Add(cwPolyPoints[ptIndex + 1]); } } else { for (int ptIndex = 0; ptIndex < cwPolyPoints.Count - 1; ++ptIndex) { quadPoints.Add(cwPolyPoints[ptIndex]); quadPoints.Add(cwPolyPoints[ptIndex + 1]); quadPoints.Add(cwBorderPts[ptIndex + 1]); quadPoints.Add(cwBorderPts[ptIndex]); } } return(quadPoints); }
public static float PolyBorderDirToSign(PolyBorderDirection borderDirection) { return(borderDirection == PolyBorderDirection.Inward ? -1.0f : 1.0f); }