Skip to content

Commit 75987a1

Browse files
committed
Fix bug in windings for open paths, fixes #346
1 parent 21cb983 commit 75987a1

File tree

3 files changed

+12
-5
lines changed

3 files changed

+12
-5
lines changed

path.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import (
1010
"strings"
1111

1212
"github.com/srwiley/scanx"
13-
"github.com/tdewolff/parse/v2/strconv"
1413
"golang.org/x/image/math/fixed"
1514
"golang.org/x/image/vector"
15+
16+
"github.com/tdewolff/parse/v2/strconv"
1617
)
1718

1819
// Tolerance is the maximum deviation from the original path in millimeters when e.g. flatting. Used for flattening in the renderers, font decorations, and path intersections.
@@ -872,7 +873,7 @@ func windings(zs []Intersection) (int, bool) {
872873
if !z.Same {
873874
n += d
874875
}
875-
} else {
876+
} else if i+1 < len(zs) {
876877
same := z.Same || zs[i+1].Same
877878
if !same {
878879
if z.Into() == zs[i+1].Into() {

path_intersection.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ import (
1616
var BentleyOttmannEpsilon = 1e-8
1717

1818
// RayIntersections returns the intersections of a path with a ray starting at (x,y) to (∞,y).
19-
// An intersection is tangent only when it is at (x,y), i.e. the start of the ray. Intersections
20-
// are sorted along the ray. This function runs in O(n) with n the number of path segments.
19+
// An intersection is tangent only when it is at (x,y), i.e. the start of the ray. The parameter T
20+
// along the ray is zero at the start but NaN otherwise. Intersections are sorted along the ray.
21+
// This function runs in O(n) with n the number of path segments.
2122
func (p *Path) RayIntersections(x, y float64) []Intersection {
2223
var start, end Point
2324
var zs []Intersection

path_test.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ import (
1010
"testing"
1111

1212
"github.com/srwiley/scanx"
13-
"github.com/tdewolff/test"
1413
"golang.org/x/image/vector"
1514
"gonum.org/v1/plot"
1615
"gonum.org/v1/plot/plotter"
1716
"gonum.org/v1/plot/vg"
1817
"gonum.org/v1/plot/vg/draw"
18+
19+
"github.com/tdewolff/test"
1920
)
2021

2122
func TestPathEmpty(t *testing.T) {
@@ -252,6 +253,10 @@ func TestPathCrossingsWindings(t *testing.T) {
252253
{"L10 10L10 -10L-10 10L20 40L20 -40L-10 -10z", Point{0.0, 0.0}, 2, 0, true},
253254
{"L10 10L10 -10L-10 10L20 40L20 -40L-10 -10z", Point{1.0, 0.0}, 2, -2, false},
254255
{"L10 10L10 -10L-10 10L20 40L20 -40L-10 -10z", Point{-1.0, 0.0}, 4, 0, false},
256+
257+
// bugs
258+
{"M0 35.43000000000029L0 385.82000000000016L11.819999999999709 397.6300000000001L185.03999999999996 397.6300000000001L188.97999999999956 393.7000000000003L196.85000000000036 385.8299999999999L196.85000000000036 19.68000000000029", Point{89.4930000000003, 19.68000000000019}, 0, 0, false}, // #346
259+
{"M0 35.43000000000029L0 385.82000000000016L11.819999999999709 397.6300000000001L185.03999999999996 397.6300000000001L188.97999999999956 393.7000000000003L196.85000000000036 385.8299999999999L196.85000000000036 19.68000000000029", Point{89.4930000000003, 20}, 1, -1, false}, // #346
255260
}
256261
for _, tt := range tts {
257262
t.Run(fmt.Sprint(tt.p, " at ", tt.pos), func(t *testing.T) {

0 commit comments

Comments
 (0)