Skip to content

Commit

Permalink
Merge pull request #435 from hannobraun/triangulate
Browse files Browse the repository at this point in the history
Add triangulation test suite
  • Loading branch information
hannobraun authored Apr 6, 2022
2 parents f054df4 + 6dbb5af commit 7c0e0e3
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions fj-kernel/src/algorithms/triangulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,92 @@ impl HasPosition for geometry::Point<2> {
}
}
}

#[cfg(test)]
mod tests {
use fj_debug::DebugInfo;
use fj_math::{Scalar, Triangle};

use crate::{geometry::Surface, shape::Shape, topology::Face};

#[test]
fn simple() -> anyhow::Result<()> {
let mut shape = Shape::new();

let a = [0., 0., 0.];
let b = [2., 0., 0.];
let c = [2., 2., 0.];
let d = [0., 1., 0.];

Face::builder(Surface::x_y_plane(), &mut shape)
.with_exterior_polygon([a, b, c, d])
.build()?;

let triangles = triangulate(shape);
assert!(triangles.contains([a, b, d]));
assert!(triangles.contains([b, c, d]));
assert!(!triangles.contains([a, b, c]));
assert!(!triangles.contains([a, c, d]));

Ok(())
}

#[test]
fn simple_hole() -> anyhow::Result<()> {
let mut shape = Shape::new();

let a = [0., 0., 0.];
let b = [4., 0., 0.];
let c = [4., 4., 0.];
let d = [0., 4., 0.];

let e = [1., 1., 0.];
let f = [3., 1., 0.];
let g = [3., 3., 0.];
let h = [1., 2., 0.];

Face::builder(Surface::x_y_plane(), &mut shape)
.with_exterior_polygon([a, b, c, d])
.with_interior_polygon([e, f, g, h])
.build()?;

let triangles = triangulate(shape);

// Should contain some triangles from the polygon. Don't need to test
// them all.
assert!(triangles.contains([a, e, h]));
assert!(triangles.contains([a, d, h]));

// Shouldn't contain any possible triangle from the hole.
assert!(!triangles.contains([e, f, g]));
assert!(!triangles.contains([e, g, h]));
assert!(!triangles.contains([e, f, h]));
assert!(!triangles.contains([f, g, h]));

Ok(())
}

fn triangulate(shape: Shape) -> Triangles {
let tolerance = Scalar::ONE;

let mut triangles = Vec::new();
let mut debug_info = DebugInfo::new();

super::triangulate(shape, tolerance, &mut triangles, &mut debug_info);

for triangle in &mut triangles {
*triangle = triangle.normalize();
}

Triangles(triangles)
}

struct Triangles(Vec<Triangle<3>>);

impl Triangles {
fn contains(&self, triangle: impl Into<Triangle<3>>) -> bool {
let triangle = triangle.into().normalize();
self.0.contains(&triangle)
}
}
}

0 comments on commit 7c0e0e3

Please sign in to comment.