Conversation
The check added in typemytype#65, which drops previousIntersectionPoint when it is not on the segment being processed, was also dropping points that were genuinely on it. The start of the segment was then re-derived from the next point in the flattened outline, so an inside corner came out as two on-curve points a few units apart (typemytype#72). When checking this case we want to know whether a point is on a segment. My previous fix answered that by recovering a t corresponding to the point, calculating that point on the curve, and measuring the distance. However, in the present (pre-existing) function t is recovered by matching a single axis, which can be quite inaccurate for "steep" curves. We could, and perhaps should, improve that function, but it's preferable to change the code to compare against the flattened outline instead, which is what this updated code does. Clipper computes its intersection points from the flattened chords, so each point will lie exactly on a chord before rounding and within less than an integer distance after. Measuring against the original curve involves an extra degree of approximation: the rounding, and then the distance of the chords from the curve. Checking distances from chords also enables a quick rejection based on bounding-box. Also adds a regression test covering the two contours from typemytype#72, and removes tValueToPoint() and _getLinePoint(), which typemytype#65 added only to support the old implementation of hasPoint() and which are now unused. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
On the "could, and perhaps should" above — I tried it. Solving both axes and The reason is that |
|
Thank you for looking at this so quickly @skef! |
Fixes #72.
The check I added in #65 drops
previousIntersectionPointwhen it isn't onthe segment being processed. It was also dropping points that were genuinely
on it. The start of the segment then got re-derived from the next point in
the flattened outline, so an inside corner came out as two on-curve points a
few units apart.
When checking this case we want to know whether a point is on a segment. My
previous fix answered that by recovering a
tcorresponding to the point,calculating that point on the curve, and measuring the distance. However, in
the present (pre-existing) function
tis recovered by matching a singleaxis, which can be quite inaccurate for "steep" curves.
We could, and perhaps should, improve that function, but it's preferable to
change the code to compare against the flattened outline instead, which is
what this updated code does. Clipper computes its intersection points from
the flattened chords, so each point will lie exactly on a chord before
rounding and within less than an integer distance after. Measuring against
the original curve involves an extra degree of approximation: the rounding,
and then the distance of the chords from the curve. Checking distances from
chords also enables a quick rejection based on bounding-box.
Also adds a regression test covering the two contours from #72, and removes
tValueToPoint()and_getLinePoint(), which #65 added only to support theold implementation of
hasPoint()and are now unused.Testing
Eglyph from Correct for (rare) bad tracking of previousIntersectionPoint #65 is unchanged — that guard still fires there, and theoutput is byte-identical to master.
itself), the old check discarded a point 8700 times and the new one 0 —
the misfire was not rare, it just needed overlapping curves to show up.
the full-corpus union.