Skip to content

Add PolygonStroker and RemoveSelfIntersections for robust, high-performance stroke normalization#22

Merged
JimBobSquarePants merged 87 commits intomainfrom
js/normalize-self-intersections
Feb 18, 2026
Merged

Add PolygonStroker and RemoveSelfIntersections for robust, high-performance stroke normalization#22
JimBobSquarePants merged 87 commits intomainfrom
js/normalize-self-intersections

Conversation

@JimBobSquarePants
Copy link
Copy Markdown
Member

@JimBobSquarePants JimBobSquarePants commented Feb 8, 2026

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

This PR adds stroking and normalization to SixLabors.PolygonClipper for handling non-simple, real-world geometry.

What’s Included

  • PolygonClipper.Normalize(Polygon)
    New explicit normalization API that resolves self-intersections and overlaps into canonical positive-winding output.
  • PolygonStroker + StrokeOptions
    New stroke-geometry pipeline for polygons/contours, with configurable join/cap behavior and optional output normalization.

Behavior and Compatibility

  • Normalization is explicit and opt-in via Normalize(...).
  • Existing boolean operation behavior is unchanged.
  • Stroker output can be normalized before return, so callers can get stable, fillable geometry without extra cleanup steps.

Why This Matters

Many production inputs are not simple polygons (self-intersections, touching edges, compound paths), especially from text outlines and imported vector artwork. This pipeline provides a practical preprocessing/geometry-generation path that improves robustness for downstream operations.

Validation and Docs

  • Tests were added/updated for complex scenarios (including compound and glyph-like inputs).
  • README/docs were updated to describe stroking and normalization usage and semantics.

Performance Note

In the ImageSharp.Drawing DrawPolygonMediumThick benchmark, replacing the default stroker/clipper path with this implementation reduced runtime from ~14 ms to ~3 ms (about 79% faster) and also reduced allocation pressure.

CC @stefannikolei

@stefannikolei
Copy link
Copy Markdown
Contributor

I like the third Party notices 👍

@JimBobSquarePants JimBobSquarePants changed the title Introduce self‑intersection normalization for polygons Add PolygonStroker and RemoveSelfIntersections for robust, high-performance stroke normalization Feb 17, 2026
@JimBobSquarePants
Copy link
Copy Markdown
Member Author

OK. I'm merging this. Super happy with the result!

@JimBobSquarePants JimBobSquarePants merged commit 93e1d8d into main Feb 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants