BezierKit
BezierKit copied to clipboard
`offset` seems to treat straight & curved segments differently
All curves
Here’s an example of a capital O showing what happens when offset(10)
is applied: each on-curve point is shifted in the offset direction by 10 units.
![Screen Shot 2020-12-17 at Dec 17 10 39 30 AM](https://user-images.githubusercontent.com/1425051/102529088-47257600-4054-11eb-9964-5c194483ec3d.png)
![Screen Shot 2020-12-17 at Dec 17 10 39 36 AM](https://user-images.githubusercontent.com/1425051/102529099-4a206680-4054-11eb-9b01-3fe01c0ffeb6.png)
All straights
Here’s an example of the same offset(10)
applied to a capital H. In this case, the points are only moving 5 units from their original positions:
![Screen Shot 2020-12-17 at Dec 17 10 39 16 AM](https://user-images.githubusercontent.com/1425051/102529257-7dfb8c00-4054-11eb-8d61-46829440732b.png)
![Screen Shot 2020-12-17 at Dec 17 10 39 20 AM](https://user-images.githubusercontent.com/1425051/102529260-7e942280-4054-11eb-88ed-1ca1c9ac526e.png)
Mix of curves and straights
Now here’s a capital D with offset(10)
. Whereas the O was only made of curves, and the H only made of straights, this combines both. The result is that the straight segments are moving only half the distance, so certain segments that should be parallel are not. For instance, the top and bottom edges are no longer horizontal.
![Screen Shot 2020-12-17 at Dec 17 10 37 24 AM](https://user-images.githubusercontent.com/1425051/102529543-e5b1d700-4054-11eb-8e65-7dfb33a21fbc.png)
![Screen Shot 2020-12-17 at Dec 17 10 37 30 AM](https://user-images.githubusercontent.com/1425051/102529546-e64a6d80-4054-11eb-9e95-3c6114da15b3.png)
Hello @mbutterick
Thank you once again for the level of detail you've gone into opening this issue.
I believe that what's going on here is that offset
doesn't work properly with corners. I haven't given the offset
method the attention it should get to ensure correctness. The behavior you're seeing at 90 degree corners where the point moves 1/2 the expected distance is because the code to compute the corner position is based on taking the average of the point's position if it were moved along one edge (vertically) and moved along the other edge (horizontally). The code needs a better approach.
Instead of using a linear average of the startPoint
and endPoint
of curves that are noncontiguous after offset
, I propose that the better idea is to project the intersection of the two segments, and then move the startPoint
and endPoint
of the offset curves to that intersection.
Here’s how that looks using the original test cases, still applying offset(10)
.
All curves
In this case, no change. Just like before, each on-curve point is shifted in the offset direction by 10 units.
All straights
Previously, with linear averaging, the points were only moving a net 5 units from their original positions. But with projection, they all move 10 points.
Mix of curves and straights
Previously, with linear averaging, the straight segments were moving only half the distance, but curve points were moving the full distance, resulting in top and bottom edges that were no longer horizontal. With projection, however, every point moves the correct distance, and parallelism is preserved:
PR #98 shows how I did this, though it is not offered as a fully tested work of art.