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

Bug: Containment with Arcs is Incorrect #32

Open
dwmunster opened this issue Jun 10, 2024 · 1 comment
Open

Bug: Containment with Arcs is Incorrect #32

dwmunster opened this issue Jun 10, 2024 · 1 comment

Comments

@dwmunster
Copy link
Contributor

dwmunster commented Jun 10, 2024

Overview

Currently, faces are tested for containment within one another by converting to polygons and using geo to test containment of those polygons. However, all Segments are converted to polygons by adding a (straight) line from the start point to the end point. This can differ significantly from the true area if the Segment is of type Segment::Arc.

Steps to Reproduce

#[cfg(test)]
mod tests {
    use crate::decompose::ring::Ring;
    use crate::decompose::segment::Segment;
    use crate::primitives::arc::Arc;
    use crate::primitives::circle::Circle;
    use crate::primitives::point2::Point2;
    use geo::Contains;
    use std::cell::RefCell;
    use std::f64::consts::PI;
    use std::rc::Rc;

    #[test]
    fn test_arcs_contains_circle() {
        let origin = Rc::new(RefCell::new(Point2::new(0.0, 0.0)));
        let circle = Circle::new(origin.clone(), 0.99);
        let ring = Ring::Circle(circle);

        let angles = [0., PI / 2., PI, 3. * PI / 2.];
        let segments = angles
            .iter()
            .zip(angles.iter().cycle().skip(1))
            .map(|(start, end)| Segment::Arc(Arc::new(origin.clone(), 1.0, false, *start, *end)))
            .collect();
        let arcs = Ring::Segments(segments);
        assert!(!ring.as_polygon().contains(&arcs.as_polygon()));
        assert!(arcs.as_polygon().contains(&ring.as_polygon()));
    }
}

This test constructs a circle of radius 1 by joining 4 quarter-circle Arc segments and compares it against a circle of radius 0.99.

Expected Outcome

Test passes.

Actual Outcome

The assertion that arcs.as_polygon().contains(&ring.as_polygon()) fails because the former is rendered as a diamond (with vertices at [(-1, 0), (0, -1), (1, 0), (0, 1)]) and the latter as a 36-gon of radius 0.99.

@dwmunster
Copy link
Contributor Author

I do have some WIP on replacing geo for our more simple case that would resolve this, but I'm not sure when I will have a chance to finish that work. Thus, I wanted to at least capture it here.

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

1 participant