pub struct ConvexPolygon { /* private fields */ }Expand description
A 2D convex polygon.
A convex polygon is a closed 2D shape where all interior angles are less than 180 degrees, and any line segment drawn between two points inside the polygon stays entirely within the polygon. Common examples include triangles, rectangles, and regular polygons like hexagons.
§What is a convex polygon?
In 2D space, a polygon is convex if:
- Every interior angle is less than or equal to 180 degrees
- The line segment between any two points inside the polygon lies entirely inside the polygon
- All vertices “bulge outward” - there are no indentations or concave areas
Examples of convex polygons: triangle, square, regular pentagon, regular hexagon Examples of non-convex (concave) polygons: star shapes, L-shapes, crescents
§Use cases
Convex polygons are widely used in:
- Game development: Character hitboxes, platform boundaries, simple building shapes
- Physics simulations: Rigid body collision detection (more efficient than arbitrary polygons)
- Robotics: Simplified environment representations, obstacle boundaries
- Computer graphics: Fast rendering primitives, clipping regions
- Computational geometry: As building blocks for more complex operations
§Representation
This structure stores:
- Points: The vertices of the polygon in counter-clockwise order
- Normals: Unit vectors perpendicular to each edge, pointing outward
The normals are pre-computed for efficient collision detection algorithms.
§Example: Creating a simple triangle
use parry2d::shape::ConvexPolygon;
use nalgebra::Point2;
// Create a triangle from three vertices (counter-clockwise order)
let vertices = vec![
Point2::origin(), // bottom-left
Point2::new(2.0, 0.0), // bottom-right
Point2::new(1.0, 2.0), // top
];
let triangle = ConvexPolygon::from_convex_polyline(vertices)
.expect("Failed to create triangle");
// The polygon has 3 vertices
assert_eq!(triangle.points().len(), 3);
// and 3 edge normals (one per edge)
assert_eq!(triangle.normals().len(), 3);Implementations§
Source§impl ConvexPolygon
impl ConvexPolygon
Source§impl ConvexPolygon
impl ConvexPolygon
Sourcepub fn bounding_sphere(&self, pos: &Isometry<f32>) -> BoundingSphere
pub fn bounding_sphere(&self, pos: &Isometry<f32>) -> BoundingSphere
Computes the world-space bounding sphere of this convex polygon, transformed by pos.
Sourcepub fn local_bounding_sphere(&self) -> BoundingSphere
pub fn local_bounding_sphere(&self) -> BoundingSphere
Computes the local-space bounding sphere of this convex polygon.
Source§impl ConvexPolygon
impl ConvexPolygon
Sourcepub fn from_convex_hull(points: &[Point<f32>]) -> Option<Self>
pub fn from_convex_hull(points: &[Point<f32>]) -> Option<Self>
Creates a new 2D convex polygon from an arbitrary set of points by computing their convex hull.
This is the most flexible constructor - it automatically computes the convex hull of the given points, which is the smallest convex polygon that contains all the input points. Think of it as wrapping a rubber band around the points.
Use this when:
- You have an arbitrary collection of points and want the convex boundary
- You’re not sure if your points form a convex shape
- You want to simplify a point cloud to its convex outline
§Returns
Some(ConvexPolygon)if successfulNoneif the convex hull computation failed (e.g., all points are collinear or coincident)
§Example: Creating a convex polygon from arbitrary points
use parry2d::shape::ConvexPolygon;
use nalgebra::Point2;
// Some arbitrary points (including one inside the convex hull)
let points = vec![
Point2::origin(),
Point2::new(4.0, 0.0),
Point2::new(2.0, 3.0),
Point2::new(2.0, 1.0), // This point is inside the triangle
];
let polygon = ConvexPolygon::from_convex_hull(&points)
.expect("Failed to create convex hull");
// The convex hull only has 3 vertices (the interior point was excluded)
assert_eq!(polygon.points().len(), 3);§Example: Simplifying a point cloud
use parry2d::shape::ConvexPolygon;
use nalgebra::Point2;
// A cloud of points that roughly forms a circle
let mut points = Vec::new();
for i in 0..20 {
let angle = (i as f32) * std::f32::consts::TAU / 20.0;
points.push(Point2::new(angle.cos(), angle.sin()));
}
// Add some interior points
points.push(Point2::origin());
points.push(Point2::new(0.5, 0.5));
let polygon = ConvexPolygon::from_convex_hull(&points)
.expect("Failed to create convex hull");
// The convex hull has 20 vertices (the boundary points)
assert_eq!(polygon.points().len(), 20);Sourcepub fn from_convex_polyline(points: Vec<Point<f32>>) -> Option<Self>
pub fn from_convex_polyline(points: Vec<Point<f32>>) -> Option<Self>
Creates a new 2D convex polygon from vertices that already form a convex shape.
This constructor is more efficient than from_convex_hull because it assumes the input
points already form a convex polygon in counter-clockwise order, and it doesn’t compute the
convex hull. The convexity is not verified - if you pass non-convex points, the resulting
shape may behave incorrectly in collision detection.
Important: Points must be ordered counter-clockwise (CCW). If you’re unsure about the
ordering or convexity, use from_convex_hull instead.
This method automatically removes collinear vertices (points that lie on the line between
their neighbors) to simplify the polygon. If you want to preserve all vertices exactly as given,
use from_convex_polyline_unmodified.
§When to use this
Use this constructor when:
- You already know your points form a convex polygon
- The points are ordered counter-clockwise around the shape
- You want better performance by skipping convex hull computation
§Returns
Some(ConvexPolygon)if successfulNoneif all points are nearly collinear (form an almost flat line) or there are fewer than 3 vertices after removing collinear points
§Example: Creating a square
use parry2d::shape::ConvexPolygon;
use nalgebra::Point2;
// A square with vertices in counter-clockwise order
let square = ConvexPolygon::from_convex_polyline(vec![
Point2::origin(), // bottom-left
Point2::new(1.0, 0.0), // bottom-right
Point2::new(1.0, 1.0), // top-right
Point2::new(0.0, 1.0), // top-left
]).expect("Failed to create square");
assert_eq!(square.points().len(), 4);§Example: Collinear points are automatically removed
use parry2d::shape::ConvexPolygon;
use nalgebra::Point2;
// A quadrilateral with one vertex on an edge (making it collinear)
let polygon = ConvexPolygon::from_convex_polyline(vec![
Point2::origin(),
Point2::new(2.0, 0.0),
Point2::new(2.0, 1.0), // This point is on the line from (2,0) to (2,2)
Point2::new(2.0, 2.0),
Point2::new(0.0, 2.0),
]).expect("Failed to create polygon");
// The collinear point at (2.0, 1.0) was removed, leaving a rectangle
assert_eq!(polygon.points().len(), 4);Sourcepub fn from_convex_polyline_unmodified(points: Vec<Point<f32>>) -> Option<Self>
pub fn from_convex_polyline_unmodified(points: Vec<Point<f32>>) -> Option<Self>
Creates a new 2D convex polygon from a set of points assumed to describe a counter-clockwise convex polyline.
This is the same as ConvexPolygon::from_convex_polyline but without removing any point
from the input even if some are coplanar.
Returns None if points doesn’t contain at least three points.
Sourcepub fn points(&self) -> &[Point<f32>] ⓘ
pub fn points(&self) -> &[Point<f32>] ⓘ
Returns the vertices of this convex polygon.
The vertices are stored in counter-clockwise order around the polygon. This is a slice reference to the internal vertex storage.
§Example
use parry2d::shape::ConvexPolygon;
use nalgebra::Point2;
let triangle = ConvexPolygon::from_convex_polyline(vec![
Point2::origin(),
Point2::new(1.0, 0.0),
Point2::new(0.5, 1.0),
]).unwrap();
let vertices = triangle.points();
assert_eq!(vertices.len(), 3);
assert_eq!(vertices[0], Point2::origin());Sourcepub fn normals(&self) -> &[Unit<Vector<f32>>]
pub fn normals(&self) -> &[Unit<Vector<f32>>]
Returns the outward-pointing normals of the edges of this convex polygon.
Each normal is a unit vector perpendicular to an edge, pointing outward from the polygon.
The normals are stored in the same order as the edges, so normals()[i] is the normal
for the edge from points()[i] to points()[(i+1) % len].
These pre-computed normals are used internally for efficient collision detection.
§Example
use parry2d::shape::ConvexPolygon;
use nalgebra::{Point2, Vector2};
// Create a square aligned with the axes
let square = ConvexPolygon::from_convex_polyline(vec![
Point2::origin(), // bottom-left
Point2::new(1.0, 0.0), // bottom-right
Point2::new(1.0, 1.0), // top-right
Point2::new(0.0, 1.0), // top-left
]).unwrap();
let normals = square.normals();
assert_eq!(normals.len(), 4);
// The first normal points downward (perpendicular to bottom edge)
let bottom_normal = normals[0];
assert!((bottom_normal.y - (-1.0)).abs() < 1e-5);
assert!(bottom_normal.x.abs() < 1e-5);Sourcepub fn scaled(self, scale: &Vector<f32>) -> Option<Self>
pub fn scaled(self, scale: &Vector<f32>) -> Option<Self>
Computes a scaled version of this convex polygon.
This method scales the polygon by multiplying each vertex coordinate by the corresponding
component of the scale vector. This allows for non-uniform scaling (different scale factors
for x and y axes).
The normals are also updated to reflect the scaling transformation.
§Returns
Some(ConvexPolygon)with the scaled shapeNoneif the scaling results in degenerate normals (e.g., if the scale factor along one axis is zero or nearly zero)
§Example: Uniform scaling
use parry2d::shape::ConvexPolygon;
use nalgebra::{Point2, Vector2};
let triangle = ConvexPolygon::from_convex_polyline(vec![
Point2::origin(),
Point2::new(1.0, 0.0),
Point2::new(0.5, 1.0),
]).unwrap();
// Scale uniformly by 2x
let scaled = triangle.scaled(&Vector2::new(2.0, 2.0))
.expect("Failed to scale");
// All coordinates are doubled
assert_eq!(scaled.points()[1], Point2::new(2.0, 0.0));
assert_eq!(scaled.points()[2], Point2::new(1.0, 2.0));§Example: Non-uniform scaling
use parry2d::shape::ConvexPolygon;
use nalgebra::{Point2, Vector2};
let square = ConvexPolygon::from_convex_polyline(vec![
Point2::origin(),
Point2::new(1.0, 0.0),
Point2::new(1.0, 1.0),
Point2::new(0.0, 1.0),
]).unwrap();
// Scale to make it wider (2x) and taller (3x)
let rectangle = square.scaled(&Vector2::new(2.0, 3.0))
.expect("Failed to scale");
assert_eq!(rectangle.points()[2], Point2::new(2.0, 3.0));Sourcepub fn offsetted(&self, amount: f32) -> Self
pub fn offsetted(&self, amount: f32) -> Self
Returns a mitered offset (expanded or contracted) version of the polygon.
This method creates a new polygon by moving each edge outward (or inward for negative values)
by the specified amount. The vertices are adjusted to maintain sharp corners (mitered joints).
This is also known as “polygon dilation” or “Minkowski sum with a circle”.
§Use cases
- Creating “safe zones” or margins around objects
- Implementing “thick” polygon collision detection
- Creating rounded rectangular shapes (when combined with rounding)
- Growing or shrinking shapes for morphological operations
§Arguments
amount- The distance to move each edge. Positive values expand the polygon outward, making it larger. Must be a non-negative finite number.
§Panics
Panics if amount is not a non-negative finite number (NaN, infinity, or negative).
§Example: Expanding a triangle
use parry2d::shape::ConvexPolygon;
use nalgebra::Point2;
let triangle = ConvexPolygon::from_convex_polyline(vec![
Point2::origin(),
Point2::new(2.0, 0.0),
Point2::new(1.0, 2.0),
]).unwrap();
// Expand the triangle by 0.5 units
let expanded = triangle.offsetted(0.5);
// The expanded triangle has the same number of vertices
assert_eq!(expanded.points().len(), 3);
// But the vertices have moved outward
// (exact positions depend on the miter calculation)§Example: Creating a margin around a square
use parry2d::shape::ConvexPolygon;
use nalgebra::Point2;
let square = ConvexPolygon::from_convex_polyline(vec![
Point2::origin(),
Point2::new(1.0, 0.0),
Point2::new(1.0, 1.0),
Point2::new(0.0, 1.0),
]).unwrap();
// Create a 0.2 unit margin around the square
let margin = square.offsetted(0.2);
// The shape is still a square (4 vertices)
assert_eq!(margin.points().len(), 4);Trait Implementations§
Source§impl Clone for ConvexPolygon
impl Clone for ConvexPolygon
Source§fn clone(&self) -> ConvexPolygon
fn clone(&self) -> ConvexPolygon
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ConvexPolygon
impl Debug for ConvexPolygon
Source§impl PointQuery for ConvexPolygon
impl PointQuery for ConvexPolygon
Source§fn project_local_point(
&self,
point: &Point<f32>,
solid: bool,
) -> PointProjection
fn project_local_point( &self, point: &Point<f32>, solid: bool, ) -> PointProjection
self. Read moreSource§fn project_local_point_and_get_feature(
&self,
point: &Point<f32>,
) -> (PointProjection, FeatureId)
fn project_local_point_and_get_feature( &self, point: &Point<f32>, ) -> (PointProjection, FeatureId)
self and returns the id of the
feature the point was projected on.Source§fn project_local_point_with_max_dist(
&self,
pt: &Point<f32>,
solid: bool,
max_dist: f32,
) -> Option<PointProjection>
fn project_local_point_with_max_dist( &self, pt: &Point<f32>, solid: bool, max_dist: f32, ) -> Option<PointProjection>
Source§fn project_point_with_max_dist(
&self,
m: &Isometry<f32>,
pt: &Point<f32>,
solid: bool,
max_dist: f32,
) -> Option<PointProjection>
fn project_point_with_max_dist( &self, m: &Isometry<f32>, pt: &Point<f32>, solid: bool, max_dist: f32, ) -> Option<PointProjection>
self transformed by m, unless the projection lies further than the given max distance.Source§fn distance_to_local_point(&self, pt: &Point<f32>, solid: bool) -> f32
fn distance_to_local_point(&self, pt: &Point<f32>, solid: bool) -> f32
self.Source§fn contains_local_point(&self, pt: &Point<f32>) -> bool
fn contains_local_point(&self, pt: &Point<f32>) -> bool
self.Source§fn project_point(
&self,
m: &Isometry<f32>,
pt: &Point<f32>,
solid: bool,
) -> PointProjection
fn project_point( &self, m: &Isometry<f32>, pt: &Point<f32>, solid: bool, ) -> PointProjection
self transformed by m.Source§fn distance_to_point(
&self,
m: &Isometry<f32>,
pt: &Point<f32>,
solid: bool,
) -> f32
fn distance_to_point( &self, m: &Isometry<f32>, pt: &Point<f32>, solid: bool, ) -> f32
self transformed by m.Source§fn project_point_and_get_feature(
&self,
m: &Isometry<f32>,
pt: &Point<f32>,
) -> (PointProjection, FeatureId)
fn project_point_and_get_feature( &self, m: &Isometry<f32>, pt: &Point<f32>, ) -> (PointProjection, FeatureId)
self transformed by m and returns the id of the
feature the point was projected on.Source§impl PolygonalFeatureMap for ConvexPolygon
impl PolygonalFeatureMap for ConvexPolygon
Source§fn local_support_feature(
&self,
dir: &Unit<Vector<f32>>,
out_feature: &mut PolygonalFeature,
)
fn local_support_feature( &self, dir: &Unit<Vector<f32>>, out_feature: &mut PolygonalFeature, )
self towards the dir.Source§fn is_convex_polyhedron(&self) -> bool
fn is_convex_polyhedron(&self) -> bool
ConvexPolyhedron?Source§impl RayCast for ConvexPolygon
impl RayCast for ConvexPolygon
Source§fn cast_local_ray_and_get_normal(
&self,
ray: &Ray,
max_time_of_impact: f32,
solid: bool,
) -> Option<RayIntersection>
fn cast_local_ray_and_get_normal( &self, ray: &Ray, max_time_of_impact: f32, solid: bool, ) -> Option<RayIntersection>
Source§fn cast_local_ray(
&self,
ray: &Ray,
max_time_of_impact: f32,
solid: bool,
) -> Option<f32>
fn cast_local_ray( &self, ray: &Ray, max_time_of_impact: f32, solid: bool, ) -> Option<f32>
Source§fn intersects_local_ray(&self, ray: &Ray, max_time_of_impact: f32) -> bool
fn intersects_local_ray(&self, ray: &Ray, max_time_of_impact: f32) -> bool
Source§fn cast_ray(
&self,
m: &Isometry<f32>,
ray: &Ray,
max_time_of_impact: f32,
solid: bool,
) -> Option<f32>
fn cast_ray( &self, m: &Isometry<f32>, ray: &Ray, max_time_of_impact: f32, solid: bool, ) -> Option<f32>
Source§fn cast_ray_and_get_normal(
&self,
m: &Isometry<f32>,
ray: &Ray,
max_time_of_impact: f32,
solid: bool,
) -> Option<RayIntersection>
fn cast_ray_and_get_normal( &self, m: &Isometry<f32>, ray: &Ray, max_time_of_impact: f32, solid: bool, ) -> Option<RayIntersection>
Source§impl Shape for ConvexPolygon
impl Shape for ConvexPolygon
Source§fn scale_dyn(
&self,
scale: &Vector<f32>,
_num_subdivisions: u32,
) -> Option<Box<dyn Shape>>
fn scale_dyn( &self, scale: &Vector<f32>, _num_subdivisions: u32, ) -> Option<Box<dyn Shape>>
scale into a boxed trait-object. Read moreSource§fn compute_local_aabb(&self) -> Aabb
fn compute_local_aabb(&self) -> Aabb
Aabb of this shape.Source§fn compute_local_bounding_sphere(&self) -> BoundingSphere
fn compute_local_bounding_sphere(&self) -> BoundingSphere
Source§fn compute_aabb(&self, position: &Isometry<f32>) -> Aabb
fn compute_aabb(&self, position: &Isometry<f32>) -> Aabb
Aabb of this shape with the given position.Source§fn mass_properties(&self, density: f32) -> MassProperties
fn mass_properties(&self, density: f32) -> MassProperties
Source§fn shape_type(&self) -> ShapeType
fn shape_type(&self) -> ShapeType
Source§fn as_typed_shape(&self) -> TypedShape<'_>
fn as_typed_shape(&self) -> TypedShape<'_>
fn ccd_thickness(&self) -> f32
fn ccd_angular_thickness(&self) -> f32
Source§fn as_support_map(&self) -> Option<&dyn SupportMap>
fn as_support_map(&self) -> Option<&dyn SupportMap>
Source§fn as_polygonal_feature_map(&self) -> Option<(&dyn PolygonalFeatureMap, f32)>
fn as_polygonal_feature_map(&self) -> Option<(&dyn PolygonalFeatureMap, f32)>
Source§fn feature_normal_at_point(
&self,
feature: FeatureId,
_point: &Point<f32>,
) -> Option<Unit<Vector<f32>>>
fn feature_normal_at_point( &self, feature: FeatureId, _point: &Point<f32>, ) -> Option<Unit<Vector<f32>>>
Source§fn clone_box(&self) -> Box<dyn Shape>
fn clone_box(&self) -> Box<dyn Shape>
clone_dynSource§fn compute_bounding_sphere(&self, position: &Isometry<f32>) -> BoundingSphere
fn compute_bounding_sphere(&self, position: &Isometry<f32>) -> BoundingSphere
fn as_composite_shape(&self) -> Option<&dyn CompositeShape>
Source§impl SupportMap for ConvexPolygon
impl SupportMap for ConvexPolygon
Source§fn local_support_point(&self, dir: &Vector<f32>) -> Point<f32>
fn local_support_point(&self, dir: &Vector<f32>) -> Point<f32>
Auto Trait Implementations§
impl Freeze for ConvexPolygon
impl RefUnwindSafe for ConvexPolygon
impl Send for ConvexPolygon
impl Sync for ConvexPolygon
impl Unpin for ConvexPolygon
impl UnwindSafe for ConvexPolygon
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.