Skip to content

Commit 6b42ee3

Browse files
Use scale appropriate tolerances
1 parent f41dc74 commit 6b42ee3

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

src/ImageSharp.Drawing/Shapes/PolygonGeometry/PolygonClipper.cs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ namespace SixLabors.ImageSharp.Drawing.Shapes.PolygonGeometry;
2121
/// </remarks>
2222
internal sealed class PolygonClipper
2323
{
24+
private const float MinimumDistanceThreshold = 1e-6f;
25+
private const float MinimumAreaThreshold = 1e-6f;
26+
private const float JoinYTolerance = 1e-6f;
27+
private const float JoinDistanceSqrdThreshold = 1e-12f;
28+
2429
private BooleanOperation clipType;
2530
private ClipperFillRule fillRule;
2631
private Active actives; // Head of the active edge list
@@ -1062,7 +1067,8 @@ private void ProcessHorzJoins()
10621067
private static bool PtsReallyClose(Vector2 pt1, Vector2 pt2)
10631068
{
10641069
Vector2 delta = Vector2.Abs(pt1 - pt2);
1065-
return delta.X < 1e-6f && delta.Y < 1e-6f;
1070+
return delta.X < MinimumDistanceThreshold &&
1071+
delta.Y < MinimumDistanceThreshold;
10661072
}
10671073

10681074
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -1125,16 +1131,16 @@ private void DoSplitOp(OutRec outrec, OutPt splitOp)
11251131
prevOp.Point, splitOp.Point, splitOp.Next.Point, nextNextOp.Point, out Vector2 ip);
11261132

11271133
float area1 = Area(prevOp);
1128-
float absArea1 = Math.Abs(area1);
1134+
float absArea1 = MathF.Abs(area1);
11291135

1130-
if (absArea1 < 2)
1136+
if (absArea1 < MinimumAreaThreshold)
11311137
{
11321138
outrec.Pts = null;
11331139
return;
11341140
}
11351141

11361142
float area2 = AreaTriangle(ip, splitOp.Point, splitOp.Next.Point);
1137-
float absArea2 = Math.Abs(area2);
1143+
float absArea2 = MathF.Abs(area2);
11381144

11391145
// de-link splitOp and splitOp.next from the path
11401146
// while inserting the intersection point
@@ -1160,7 +1166,7 @@ private void DoSplitOp(OutRec outrec, OutPt splitOp)
11601166
// So the only way for these areas to have the same sign is if
11611167
// the split triangle is larger than the path containing prevOp or
11621168
// if there's more than one self=intersection.
1163-
if (absArea2 > 1 && (absArea2 > absArea1 || ((area2 > 0) == (area1 > 0))))
1169+
if (absArea2 > MinimumAreaThreshold && (absArea2 > absArea1 || ((area2 > 0) == (area1 > 0))))
11641170
{
11651171
OutRec newOutRec = this.NewOutRec();
11661172
newOutRec.Owner = outrec.Owner;
@@ -3022,15 +3028,15 @@ private void CheckJoinLeft(Active e, Vector2 pt, bool checkCurrX = false)
30223028
}
30233029

30243030
// Avoid trivial joins
3025-
if ((pt.Y < e.Top.Y + 2 || pt.Y < prev.Top.Y + 2)
3031+
if ((pt.Y < e.Top.Y + JoinYTolerance || pt.Y < prev.Top.Y + JoinYTolerance)
30263032
&& ((e.Bot.Y > pt.Y) || (prev.Bot.Y > pt.Y)))
30273033
{
30283034
return;
30293035
}
30303036

30313037
if (checkCurrX)
30323038
{
3033-
if (PolygonClipperUtilities.PerpendicDistFromLineSqrd(pt, prev.Bot, prev.Top) > 0.25)
3039+
if (PolygonClipperUtilities.PerpendicDistFromLineSqrd(pt, prev.Bot, prev.Top) > JoinDistanceSqrdThreshold)
30343040
{
30353041
return;
30363042
}
@@ -3077,15 +3083,15 @@ private void CheckJoinRight(Active e, Vector2 pt, bool checkCurrX = false)
30773083
}
30783084

30793085
// Avoid trivial joins
3080-
if ((pt.Y < e.Top.Y + 2 || pt.Y < next.Top.Y + 2)
3086+
if ((pt.Y < e.Top.Y + JoinYTolerance || pt.Y < next.Top.Y + JoinYTolerance)
30813087
&& ((e.Bot.Y > pt.Y) || (next.Bot.Y > pt.Y)))
30823088
{
30833089
return;
30843090
}
30853091

30863092
if (checkCurrX)
30873093
{
3088-
if (PolygonClipperUtilities.PerpendicDistFromLineSqrd(pt, next.Bot, next.Top) > 0.25)
3094+
if (PolygonClipperUtilities.PerpendicDistFromLineSqrd(pt, next.Bot, next.Top) > JoinDistanceSqrdThreshold)
30893095
{
30903096
return;
30913097
}

0 commit comments

Comments
 (0)