Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinitesimal stroked bezier fills whole tile #650

Open
dominikh opened this issue Jul 31, 2024 · 4 comments
Open

Infinitesimal stroked bezier fills whole tile #650

dominikh opened this issue Jul 31, 2024 · 4 comments

Comments

@dominikh
Copy link

The scene

let mut scene = Scene::new();
let mut p: BezPath = BezPath::default();
p.move_to((399.997, 400.0002));
p.quad_to((399.998, 400.0002), (400., 400.));
scene.stroke(
    &Stroke::default(),
    Affine::IDENTITY,
    Color::rgb(1., 0., 0.),
    None,
    &p,
);

renders as a solid square
image

This seems very sensitive to the coordinates, and many translations of the coordinates don't reproduce the issue. The same issue reproduces with a cubic bezier, with the point (400., 400.) repeated.

@raphlinus
Copy link
Contributor

raphlinus commented Jul 31, 2024

It's very likely this is another manifestation of #644 (edit: I meant #616), which I believe is a watertightness issue in the expanded stroke outlines. It's in my queue to look at.

@waywardmonkeys waywardmonkeys added this to the Vello 0.3 release milestone Aug 1, 2024
@raphlinus
Copy link
Contributor

I'm not able to repro directly (or #616 either) from the given example, but I do see an artifact with the following:

        let mut p: BezPath = BezPath::default();
        p.move_to((399.997, 400.0002));
        p.quad_to((399.998, 400.0002), (400., 400.));
        p.line_to((390., 390.));
        let a = Affine::translate((31.90625, 23.98875));
        scene.stroke(
            &Stroke::new(2.0).with_caps(Cap::Butt),
            a,
            Color::WHITE,
            None,
            &p,
        );

It definitely appears to be a watertightness bug, and I suspect it's the same underlying issue. I should be able to track it down now that I've got a repro.

Curious why the variation in reproducibility, but we'll most likely get to that when we have a proposed fix.

@DJMcNab
Copy link
Member

DJMcNab commented Aug 12, 2024

I suspect the difference could be a fast-math issue.

That's my general heuristic to explain if something is different on Mac :P

@raphlinus
Copy link
Contributor

I have a tentative analysis and proposed fix for this particular case. Basically the tangent computed for the start cap is not bit-identical to the tangent for the parallel curves (even though mathematically it's the same). Change line 847 of flatten.rs from:

                    let tangent = cubic_start_tangent(pts.p0, pts.p1, pts.p2, pts.p3);

to

                    let tangent = pts.p3 - pts.p0;

I'm not sure this fixes everything (still investigating), but did want to send an update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants