-
Notifications
You must be signed in to change notification settings - Fork 91
Open
Description
Hi there.
I've stumbled upon a very specific case where the contains check returns a wrong result if the test point sits right between the endpoint of two Bézier curves:
let bez = BezPath::from_vec(vec![
PathEl::MoveTo((200.0, 410.0).into()),
PathEl::CurveTo((139.12278747558594, 410.0).into(), (90.0, 360.8772277832031).into(), (90.0, 300.0).into()),
PathEl::CurveTo((90.0, 239.12278747558594).into(), (139.12278747558594, 190.0).into(), (200.0, 190.0).into()),
PathEl::CurveTo((150.19137573242188, 210.0).into(), (110.0, 250.19137573242188).into(), (110.0, 300.0).into()),
PathEl::CurveTo((110.0, 349.8086242675781).into(), (150.19137573242188, 390.0).into(), (200.0, 390.0).into()),
PathEl::ClosePath]);
assert!(bez.contains((100.0,300.1).into())); // Works fine.
assert!(bez.contains((100.0,299.9).into())); // Works fine.
assert!(bez.contains((100.0,300.0).into())); // Fails.I have tried simplifying more, but even if I remove the digits after the decimal points, the test produces the correct results instead of reproducing the issue.
Tried this in both debug and release.
I have no idea if there is an established way to numerically stablise this check. Kurbo can't be the first program to run into this issue.
From what I read, issue #180 is not directly related to this. But that's for the crate experts to decide. :)
All the best,
Simon
Bonus SVG code to quickly see that the point should indeed be contained:
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="800" viewBox="0 0 500 500" fill="none">
<path d="M200,410 C139.12278747558594,410 90,360.8772277832031 90,300 C90,239.12278747558594 139.12278747558594,190 200,190 C150.19137573242188,210 110,250.19137573242188 110,300 C110,349.8086242675781 150.19137573242188,390 200,390 Z" fill="red"/>
<rect x="100" y="300" width="3" height="3" fill="#000"/>
</svg>Metadata
Metadata
Assignees
Labels
No labels