Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.

Commit a37ae27

Browse files
committed
[core] fix rendering 180° line joins
1 parent f1c3cfb commit a37ae27

File tree

3 files changed

+14
-6
lines changed

3 files changed

+14
-6
lines changed

mapbox-gl-js

Submodule mapbox-gl-js updated 89 files

src/mbgl/programs/line_program.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct LineAttributes : gl::Attributes<
4949
static_cast<int16_t>((p.y * 2) | t.y)
5050
},
5151
{
52-
// add 128 to store an byte in an unsigned byte
52+
// add 128 to store a byte in an unsigned byte
5353
static_cast<uint8_t>(::round(extrudeScale * e.x) + 128),
5454
static_cast<uint8_t>(::round(extrudeScale * e.y) + 128),
5555

src/mbgl/renderer/line_bucket.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,14 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
139139

140140
// Determine the normal of the join extrusion. It is the angle bisector
141141
// of the segments between the previous line and the next line.
142-
Point<double> joinNormal = util::unit(*prevNormal + *nextNormal);
142+
// In the case of 180° angles, the prev and next normals cancel each other out:
143+
// prevNormal + nextNormal = (0, 0), its magnitude is 0, so the unit vector would be
144+
// undefined. In that case, we're keeping the joinNormal at (0, 0), so that the cosHalfAngle
145+
// below will also become 0 and miterLength will become Infinity.
146+
Point<double> joinNormal = *prevNormal + *nextNormal;
147+
if (joinNormal.x != 0 || joinNormal.y != 0) {
148+
joinNormal = util::unit(joinNormal);
149+
}
143150

144151
/* joinNormal prevNormal
145152
* ↖ ↑
@@ -155,7 +162,8 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
155162
// Find the cosine of the angle between the next and join normals
156163
// using dot product. The inverse of that is the miter length.
157164
const double cosHalfAngle = joinNormal.x * nextNormal->x + joinNormal.y * nextNormal->y;
158-
const double miterLength = cosHalfAngle != 0 ? 1 / cosHalfAngle: 1;
165+
const double miterLength =
166+
cosHalfAngle != 0 ? 1 / cosHalfAngle : std::numeric_limits<double>::infinity();
159167

160168
const bool isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevCoordinate && nextCoordinate;
161169

@@ -189,7 +197,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
189197

190198
if (currentJoin == LineJoinType::Bevel) {
191199
// The maximum extrude length is 128 / 63 = 2 times the width of the line
192-
// so if miterLength >= 2 we need to draw a different type of bevel where.
200+
// so if miterLength >= 2 we need to draw a different type of bevel here.
193201
if (miterLength > 2) {
194202
currentJoin = LineJoinType::FlipBevel;
195203
}
@@ -216,7 +224,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
216224

217225
if (miterLength > 100) {
218226
// Almost parallel lines
219-
joinNormal = *nextNormal;
227+
joinNormal = *nextNormal * -1.0;
220228
} else {
221229
const double direction = prevNormal->x * nextNormal->y - prevNormal->y * nextNormal->x > 0 ? -1 : 1;
222230
const double bevelLength = miterLength * util::mag(*prevNormal + *nextNormal) /

0 commit comments

Comments
 (0)