diff --git a/README.md b/README.md
index fbe434e..2e59dfd 100644
--- a/README.md
+++ b/README.md
@@ -61,7 +61,6 @@ StrokeOptions options = new()
LineJoin = LineJoin.Round,
LineCap = LineCap.Round,
MiterLimit = 4,
- InnerMiterLimit = 1.01,
ArcDetailScale = 1
};
diff --git a/src/PolygonClipper/InnerJoin.cs b/src/PolygonClipper/InnerJoin.cs
deleted file mode 100644
index 0785f01..0000000
--- a/src/PolygonClipper/InnerJoin.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-namespace SixLabors.PolygonClipper;
-
-///
-/// Specifies join styles for sharp interior angles.
-///
-public enum InnerJoin
-{
- ///
- /// Use an interior miter join.
- ///
- Miter = 0,
-
- ///
- /// Use an interior jag join.
- ///
- Jag = 1,
-
- ///
- /// Use an interior round join.
- ///
- Round = 2,
-
- ///
- /// Use an interior bevel join.
- ///
- Bevel = 3
-}
diff --git a/src/PolygonClipper/PolygonStroker.cs b/src/PolygonClipper/PolygonStroker.cs
index f210c35..8b57061 100644
--- a/src/PolygonClipper/PolygonStroker.cs
+++ b/src/PolygonClipper/PolygonStroker.cs
@@ -36,6 +36,9 @@ public sealed class PolygonStroker
private const double Pi = Math.PI;
private const double PiMul2 = Math.PI * 2D;
+ // The inner miter limit used to clamp joins on acute interior angles.
+ private const double InnerMiterLimit = 1.01D;
+
// Keep at most 2 warm instances per option-set (one active shape and one spare)
// to reduce churn without retaining many rarely reused configurations.
private const int MaxPooledStrokersPerOptions = 2;
@@ -79,10 +82,8 @@ public PolygonStroker(StrokeOptions options)
ArgumentNullException.ThrowIfNull(options);
this.NormalizeOutput = options.NormalizeOutput;
this.LineJoin = options.LineJoin;
- this.InnerJoin = options.InnerJoin;
this.LineCap = options.LineCap;
this.MiterLimit = options.MiterLimit;
- this.InnerMiterLimit = options.InnerMiterLimit;
this.ArcDetailScale = options.ArcDetailScale;
}
@@ -131,10 +132,8 @@ public StrokeOptionsKey(StrokeOptions options)
{
this.NormalizeOutput = options.NormalizeOutput;
this.LineJoin = options.LineJoin;
- this.InnerJoin = options.InnerJoin;
this.LineCap = options.LineCap;
this.MiterLimit = options.MiterLimit;
- this.InnerMiterLimit = options.InnerMiterLimit;
this.ArcDetailScale = options.ArcDetailScale;
}
@@ -142,23 +141,17 @@ public StrokeOptionsKey(StrokeOptions options)
public LineJoin LineJoin { get; }
- public InnerJoin InnerJoin { get; }
-
public LineCap LineCap { get; }
public double MiterLimit { get; }
- public double InnerMiterLimit { get; }
-
public double ArcDetailScale { get; }
public bool Equals(StrokeOptionsKey other)
=> this.NormalizeOutput == other.NormalizeOutput &&
this.LineJoin == other.LineJoin &&
- this.InnerJoin == other.InnerJoin &&
this.LineCap == other.LineCap &&
this.MiterLimit == other.MiterLimit &&
- this.InnerMiterLimit == other.InnerMiterLimit &&
this.ArcDetailScale == other.ArcDetailScale;
public override bool Equals(object? obj) => obj is StrokeOptionsKey other && this.Equals(other);
@@ -167,10 +160,8 @@ public override int GetHashCode()
=> HashCode.Combine(
this.NormalizeOutput,
this.LineJoin,
- this.InnerJoin,
this.LineCap,
this.MiterLimit,
- this.InnerMiterLimit,
this.ArcDetailScale);
}
@@ -266,11 +257,6 @@ public Polygon Stroke(Polygon polygon, double width)
///
public double MiterLimit { get; }
- ///
- /// Gets the inner miter limit used to clamp joins on acute interior angles.
- ///
- public double InnerMiterLimit { get; }
-
///
/// Gets the tessellation detail scale used for round joins and round caps.
/// Higher values produce more vertices and smoother curves.
@@ -287,11 +273,6 @@ public Polygon Stroke(Polygon polygon, double width)
///
public LineCap LineCap { get; }
- ///
- /// Gets the join style used for sharp interior angles.
- ///
- public InnerJoin InnerJoin { get; }
-
///
/// Gets a value indicating whether generated contours should be normalized by resolving
/// self-intersections and overlaps.
@@ -1123,52 +1104,12 @@ private void CalcJoin(ref StrokeVertexDistance v0, ref StrokeVertexDistance v1,
if (Math.Abs(cp) > double.Epsilon && (cp > 0D) == (strokeWidth > 0D))
{
double limit = Math.Min(len1, len2) / widthAbs;
- if (limit < this.InnerMiterLimit)
+ if (limit < InnerMiterLimit)
{
- limit = this.InnerMiterLimit;
+ limit = InnerMiterLimit;
}
- switch (this.InnerJoin)
- {
- default:
- // Bevel-like fallback for inner corners.
- this.AddPoint(v1.X + dx1, v1.Y - dy1);
- this.AddPoint(v1.X + dx2, v1.Y - dy2);
- break;
-
- case InnerJoin.Miter:
- this.CalcMiter(ref v0, ref v1, ref v2, dx1, dy1, dx2, dy2, LineJoin.MiterRevert, limit, 0D);
- break;
-
- case InnerJoin.Jag:
- case InnerJoin.Round:
- // If offsets are close enough, miter produces cleaner inner-corner output.
- Vertex offset1 = new(dx1, dy1);
- Vertex offset2 = new(dx2, dy2);
- double offsetDeltaSquared = Vertex.DistanceSquared(offset1, offset2);
- if (offsetDeltaSquared < len1 * len1 && offsetDeltaSquared < len2 * len2)
- {
- this.CalcMiter(ref v0, ref v1, ref v2, dx1, dy1, dx2, dy2, LineJoin.MiterRevert, limit, 0D);
- }
- else if (this.InnerJoin == InnerJoin.Jag)
- {
- // Jagged inner join inserts center vertex to preserve cusp.
- this.AddPoint(v1.X + dx1, v1.Y - dy1);
- this.AddPoint(v1.X, v1.Y);
- this.AddPoint(v1.X + dx2, v1.Y - dy2);
- }
- else
- {
- // Rounded inner join bridges via arc passing through the corner.
- this.AddPoint(v1.X + dx1, v1.Y - dy1);
- this.AddPoint(v1.X, v1.Y);
- this.CalcArc(v1.X, v1.Y, dx2, -dy2, dx1, -dy1);
- this.AddPoint(v1.X, v1.Y);
- this.AddPoint(v1.X + dx2, v1.Y - dy2);
- }
-
- break;
- }
+ this.CalcMiter(ref v0, ref v1, ref v2, dx1, dy1, dx2, dy2, LineJoin.MiterRevert, limit, 0D);
}
else
{
diff --git a/src/PolygonClipper/StrokeOptions.cs b/src/PolygonClipper/StrokeOptions.cs
index f9e5eb3..5034af8 100644
--- a/src/PolygonClipper/StrokeOptions.cs
+++ b/src/PolygonClipper/StrokeOptions.cs
@@ -23,11 +23,6 @@ public sealed class StrokeOptions : IEquatable
///
public double MiterLimit { get; set; } = 4D;
- ///
- /// Gets or sets the inner miter limit used to clamp joins on acute interior angles.
- ///
- public double InnerMiterLimit { get; set; } = 1.01D;
-
///
/// Gets or sets the tessellation detail scale for round joins and round caps.
/// Higher values produce more vertices (smoother curves, more work).
@@ -45,11 +40,6 @@ public sealed class StrokeOptions : IEquatable
///
public LineCap LineCap { get; set; } = LineCap.Butt;
- ///
- /// Gets or sets the join style used for sharp interior angles.
- ///
- public InnerJoin InnerJoin { get; set; } = InnerJoin.Miter;
-
///
public override bool Equals(object? obj) => this.Equals(obj as StrokeOptions);
@@ -58,20 +48,16 @@ public bool Equals(StrokeOptions? other)
=> other is not null &&
this.NormalizeOutput == other.NormalizeOutput &&
this.MiterLimit == other.MiterLimit &&
- this.InnerMiterLimit == other.InnerMiterLimit &&
this.ArcDetailScale == other.ArcDetailScale &&
this.LineJoin == other.LineJoin &&
- this.LineCap == other.LineCap &&
- this.InnerJoin == other.InnerJoin;
+ this.LineCap == other.LineCap;
///
public override int GetHashCode()
=> HashCode.Combine(
this.NormalizeOutput,
this.MiterLimit,
- this.InnerMiterLimit,
this.ArcDetailScale,
this.LineJoin,
- this.LineCap,
- this.InnerJoin);
+ this.LineCap);
}
diff --git a/tests/PolygonClipper.Tests/PolygonStrokerTests.cs b/tests/PolygonClipper.Tests/PolygonStrokerTests.cs
index 64d6172..c4d8ce3 100644
--- a/tests/PolygonClipper.Tests/PolygonStrokerTests.cs
+++ b/tests/PolygonClipper.Tests/PolygonStrokerTests.cs
@@ -68,8 +68,7 @@ public void Stroke_OpenPolylineWithThreeVertices_IsNotForcedClosed()
StrokeOptions options = new()
{
LineCap = LineCap.Butt,
- LineJoin = LineJoin.Miter,
- InnerJoin = InnerJoin.Miter
+ LineJoin = LineJoin.Miter
};
Polygon open =
@@ -138,7 +137,7 @@ public void ProcessPolygonAndClip_FigureNinePath_ProducesValidStroke()
AssertStrokeCoversInputCenterline(input, actual, samplesPerSegment: 3);
}
- [Theory (Skip = "For profiling only.")]
+ [Theory(Skip = "For profiling only.")]
[InlineData(101)]
[InlineData(301)]
[InlineData(1001)]