parry3d/mass_properties/mass_properties_convex_polyhedron.rs
1use crate::mass_properties::MassProperties;
2use crate::math::{Point, Real, DIM};
3
4impl MassProperties {
5 /// Computes the mass properties of a convex polyhedron (3D) or polygon (2D).
6 ///
7 /// A convex polyhedron is a 3D solid where all faces are flat and all vertices point
8 /// outward. This is a convenience function that delegates to `from_trimesh()`, which
9 /// handles the actual computation by treating the polyhedron as a triangle mesh.
10 ///
11 /// # Arguments
12 ///
13 /// * `density` - The material density
14 /// - In 3D: kg/m³ (mass per unit volume)
15 /// - In 2D: kg/m² (mass per unit area)
16 /// * `vertices` - Array of vertex positions defining the polyhedron
17 /// * `indices` - Array of triangle indices
18 /// - In 3D: Each element is `[u32; 3]` indexing into vertices array
19 /// - In 2D: Each element is `[u32; 2]` for line segments
20 ///
21 /// # Returns
22 ///
23 /// A `MassProperties` struct containing:
24 /// - **mass**: Total mass calculated from volume/area and density
25 /// - **local_com**: Center of mass (volume-weighted centroid)
26 /// - **inv_principal_inertia**: Inverse angular inertia tensor
27 ///
28 /// # Example (3D) - Tetrahedron
29 ///
30 /// ```
31 /// # #[cfg(all(feature = "dim3", feature = "f32"))] {
32 /// use parry3d::mass_properties::MassProperties;
33 /// use nalgebra::Point3;
34 ///
35 /// // Create a regular tetrahedron (4 vertices, 4 triangular faces)
36 /// let vertices = vec![
37 /// Point3::new(1.0, 0.0, 0.0),
38 /// Point3::new(0.0, 1.0, 0.0),
39 /// Point3::new(0.0, 0.0, 1.0),
40 /// Point3::origin(),
41 /// ];
42 ///
43 /// let indices = vec![
44 /// [0, 1, 2], // Face 1
45 /// [0, 1, 3], // Face 2
46 /// [0, 2, 3], // Face 3
47 /// [1, 2, 3], // Face 4
48 /// ];
49 ///
50 /// let density = 1000.0;
51 /// let tetra_props = MassProperties::from_convex_polyhedron(density, &vertices, &indices);
52 ///
53 /// println!("Tetrahedron mass: {:.4} kg", tetra_props.mass());
54 /// println!("Center of mass: {:?}", tetra_props.local_com);
55 /// # }
56 /// ```
57 ///
58 /// # Example (3D) - Octahedron
59 ///
60 /// ```
61 /// # #[cfg(all(feature = "dim3", feature = "f32"))] {
62 /// use parry3d::mass_properties::MassProperties;
63 /// use nalgebra::Point3;
64 ///
65 /// // Regular octahedron (6 vertices, 8 triangular faces)
66 /// let vertices = vec![
67 /// Point3::new(1.0, 0.0, 0.0), // +X
68 /// Point3::new(-1.0, 0.0, 0.0), // -X
69 /// Point3::new(0.0, 1.0, 0.0), // +Y
70 /// Point3::new(0.0, -1.0, 0.0), // -Y
71 /// Point3::new(0.0, 0.0, 1.0), // +Z
72 /// Point3::new(0.0, 0.0, -1.0), // -Z
73 /// ];
74 ///
75 /// let indices = vec![
76 /// [0, 2, 4], [0, 4, 3], [0, 3, 5], [0, 5, 2], // Right hemisphere
77 /// [1, 4, 2], [1, 3, 4], [1, 5, 3], [1, 2, 5], // Left hemisphere
78 /// ];
79 ///
80 /// let density = 800.0;
81 /// let octa_props = MassProperties::from_convex_polyhedron(density, &vertices, &indices);
82 ///
83 /// println!("Octahedron mass: {:.2} kg", octa_props.mass());
84 /// # }
85 /// ```
86 ///
87 /// # Use Cases
88 ///
89 /// - **Custom 3D shapes**: Game objects with specific polyhedral geometry
90 /// - **Crystalline structures**: Geometric solids (tetrahedra, octahedra, dodecahedra)
91 /// - **Simplified models**: Convex approximations of complex shapes
92 /// - **Gems and jewels**: Faceted objects
93 /// - **Dice**: Polyhedral game dice (d4, d6, d8, d12, d20)
94 ///
95 /// # Requirements
96 ///
97 /// - **Must be convex**: All faces must be flat and point outward
98 /// - **Closed mesh**: Triangles must form a watertight volume
99 /// - **Consistent winding**: Triangle vertices should follow consistent order
100 /// (counter-clockwise when viewed from outside)
101 /// - **Valid indices**: All index values must be < vertices.len()
102 ///
103 /// # Convex vs Non-Convex
104 ///
105 /// This function assumes the shape is convex. For non-convex (concave) meshes:
106 /// - The result may be incorrect
107 /// - Consider using `from_compound()` with a convex decomposition
108 /// - Or use `from_trimesh()` directly (handles both convex and concave)
109 ///
110 /// # Implementation Note
111 ///
112 /// This function is a thin wrapper around `from_trimesh()`. Both produce identical
113 /// results. Use `from_convex_polyhedron()` when you know the shape is convex to
114 /// make intent clear in code.
115 ///
116 /// # See Also
117 ///
118 /// - `from_trimesh()`: For general triangle meshes (convex or concave)
119 /// - `from_convex_polygon()`: For 2D convex polygons
120 /// - `from_compound()`: For combining multiple convex shapes
121 pub fn from_convex_polyhedron(
122 density: Real,
123 vertices: &[Point<Real>],
124 indices: &[[u32; DIM]],
125 ) -> MassProperties {
126 Self::from_trimesh(density, vertices, indices)
127 }
128}