From 106daedf755aa60be4ff257b6965e6f32294d98f Mon Sep 17 00:00:00 2001 From: scurest Date: Tue, 21 Feb 2023 19:00:29 -0600 Subject: [PATCH] graphics: fix for anti-parallel line segments (#1894) Handle the case when a line doubles back on itself, eg love.graphics.setLineJoin("bevel") love.graphics.line({ 180, 400, 200, 400, 100, 400 }) --- src/modules/graphics/Polyline.cpp | 33 +++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/modules/graphics/Polyline.cpp b/src/modules/graphics/Polyline.cpp index 6861e759f..5ce7e2a2f 100644 --- a/src/modules/graphics/Polyline.cpp +++ b/src/modules/graphics/Polyline.cpp @@ -188,11 +188,26 @@ void MiterJoinPolyline::renderEdge(std::vector &anchors, std::vector 0) + if (fabs(det) / (segmentLength * newSegmentLength) < LINES_PARALLEL_EPS) { // lines parallel, compute as u1 = q + ns * w/2, u2 = q - ns * w/2 normals.push_back(segmentNormal); normals.push_back(-segmentNormal); + + if (Vector2::dot(segment, newSegment) < 0) + { + // line reverses direction; because the normal flips, the + // triangle strip would twist here, so insert a zero-size + // quad to contain the twist + // ____.___.____ + // | |\ /| | + // p q X q r + // |____|/ \|____| + anchors.push_back(pointA); + anchors.push_back(pointA); + normals.push_back(-segmentNormal); + normals.push_back(segmentNormal); + } } else { @@ -233,14 +248,24 @@ void BevelJoinPolyline::renderEdge(std::vector &anchors, std::vector 0) + if (fabs(det) / (segmentLength * newSegmentLength) < LINES_PARALLEL_EPS) { // lines parallel, compute as u1 = q + ns * w/2, u2 = q - ns * w/2 Vector2 newSegmentNormal = newSegment.getNormal(halfWidth / newSegmentLength); anchors.push_back(pointA); anchors.push_back(pointA); - normals.push_back(newSegmentNormal); - normals.push_back(-newSegmentNormal); + normals.push_back(segmentNormal); + normals.push_back(-segmentNormal); + + if (Vector2::dot(segment, newSegment) < 0) + { + // line reverses direction; same as for miter + anchors.push_back(pointA); + anchors.push_back(pointA); + normals.push_back(-segmentNormal); + normals.push_back(segmentNormal); + } + segment = newSegment; segmentLength = newSegmentLength; segmentNormal = newSegmentNormal;