Skip to content

Commit 81c2c67

Browse files
authored
Merge pull request #1365 from OpenGeoscience/mitering
fix: When lines reverse on themselves, mitering could be wrong
2 parents 90ae5d5 + d34e13c commit 81c2c67

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

src/webgl/lineFeature.vert

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,29 @@ void main(void)
6262
gl_Position = vec4(2.0, 2.0, 0.0, 1.0);
6363
return;
6464
}
65+
float lineLength = length(vec2(deltaCB.x, deltaCB.y / aspect)) / pixelWidth;
66+
// if lines reverse upon themselves and are not nearly the same length, skip
67+
// joins. This is a heuristic; the correct method would to be to pass some
68+
// sort of length of the adjacent line to the fragment renderer and adjust
69+
// which fragments are rendered, but this is much more complex.
70+
float abLimit = length(vec2(A.x - B.x, (A.y - B.y) / aspect)) / pixelWidth;
71+
float dcLimit = length(vec2(D.x - C.x, (D.y - C.y) / aspect)) / pixelWidth;
72+
if (abLimit >= lineLength - antialiasing - strokeWidth * 0.5 && abLimit <= lineLength + antialiasing + strokeWidth * 0.5) {
73+
abLimit = 0.0001;
74+
} else {
75+
if (abLimit < lineLength) abLimit = lineLength;
76+
abLimit = (strokeWidth - antialiasing) / (abLimit + antialiasing);
77+
if (abLimit < 0.0001) abLimit = 0.0001;
78+
if (abLimit > 0.1) abLimit = 0.1;
79+
}
80+
if (dcLimit >= lineLength - antialiasing - strokeWidth * 0.5 && dcLimit <= lineLength + antialiasing + strokeWidth * 0.5) {
81+
dcLimit = 0.0001;
82+
} else {
83+
if (dcLimit < lineLength) dcLimit = lineLength;
84+
dcLimit = (strokeWidth - antialiasing) / (dcLimit + antialiasing);
85+
if (dcLimit < 0.0001) dcLimit = 0.0001;
86+
if (dcLimit > 0.1) dcLimit = 0.1;
87+
}
6588
float angleCB = atan2(deltaCB.y, deltaCB.x * aspect);
6689
// values we need to pass along
6790
strokeColorVar = vec4(strokeColor, strokeOpacity);
@@ -78,7 +101,7 @@ void main(void)
78101
// by default, offset by the width and don't extend lines. Later,
79102
// calculate line extensions based on end cap and end join modes
80103
float yOffset = strokeWidth + antialiasing;
81-
if (vertex == 0 || vertex == 2) yOffset *= -1.0;
104+
if (vertex == 0) yOffset *= -1.0;
82105
yOffset += strokeWidth * offset;
83106
float xOffset = 0.0;
84107
// end caps
@@ -105,7 +128,7 @@ void main(void)
105128
angleABC = (mod(angleABC + 3.0 * PI, 2.0 * PI) - PI) / 2.0;
106129
cosABC = cos(angleABC); sinABC = sin(angleABC);
107130
// if this angle is close to flat, pass-through the join
108-
if (nearMode >= 4 && cosABC > 0.999999) {
131+
if (nearMode >= 4 && (cosABC > 0.999999 || cosABC < abLimit)) {
109132
nearMode = 3;
110133
}
111134
// miter, miter-clip
@@ -138,7 +161,7 @@ void main(void)
138161
angleBCD = (mod(angleBCD + 3.0 * PI, 2.0 * PI) - PI) / 2.0;
139162
cosBCD = cos(angleBCD); sinBCD = sin(angleBCD);
140163
// if this angle is close to flat, pass-through the join
141-
if (farMode >= 4 && cosBCD > 0.999999) {
164+
if (farMode >= 4 && (cosBCD > 0.999999 || cosBCD < dcLimit)) {
142165
farMode = 3;
143166
}
144167
// miter, miter-clip
@@ -159,8 +182,6 @@ void main(void)
159182
B.y + (xOffset * sin(angleCB) + yOffset * cos(angleCB)) * pixelWidth * aspect,
160183
B.z, 1.0);
161184
// store other values needed to determine which pixels to plot.
162-
float lineLength = length(vec2(deltaCB.x, deltaCB.y / aspect)) / pixelWidth;
163-
164185
if (vertex == 0 || vertex == 1) {
165186
subpos = vec4(xOffset, yOffset, lineLength - xOffset, strokeWidth);
166187
info = vec4(float(nearMode), float(farMode), offset, 0.0);

0 commit comments

Comments
 (0)