@@ -63,14 +63,6 @@ public PolygonClipper()
6363 /// </summary>
6464 public bool ReverseSolution { get ; set ; }
6565
66- /// <summary>
67- /// Adds subject paths to the clipping operation.
68- /// Subject paths are the primary polygons being clipped.
69- /// </summary>
70- /// <param name="paths">The subject paths to add.</param>
71- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
72- public void AddSubject ( PathsF paths ) => this . AddPaths ( paths , ClippingType . Subject ) ;
73-
7466 /// <summary>
7567 /// Adds a single path to the clipping operation.
7668 /// </summary>
@@ -244,52 +236,13 @@ private void AddNewIntersectNode(Active ae1, Active ae2, float topY)
244236 // Adjust intersection point if it's outside the scanbeam bounds
245237 if ( ip . Y > this . currentBotY || ip . Y < topY )
246238 {
239+ // Clamp Y to scanbeam bounds
240+ ip . Y = ip . Y < topY ? topY : this . currentBotY ;
241+
242+ // Use the more vertical edge (smaller |Dx|) to compute X for numerical stability
247243 float absDx1 = MathF . Abs ( ae1 . Dx ) ;
248244 float absDx2 = MathF . Abs ( ae2 . Dx ) ;
249-
250- // For very steep edges, project the point onto the edge
251- // TODO: Check threshold here once we remove upscaling.
252- if ( absDx1 > 100 && absDx2 > 100 )
253- {
254- if ( absDx1 > absDx2 )
255- {
256- ip = PolygonClipperUtilities . GetClosestPtOnSegment ( ip , ae1 . Bot , ae1 . Top ) ;
257- }
258- else
259- {
260- ip = PolygonClipperUtilities . GetClosestPtOnSegment ( ip , ae2 . Bot , ae2 . Top ) ;
261- }
262- }
263- else if ( absDx1 > 100 )
264- {
265- ip = PolygonClipperUtilities . GetClosestPtOnSegment ( ip , ae1 . Bot , ae1 . Top ) ;
266- }
267- else if ( absDx2 > 100 )
268- {
269- ip = PolygonClipperUtilities . GetClosestPtOnSegment ( ip , ae2 . Bot , ae2 . Top ) ;
270- }
271- else
272- {
273- // Clamp Y to scanbeam bounds
274- if ( ip . Y < topY )
275- {
276- ip . Y = topY ;
277- }
278- else
279- {
280- ip . Y = this . currentBotY ;
281- }
282-
283- // Use the less steep edge to determine X
284- if ( absDx1 < absDx2 )
285- {
286- ip . X = TopX ( ae1 , ip . Y ) ;
287- }
288- else
289- {
290- ip . X = TopX ( ae2 , ip . Y ) ;
291- }
292- }
245+ ip . X = absDx1 < absDx2 ? TopX ( ae1 , ip . Y ) : TopX ( ae2 , ip . Y ) ;
293246 }
294247
295248 IntersectNode node = new ( ip , ae1 , ae2 ) ;
@@ -1107,9 +1060,10 @@ private void ProcessHorzJoins()
11071060
11081061 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
11091062 private static bool PtsReallyClose ( Vector2 pt1 , Vector2 pt2 )
1110-
1111- // TODO: Check scale once we can remove upscaling.
1112- => ( Math . Abs ( pt1 . X - pt2 . X ) < 2F ) && ( Math . Abs ( pt1 . Y - pt2 . Y ) < 2F ) ;
1063+ {
1064+ Vector2 delta = Vector2 . Abs ( pt1 - pt2 ) ;
1065+ return delta . X < 1e-6f && delta . Y < 1e-6f ;
1066+ }
11131067
11141068 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
11151069 private void CleanCollinear ( OutRec outrec )
0 commit comments