Currently working on a system to convert a stroked path, into a filled primitive represented by another path, and getting caught up with joins, and surprisingly can’t find much info on it.
Thus far I have per bezier stroke expansion:
And I can connect them by using a bevel join:
However as you see, the red expansion self intersects, the first solution is to check for an intersection, then if they do shorten the curves by De Casteljau’s, however the methods I’ve come across for checking for intersections tend to be very unreliable, producing multiple intersections near each other (bounding box subdivision as described on the bezier primer), or suffering from numerical precision (implicitization).
So is there a better way to do this, or am I stuck with 2 kinda bad options?
As a final note, as a quirk of the system I’m working in, all paths are comprised solely of quadratic beziers (eg straight lines are represented as having the control point of be bezier be in the middle directly between the two end points, cubics are approximated by multiple quadratics, etc). So we don’t need this to generalize to working with other orders, but it also needs to work with potentially degenerate beziers (ie the bezier control points being in a line).