aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/polygon.rs
diff options
context:
space:
mode:
authorSébastien Crozet <developer@crozet.re>2020-08-25 22:10:25 +0200
committerSébastien Crozet <developer@crozet.re>2020-08-25 22:10:25 +0200
commit754a48b7ff6d8c58b1ee08651e60112900b60455 (patch)
tree7d777a6c003f1f5d8f8d24f533f35a95a88957fe /src/geometry/polygon.rs
downloadrapier-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.rs76
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
+ }
+}