Skip to content

Commit

Permalink
Keep non-intersection subpaths as-in, without flattening, but X-monot…
Browse files Browse the repository at this point in the history
…one, see #290
  • Loading branch information
tdewolff committed Apr 19, 2024
1 parent 03a00b7 commit 28ea1b5
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 11 deletions.
29 changes: 18 additions & 11 deletions path_intersection.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,8 @@ func (p *Path) Settle(fillRule FillRule) *Path {

// zp is an list of even length where each ith intersections is a pseudo-vertex of the ith+len/2
zp, zq := pathIntersections(p, nil, false, false)
if 0 < len(zp) {
ps = p.Split() // otherwise, keep unflattened path
}
psOrig := ps
ps = p.Split()
//for i, z := range zp {
// fmt.Println(i, z)
//}
Expand Down Expand Up @@ -246,6 +245,20 @@ func (p *Path) Settle(fillRule FillRule) *Path {
continue // consists solely of MoveTo and Close
}

j1 := j0
for _, z := range zp[j0:] {
if segs[i] <= z.Seg {
break
}
j1++
}
hasIntersections := j0 != j1

if !hasIntersections {
// use unflattened path when subpath has no intersections, but make sure it is XMonotone
pi = psOrig[i].XMonotone()
}

// Find the left-most path segment coordinate for each subpath, we thus know that to the
// right of the coordinate the path is filled and that it is an outer ring. If the path
// runs counter clock-wise at the coordinate, the LHS is filled, otherwise it runs
Expand Down Expand Up @@ -282,14 +295,7 @@ func (p *Path) Settle(fillRule FillRule) *Path {
parentWindings := leftmostWindings(i, ps, pos.X, pos.Y)

// find the intersections for the subpath
j1 := j0
for _, z := range zp[j0:] {
if segs[i] <= z.Seg {
break
}
j1++
}
if j0 == j1 {
if !hasIntersections {
// subpath has no intersections
winding := 1
if !ccw {
Expand Down Expand Up @@ -402,6 +408,7 @@ func (p *Path) Settle(fillRule FillRule) *Path {
}
ring++
}
// TODO: undo X-Monotone to give a more optimal path?
return R.Append(simple).Append(open)
}

Expand Down
1 change: 1 addition & 0 deletions path_intersection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,7 @@ func TestPathSettle(t *testing.T) {
//{NonZero, "L2 0L2 2L0 2L0 1L-1 2L-2 2L-1 2L0 1z", ""}, // parallel left-most endpoint
//{NonZero, "L0 1L-1 2L0 1z", ""}, // all parallel
{NonZero, "M1 0L1 2.1L1.1 2.1L1.1 2L0 2L0 3L2 3L2 1L5 1L5 2L5.1 2.1L5.1 1.9L5 2L5 3L6 3L6 0z", "M5 1L2 1L2 3L0 3L0 2L1 2L1 0L6 0L6 3L5 3z"}, // CCW open first leg for CW path
{Positive, "M4.428086304186892 0.375A0.375 0.375 0 0 1 4.428086304186892 -0.375L6.428086304186892 -0.375A0.375 0.375 0 0 1 6.428086304186892 0.375z", "M4.428086304186892 0.375A0.375 0.375 0 0 1 4.053086304186892 4.592425496802568e-17A0.375 0.375 0 0 1 4.428086304186892 -0.375L6.428086304186892 -0.375A0.375 0.375 0 0 1 6.803086304186892 -9.184850993605136e-17A0.375 0.375 0 0 1 6.428086304186892 0.375z"}, // two arcs as leftmost point

// example from Subramaniam's thesis
{NonZero, "L5.5 10L4.5 10L9 1.5L1 8L9 8L1.6 2L3 1L5 7L8 0z", "M3.349892008639309 6.090712742980562L0 0L8 0L6.479452054794521 3.547945205479452L9 1.5L6.592324805339266 6.047830923248053L9 8L5.5588235294117645 8L4.990463215258855 9.073569482288828L4.3999999999999995 8L1 8L3.349892008639309 6.090712742980561zM3.9753086419753085 3.9259259259259265L3 1L1.6 2L3.975308641975309 3.925925925925927zM4.990463215258855 9.073569482288828L5.5 10L4.5 10L4.990463215258855 9.073569482288828z"},
Expand Down
Binary file modified resources/preview/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 28ea1b5

Please # to comment.