Skip to content

NaNs when attempting to tessellate a polygon which contains the origin as a vertex twice #25

@timschmidt

Description

@timschmidt

Attempting to run the polygon described by the following vertices through Polygon::tessellate() results in the following LineString being passed to earcutr, resulting in a crash when attempting to unwrap a non-existent result inside earcutr.

[
    Vertex {
        pos: [
            -0.38252272915132224,
            -0.5349545416973491,
            -2.3000000000000007,
        ],
        normal: [
            [
                -0.8982972487551757,
                0.05085137562241219,
                0.4364357804719848,
            ],
        ],
    },
    Vertex {
        pos: [
            0.0,
            0.0,
            0.0,
        ],
        normal: [
            [
                -0.8982972487551757,
                0.05085137562241219,
                0.4364357804719848,
            ],
        ],
    },
    Vertex {
        pos: [
            0.0,
            0.0,
            0.0,
        ],
        normal: [
            [
                -0.8493784211997779,
                0.4199339880208443,
                0.3197057135946779,
            ],
        ],
    },
    Vertex {
        pos: [
            -0.41614886367848847,
            -0.7886568930485289,
            -2.2197613448986218,
        ],
        normal: [
            [
                -0.8493784211997779,
                0.4199339880208443,
                0.3197057135946779,
            ],
        ],
    },
]


LineString(
    [
        Coord {
            x: NaN,
            y: NaN,
        },
        Coord {
            x: NaN,
            y: NaN,
        },
        Coord {
            x: NaN,
            y: NaN,
        },
        Coord {
            x: NaN,
            y: NaN,
        },
    ],
)

Here's the relevant section of code:

    /// Triangulate this polygon into a list of triangles, each triangle is [v0, v1, v2].
    pub fn tessellate(&self) -> Vec<[Vertex; 3]> {
        // If polygon has fewer than 3 vertices, nothing to tessellate
        if self.vertices.len() < 3 {
            return Vec::new();
        }
        
        println!("{:#?}",  self.vertices);

        let normal_3d = self.plane.normal.normalize();
        let (u, v) = build_orthonormal_basis(normal_3d);
        let origin_3d = self.vertices[0].pos;
    
        // Flatten each vertex to 2D
        let mut all_vertices_2d = Vec::with_capacity(self.vertices.len());
        for vert in &self.vertices {
            let offset = vert.pos.coords - origin_3d.coords;
            let x = offset.dot(&u);
            let y = offset.dot(&v);
            all_vertices_2d.push(coord!{x: x, y: y});
        }
    
        println!("{:#?}",  LineString::new(all_vertices_2d.clone()));

        let triangulation = GeoPolygon::new(LineString::new(all_vertices_2d), Vec::new()).earcut_triangles_raw();
        let triangle_indices = triangulation.triangle_indices;
        let vertices = triangulation.vertices;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions