99
1010package poly
1111
12+ import (
13+ "math"
14+
15+ "github.com/richardwilkes/toolbox/v2/geom"
16+ "github.com/richardwilkes/toolbox/v2/xmath"
17+ )
18+
19+ const epsilon = 0.00001
20+
1221type horizontalEdgeStates int
1322
1423const (
@@ -42,12 +51,12 @@ type edgeNode struct {
4251 aboveState bundleState
4352 belowState bundleState
4453 which int
45- vertex Point
46- bot Point
47- top Point
48- xb Num
49- xt Num
50- dx Num
54+ vertex geom. Point
55+ bot geom. Point
56+ top geom. Point
57+ xb float32
58+ xt float32
59+ dx float32
5160 bundleAbove [2 ]bool
5261 bundleBelow [2 ]bool
5362 subjectSide bool
@@ -57,9 +66,9 @@ type edgeNode struct {
5766type sortedEdge struct {
5867 edge * edgeNode
5968 prev * sortedEdge
60- xb Num
61- xt Num
62- dx Num
69+ xb float32
70+ xt float32
71+ dx float32
6372}
6473
6574func (e * edgeNode ) insertInto (b * * edgeNode ) {
@@ -91,7 +100,7 @@ func (e *edgeNode) addEdgeToActiveEdgeTable(aet, prev *edgeNode) *edgeNode {
91100 return aet
92101}
93102
94- func (e * edgeNode ) addLocalMin (p * polygonNode , pt Point ) * polygonNode {
103+ func (e * edgeNode ) addLocalMin (p * polygonNode , pt geom. Point ) * polygonNode {
95104 v := & vertexNode {pt : pt }
96105 result := & polygonNode {
97106 left : v ,
@@ -104,7 +113,7 @@ func (e *edgeNode) addLocalMin(p *polygonNode, pt Point) *polygonNode {
104113 return result
105114}
106115
107- func (e * edgeNode ) buildIntersections (dy Num ) * intersection {
116+ func (e * edgeNode ) buildIntersections (dy float32 ) * intersection {
108117 var se * sortedEdge
109118 var it * intersection
110119 for edge := e ; edge != nil ; edge = edge .next {
@@ -115,7 +124,7 @@ func (e *edgeNode) buildIntersections(dy Num) *intersection {
115124 return it
116125}
117126
118- func (e * edgeNode ) addToSortedEdgeTable (se * * sortedEdge , it * * intersection , dy Num ) {
127+ func (e * edgeNode ) addToSortedEdgeTable (se * * sortedEdge , it * * intersection , dy float32 ) {
119128 if * se == nil {
120129 * se = & sortedEdge {
121130 edge : e ,
@@ -125,7 +134,7 @@ func (e *edgeNode) addToSortedEdgeTable(se **sortedEdge, it **intersection, dy N
125134 }
126135 } else {
127136 den := ((* se ).xt - (* se ).xb ) - (e .xt - e .xb )
128- if e .xt >= (* se ).xt || e .dx == (* se ).dx || den <= 0 {
137+ if e .xt >= (* se ).xt || e .dx == (* se ).dx || xmath . Abs ( den ) <= epsilon {
129138 * se = & sortedEdge {
130139 edge : e ,
131140 xb : e .xb ,
@@ -134,17 +143,17 @@ func (e *edgeNode) addToSortedEdgeTable(se **sortedEdge, it **intersection, dy N
134143 prev : * se ,
135144 }
136145 } else {
137- r := (e .xb - (* se ).xb ). Div ( den )
138- addIntersection (it , (* se ).edge , e , Point {
139- X : (* se ).xb + r . Mul ((( * se ).xt - (* se ).xb ) ),
140- Y : r . Mul ( dy ) ,
146+ r := (e .xb - (* se ).xb ) / den
147+ addIntersection (it , (* se ).edge , e , geom. Point {
148+ X : (* se ).xb + r * (( * se ).xt - (* se ).xb ),
149+ Y : r * dy ,
141150 })
142151 e .addToSortedEdgeTable (& (* se ).prev , it , dy )
143152 }
144153 }
145154}
146155
147- func addIntersection (it * * intersection , edge0 , edge1 * edgeNode , pt Point ) {
156+ func addIntersection (it * * intersection , edge0 , edge1 * edgeNode , pt geom. Point ) {
148157 switch {
149158 case * it == nil :
150159 * it = & intersection {
@@ -164,7 +173,7 @@ func addIntersection(it **intersection, edge0, edge1 *edgeNode, pt Point) {
164173 }
165174}
166175
167- func (e * edgeNode ) bundleFields (pt Point ) {
176+ func (e * edgeNode ) bundleFields (pt geom. Point ) {
168177 updated := e
169178 e .bundleAbove [e .which ] = e .top .Y != pt .Y
170179 e .bundleAbove [1 - e .which ] = false
@@ -174,7 +183,7 @@ func (e *edgeNode) bundleFields(pt Point) {
174183 nextEdge .bundleAbove [1 - nextEdge .which ] = false
175184 nextEdge .aboveState = unbundled
176185 if nextEdge .bundleAbove [nextEdge .which ] {
177- if updated .xb == nextEdge .xb && updated .dx == nextEdge .dx && updated .top .Y != pt .Y {
186+ if mostlyEqual ( updated .xb , nextEdge .xb ) && mostlyEqual ( updated .dx , nextEdge .dx ) && updated .top .Y != pt .Y {
178187 nextEdge .bundleAbove [nextEdge .which ] = nextEdge .bundleAbove [nextEdge .which ] != updated .bundleAbove [nextEdge .which ]
179188 nextEdge .bundleAbove [1 - nextEdge .which ] = updated .bundleAbove [1 - nextEdge .which ]
180189 nextEdge .aboveState = bundleHead
@@ -187,7 +196,7 @@ func (e *edgeNode) bundleFields(pt Point) {
187196 }
188197}
189198
190- func (e * edgeNode ) process (op clipOp , pt Point , inPoly * polygonNode ) (bPt Point , outPoly * polygonNode ) {
199+ func (e * edgeNode ) process (op clipOp , pt geom. Point , inPoly * polygonNode ) (bPt geom. Point , outPoly * polygonNode ) {
191200 bPt = pt
192201 outPoly = inPoly
193202 var parityClipRight , paritySubjRight bool
@@ -196,7 +205,7 @@ func (e *edgeNode) process(op clipOp, pt Point, inPoly *polygonNode) (bPt Point,
196205 }
197206 var horiz [2 ]horizontalEdgeStates
198207 var cf * polygonNode
199- px := Min
208+ px := float32 ( - math . MaxFloat32 )
200209 for edge := e ; edge != nil ; edge = edge .next {
201210 clipExistsState , clipExists := edge .existsState (clipping )
202211 subjExistsState , subjExists := edge .existsState (subject )
@@ -365,7 +374,7 @@ func (e *edgeNode) process(op clipOp, pt Point, inPoly *polygonNode) (bPt Point,
365374 return
366375}
367376
368- func (e * edgeNode ) deleteTerminatingEdges (pt Point , yt Num ) * edgeNode {
377+ func (e * edgeNode ) deleteTerminatingEdges (pt geom. Point , yt float32 ) * edgeNode {
369378 updated := e
370379 for edge := e ; edge != nil ; edge = edge .next {
371380 switch edge .top .Y {
@@ -390,13 +399,13 @@ func (e *edgeNode) deleteTerminatingEdges(pt Point, yt Num) *edgeNode {
390399 case yt :
391400 edge .xt = edge .top .X
392401 default :
393- edge .xt = edge .bot .X + edge .dx . Mul (yt - edge .bot .Y )
402+ edge .xt = edge .bot .X + edge .dx * (yt - edge .bot .Y )
394403 }
395404 }
396405 return updated
397406}
398407
399- func (e * edgeNode ) prepareForNextScanBeam (yt Num ) * edgeNode {
408+ func (e * edgeNode ) prepareForNextScanBeam (yt float32 ) * edgeNode {
400409 updated := e
401410 for edge := e ; edge != nil ; edge = edge .next {
402411 successorEdge := edge .successor
@@ -522,6 +531,10 @@ func (e *edgeNode) existsState(which int) (int, bool) {
522531 return state , e .bundleAbove [which ] || e .bundleBelow [which ]
523532}
524533
534+ func mostlyEqual (a , b float32 ) bool {
535+ return xmath .Abs (a - b ) <= epsilon
536+ }
537+
525538func calcNextHState (existsState int , current horizontalEdgeStates , parityRight bool ) horizontalEdgeStates {
526539 i := (existsState - 1 ) << 1
527540 if parityRight {
0 commit comments