mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-08 22:28:09 +00:00
The boolean's answer went through orient(), which judges each ring's side from its first point. The boolean often starts a contour where it touches another, so a triangle whose tip rests on a square's edge was dropped, and an even-odd hole touching its outline was filled. The boolean already runs holes against their outlines, so its rings are now only turned as a whole. Other fixes: - A bowtie drawn as one contour has no area of its own. It was dropped before the meet check and built nothing, although it fills both lobes. Sampling now keeps rings with no area, and orient() drops them after the check. Flat rings, every point on one line, fill nothing and are still dropped, so a stray flat contour doesn't send separate art through the boolean. - An open subpath was closed along its end handles when the profile went through the boolean, but straight otherwise, as the renderer fills it. It is now closed straight before the boolean too. - An empty union was taken as a refusal. Contours that cancel (a square drawn twice under even-odd) built a square. They now build nothing. - Contours meet within twice the boolean's own sweep tolerance, computed by its rule from every anchor and handle of the path it is given. pathops snaps anchors onto nearby heights before the sweep joins edges within that tolerance, so contours up to about 1.4 times it apart can come out as one; within twice it, every contour it might join goes through it, even far from the origin, and the few it leaves apart cost a boolean that builds the same shape. - A one-anchor subpath draws nothing, so it is skipped, as the renderer and the boolean skip it. - A profile the boolean refuses reuses the rings already sampled. Tests: - touching parts and holes; - an open subpath with handles, alone and beside crossing bars; - a flat contour beside separate squares; - contours joined far from the origin, including by handles alone, and contours a few millionths apart near it kept apart; - triangles snapped together and joined at 1.4 times the tolerance, the same triangles left apart and kept whole, and the factor pinned between 1.9 and 2.2 times, with the worst case just past twice the tolerance left apart by pathops; - a 24-bar grid: too complex for Extrude and Inflate, whole under Rotate; - the merged rings turned as a whole; - a one-anchor loop; - the bowtie and the cancelling squares under all three effects; - a 3,001-point star that the boolean refuses (TooComplex), built as drawn. Docs: the pathops README's Limits section now says only the try_ functions refuse, lists OpenPath and the caught panic, and describes unite_all's answers, and which calls take a precision. three-d.md and effects-parity.md (the 3D row, its history and status line) describe the merge and its limits.