/// <summary> /// Average extruded points of a segment to an intersection point based on fraction of how far along the segment the intersection happened. /// Averages UVs directly. /// </summary> /// <param name="first">First point</param> /// <param name="second">Second point</param> /// <param name="fractionOfSecond">From of the section point to be used in the average</param> /// <param name="otherOriginalLineIndex1">Additional original line index to be referred to by the intersection point.</param> /// <param name="otherOriginalLineIndex2">Additional original line index to be referred to by the intersection point.</param> private static IntersectionPoint AverageExtrudedPointsToIntersection(ExtrudedPointUV first, ExtrudedPointUV second, float fractionOfSecond, int otherOriginalLineIndex1, int otherOriginalLineIndex2) { var averagedLinePoint = new LinePointUV(first).AverageWith(new LinePointUV(second), fractionOfSecond); var extrudedPoint = new ExtrudedPointUV(averagedLinePoint, first.LinePointSegmentIndex, second.LinePointSegmentIndex2); var extrudedPointOtherIndices = extrudedPoint; extrudedPointOtherIndices.LinePointSegmentIndex = otherOriginalLineIndex1; extrudedPointOtherIndices.LinePointSegmentIndex2 = otherOriginalLineIndex2; return(new IntersectionPoint(extrudedPoint, extrudedPoint, extrudedPointOtherIndices)); }
/// <summary> /// Gets the extruded subspace of points with v parameter set appropriately to direction of hte line compared to extrusion. /// </summary> /// <param name="originalLineSegments">List of line points with segments connecting to the next point in the line.</param> /// <param name="lastLinePoint">The final line point.</param> /// <param name="extrusionAmount">The extrusion amount.</param> /// <param name="parameterShift">The amount to shift the original line point parameters by when constructing the extruded points.</param> /// <param name="isReversed">Whether line point indices associated with extruded points should be reversed.</param> private static List <ExtrudedPointUV> GetExtrudedSubspaceAndUvFromSegmentIntersections(List <LinePointUVAndSegment> originalLineSegments, LinePointUV lastLinePoint, float extrusionAmount, float parameterShift, bool isReversed) { var extrudedSubspace = GetExtrudedSubspace_Points_SegmentIntersections(originalLineSegments, lastLinePoint, extrusionAmount, parameterShift, isReversed, includeLast: true); float uv_vparameter = isReversed ? 0f : 1f; for (int i = 0; i < extrudedSubspace.Count; i++) { ExtrudedPointUV extrudedPointUV = extrudedSubspace[i]; extrudedPointUV.UV = new Vector2(extrudedSubspace[i].UV.x, uv_vparameter); extrudedSubspace[i] = extrudedPointUV; } return(extrudedSubspace); }
/// <summary> /// Gets the smallest difference between parameter value of the given extruded point and the parameters of intersection points. /// </summary> /// <param name="point">The extruded point</param> /// <param name="intersectionPoints">The intersection points</param> private static float SmallestParameterDifference(ExtrudedPointUV point, IList <IntersectionPoint> intersectionPoints) { float minDist = float.PositiveInfinity; var parameter = point.Parameter; for (int i = 0; i < intersectionPoints.Count; i++) { var intersectionParameter = intersectionPoints[i].Parameter; var dist = Mathf.Abs(parameter - intersectionParameter); if (dist < minDist) { minDist = dist; } } return(minDist); }
/// <summary> /// Returns the extruded point which has the largest distance parameter-wise to the parameters of a set of intersection points. /// </summary> /// <param name="extrudedPoints">Extruded points</param> /// <param name="intersectionPoints">Intersection points</param> private static ExtrudedPointUV PointOfLargestParameterDifference(IList <ExtrudedPointUV> extrudedPoints, IList <IntersectionPoint> intersectionPoints) { float maxDist = float.NegativeInfinity; ExtrudedPointUV point = new ExtrudedPointUV(); for (int i = 0; i < extrudedPoints.Count; i++) { var currentChunkPoint = extrudedPoints[i]; var dist = SmallestParameterDifference(currentChunkPoint, intersectionPoints); if (dist > maxDist) { maxDist = dist; point = currentChunkPoint; } } return(point); }
/// <summary> /// Atempt to add naively-extruded points when the extrusion from two neighbouring segments would intersect outside of those extruded segments. /// </summary> /// <param name="linePointAndForwardSegment">First segment.</param> /// <param name="previousLinePointAndForwardSegment">Previous segment.</param> /// <param name="lineSegmentIndexToAssign">Line segment index to assign the extruded point coming from.</param> /// <param name="extrusionAmount">The extrusion amount.</param> /// <param name="extrudedLinePoints">The list of all extruded line points.</param> /// <param name="findParameter">Delegate for determining altered point parameter.</param> /// <param name="extrusionIntersectionDistanceAlongTangents">The extrusion intersection distance along segment tangent directions.</param> private static void AttemptAddNaiveExtrudedPointsWhenTheirExtrudedSegmentsDoNotIntersect(LinePointUVAndSegment linePointAndForwardSegment, LinePointUVAndSegment previousLinePointAndForwardSegment, int lineSegmentIndexToAssign, float extrusionAmount, List <ExtrudedPointUV> extrudedLinePoints, GetShiftedScaledParameter findParameter, float extrusionIntersectionDistanceAlongTangents) { bool intersectionOccursOutOfBothSegments = extrusionIntersectionDistanceAlongTangents >= Mathf.Max(previousLinePointAndForwardSegment.SegmentLength, linePointAndForwardSegment.SegmentLength); if (intersectionOccursOutOfBothSegments) { //Nothing to do here, since any additional points will not contribute to any chunks that are not too close to the original line. } else { var extrudedFromCenterPointPreviousSegmentNormal = new ExtrudedPointUV(linePointAndForwardSegment.LinePoint, findParameter(linePointAndForwardSegment.Parameter), previousLinePointAndForwardSegment.SegmentNormal, extrusionAmount, lineSegmentIndexToAssign - 1);//Previous segment's index extrudedLinePoints.Add(extrudedFromCenterPointPreviousSegmentNormal); var extrudedFromCenterPointCurrentSegmentNormal = new ExtrudedPointUV(linePointAndForwardSegment.LinePoint, findParameter(linePointAndForwardSegment.Parameter), linePointAndForwardSegment.SegmentNormal, extrusionAmount, lineSegmentIndexToAssign);//Current segment's index extrudedLinePoints.Add(extrudedFromCenterPointCurrentSegmentNormal); //NB Here we are just adding the 'naive' points without computing the intersection, and relying on the overall intersection algorithm to take care of the rest. } }
/// <summary> /// Gets the points corresponding to the extruded subspace due to extruded segment-by-segment intersection. /// </summary> /// <param name="linePointsAndForwardSegments">List of line points with segments connecting to the next point in the line.</param> /// <param name="lastLinePoint">The final line point.</param> /// <param name="extrusionAmount">The extrusion amount.</param> /// <param name="parameterShift">The amount to shift the original line point parameters by when constructing the extruded points.</param> /// <param name="reverseIndices">Whether line point indices associated with extruded points should be reversed.</param> /// <param name="includeLast">If final segment should be included in the extrusion.</param> private static List <ExtrudedPointUV> GetExtrudedSubspace_Points_SegmentIntersections(List <LinePointUVAndSegment> linePointsAndForwardSegments, LinePointUV lastLinePoint, float extrusionAmount, float parameterShift, bool reverseIndices, bool includeLast) { var extrudedLinePoints = new List <ExtrudedPointUV>(); GetShiftedScaledParameter findParameter = (originalPointParameter) => parameterShift + originalPointParameter; var numSegments = linePointsAndForwardSegments.Count; if (numSegments >= 2) { int endCount = includeLast ? numSegments : numSegments - 1; for (int i = 0; i <= endCount; i++) { if (i == 0) { int lineSegmentIndex = 0; var linePointAndSegment = linePointsAndForwardSegments[lineSegmentIndex]; int extrudedPointIndexOnOriginalLine = reverseIndices ? numSegments : 0; var extrudedStartPoint = new ExtrudedPointUV(linePointAndSegment.LinePoint, findParameter(linePointAndSegment.Parameter), linePointAndSegment.SegmentNormal, extrusionAmount, extrudedPointIndexOnOriginalLine); extrudedLinePoints.Add(extrudedStartPoint); } else if (i == numSegments) { int lineSegmentIndex = numSegments - 1; var lastLinePointAndSegment = linePointsAndForwardSegments[lineSegmentIndex]; int extrudedPointIndexOnOriginalLine = reverseIndices ? 0 : numSegments; var extrudedEndPoint = new ExtrudedPointUV(lastLinePoint, findParameter(lastLinePoint.Parameter), lastLinePointAndSegment.SegmentNormal, extrusionAmount, extrudedPointIndexOnOriginalLine); extrudedLinePoints.Add(extrudedEndPoint); } else { var indexToAssign = reverseIndices ? numSegments - i : i; var linePointAndSegment = linePointsAndForwardSegments[i]; var nextLinePoint = i + 1 < numSegments ? linePointsAndForwardSegments[i + 1].LinePoint : lastLinePoint; AddPointExtrusionFromPreviousNextSegments(linePointAndSegment, linePointsAndForwardSegments[i - 1], nextLinePoint, indexToAssign, extrusionAmount, extrudedLinePoints, findParameter); } } } return(extrudedLinePoints); }