diff options
| author | Sébastien Crozet <developer@crozet.re> | 2020-08-25 22:10:25 +0200 |
|---|---|---|
| committer | Sébastien Crozet <developer@crozet.re> | 2020-08-25 22:10:25 +0200 |
| commit | 754a48b7ff6d8c58b1ee08651e60112900b60455 (patch) | |
| tree | 7d777a6c003f1f5d8f8d24f533f35a95a88957fe /src/geometry/polygon.rs | |
| download | rapier-754a48b7ff6d8c58b1ee08651e60112900b60455.tar.gz rapier-754a48b7ff6d8c58b1ee08651e60112900b60455.tar.bz2 rapier-754a48b7ff6d8c58b1ee08651e60112900b60455.zip | |
First public release of Rapier.v0.1.0
Diffstat (limited to 'src/geometry/polygon.rs')
| -rw-r--r-- | src/geometry/polygon.rs | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/geometry/polygon.rs b/src/geometry/polygon.rs new file mode 100644 index 0000000..cdb1012 --- /dev/null +++ b/src/geometry/polygon.rs @@ -0,0 +1,76 @@ +use crate::math::{Isometry, Point, Vector}; +use ncollide::bounding_volume::AABB; + +#[derive(Clone)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +/// A convex planar polygon. +pub struct Polygon { + pub(crate) vertices: Vec<Point<f32>>, + pub(crate) normals: Vec<Vector<f32>>, +} + +impl Polygon { + /// Builds a new polygon from a set of vertices and normals. + /// + /// The vertices must be ordered in such a way that two consecutive + /// vertices determines an edge of the polygon. For example `vertices[0], vertices[1]` + /// is an edge, `vertices[1], vertices[2]` is the next edge, etc. The last edge will + /// be `vertices[vertices.len() - 1], vertices[0]`. + /// The vertices must be given in counter-clockwise order. + /// The vertices must form a convex polygon. + /// + /// One normal must be provided per edge and mut point towards the outside of the polygon. + pub fn new(vertices: Vec<Point<f32>>, normals: Vec<Vector<f32>>) -> Self { + Self { vertices, normals } + } + + /// Compute the axis-aligned bounding box of the polygon. + pub fn aabb(&self, pos: &Isometry<f32>) -> AABB<f32> { + let p0 = pos * self.vertices[0]; + let mut mins = p0; + let mut maxs = p0; + + for pt in &self.vertices[1..] { + let pt = pos * pt; + mins = mins.inf(&pt); + maxs = maxs.sup(&pt); + } + + AABB::new(mins.into(), maxs.into()) + } + + /// The vertices of this polygon. + pub fn vertices(&self) -> &[Point<f32>] { + &self.vertices + } + + pub(crate) fn support_point(&self, dir: &Vector<f32>) -> usize { + let mut best_dot = -f32::MAX; + let mut best_i = 0; + + for (i, pt) in self.vertices.iter().enumerate() { + let dot = pt.coords.dot(&dir); + if dot > best_dot { + best_dot = dot; + best_i = i; + } + } + + best_i + } + + pub(crate) fn support_face(&self, dir: &Vector<f32>) -> usize { + let mut max_dot = -f32::MAX; + let mut max_dot_i = 0; + + for (i, normal) in self.normals.iter().enumerate() { + let dot = normal.dot(dir); + if dot > max_dot { + max_dot = dot; + max_dot_i = i; + } + } + + max_dot_i + } +} |
