-
-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #133 from hannobraun/surface-point
Prevent potential floating-point accuracy issues in triangulation
- Loading branch information
Showing
6 changed files
with
155 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
pub mod curves; | ||
pub mod points; | ||
pub mod surfaces; | ||
|
||
pub use self::{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use std::ops::{Add, Deref, DerefMut, Sub}; | ||
|
||
use crate::math::{Point, Vector}; | ||
|
||
/// A point on a surface | ||
/// | ||
/// This type is used for algorithms that need to deal with 2D points in surface | ||
/// coordinates. It can be converted back to the 3D point it originates from | ||
/// without loss from floating point accuracy issues. | ||
#[derive(Clone, Copy, Debug, PartialEq)] | ||
pub struct SurfacePoint { | ||
/// The surface coordinates of this point | ||
pub value: Point<2>, | ||
|
||
/// The 3D point this surface point was converted from | ||
/// | ||
/// Keeping this point around allows for the conversion back to a 3D point | ||
/// to be unaffected by floating point accuracy issues, which avoids a whole | ||
/// host of possible issues. | ||
pub from: Point<3>, | ||
} | ||
|
||
impl Deref for SurfacePoint { | ||
type Target = Point<2>; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.value | ||
} | ||
} | ||
|
||
impl DerefMut for SurfacePoint { | ||
fn deref_mut(&mut self) -> &mut Self::Target { | ||
&mut self.value | ||
} | ||
} | ||
|
||
// Some math operations for convenience. Obviously those can never return a new | ||
// `SurfacePoint`, or the conversion back to 3D would be broken. | ||
|
||
impl Add<Vector<2>> for SurfacePoint { | ||
type Output = Point<2>; | ||
|
||
fn add(self, rhs: Vector<2>) -> Self::Output { | ||
self.value.add(rhs) | ||
} | ||
} | ||
|
||
impl Sub<Self> for SurfacePoint { | ||
type Output = Vector<2>; | ||
|
||
fn sub(self, rhs: Self) -> Self::Output { | ||
self.value.sub(rhs.value) | ||
} | ||
} | ||
|
||
impl Sub<Point<2>> for SurfacePoint { | ||
type Output = Vector<2>; | ||
|
||
fn sub(self, rhs: Point<2>) -> Self::Output { | ||
self.value.sub(rhs) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
pub mod geometry; | ||
pub mod shapes; | ||
pub mod topology; | ||
pub mod util; | ||
|
||
use parry3d_f64::bounding_volume::AABB; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use parry2d_f64::utils::point_in_triangle::{corner_direction, Orientation}; | ||
use spade::HasPosition; | ||
|
||
use super::geometry::points::SurfacePoint; | ||
|
||
/// Create a Delaunay triangulation of all points | ||
pub fn triangulate(points: Vec<SurfacePoint>) -> Vec<[SurfacePoint; 3]> { | ||
use spade::Triangulation as _; | ||
|
||
let triangulation = spade::DelaunayTriangulation::<_>::bulk_load(points) | ||
.expect("Inserted invalid values into triangulation"); | ||
|
||
let mut triangles = Vec::new(); | ||
for triangle in triangulation.inner_faces() { | ||
let [v0, v1, v2] = triangle.vertices().map(|vertex| *vertex.data()); | ||
|
||
let triangle = match corner_direction(&v0, &v1, &v2) { | ||
Orientation::Ccw => [v0, v1, v2], | ||
Orientation::Cw => [v0, v2, v1], | ||
Orientation::None => { | ||
panic!( | ||
"Triangle returned from triangulation isn't actually a\ | ||
triangle" | ||
); | ||
} | ||
}; | ||
|
||
triangles.push(triangle); | ||
} | ||
|
||
triangles | ||
} | ||
|
||
// Enables the use of `SurfacePoint` in the triangulation. | ||
impl HasPosition for SurfacePoint { | ||
type Scalar = f64; | ||
|
||
fn position(&self) -> spade::Point2<Self::Scalar> { | ||
spade::Point2 { | ||
x: self.value.x, | ||
y: self.value.y, | ||
} | ||
} | ||
} |