parry2d/shape/
polygonal_feature_map.rs1use crate::math::Vector;
2#[cfg(feature = "dim3")]
3use crate::shape::{Cone, Cylinder, PackedFeatureId};
4use crate::shape::{Cuboid, PolygonalFeature, Segment, SupportMap, Triangle};
5
6pub trait PolygonalFeatureMap: SupportMap {
8 fn local_support_feature(&self, dir: Vector, out_feature: &mut PolygonalFeature);
10
11 fn is_convex_polyhedron(&self) -> bool {
16 false
17 }
18}
19
20impl PolygonalFeatureMap for Segment {
21 fn local_support_feature(&self, _: Vector, out_feature: &mut PolygonalFeature) {
22 *out_feature = PolygonalFeature::from(*self);
23 }
24}
25
26impl PolygonalFeatureMap for Triangle {
27 fn local_support_feature(&self, dir: Vector, out_feature: &mut PolygonalFeature) {
28 *out_feature = self.support_face(dir);
29 }
30}
31
32impl PolygonalFeatureMap for Cuboid {
33 fn local_support_feature(&self, dir: Vector, out_feature: &mut PolygonalFeature) {
34 *out_feature = self.support_face(dir);
35 }
36}
37
38#[cfg(feature = "dim3")]
39impl PolygonalFeatureMap for Cylinder {
40 fn local_support_feature(&self, dir: Vector, out_features: &mut PolygonalFeature) {
41 use crate::math::Vector2;
42
43 let dir2 = Vector2::new(dir.x, dir.z)
58 .try_normalize()
59 .unwrap_or(Vector2::X);
60
61 if dir.y.abs() < 0.5 {
62 out_features.vertices[0] = Vector::new(
64 dir2.x * self.radius,
65 -self.half_height,
66 dir2.y * self.radius,
67 );
68 out_features.vertices[1] =
69 Vector::new(dir2.x * self.radius, self.half_height, dir2.y * self.radius);
70 out_features.eids = PackedFeatureId::edges([0, 0, 0, 0]);
71 out_features.fid = PackedFeatureId::face(0);
72 out_features.num_vertices = 2;
73 out_features.vids = PackedFeatureId::vertices([1, 11, 11, 11]);
74 } else {
75 let y = self.half_height.copysign(dir.y);
77 out_features.vertices[0] = Vector::new(dir2.x * self.radius, y, dir2.y * self.radius);
78 out_features.vertices[1] = Vector::new(-dir2.y * self.radius, y, dir2.x * self.radius);
79 out_features.vertices[2] = Vector::new(-dir2.x * self.radius, y, -dir2.y * self.radius);
80 out_features.vertices[3] = Vector::new(dir2.y * self.radius, y, -dir2.x * self.radius);
81
82 if dir.y < 0.0 {
83 out_features.eids = PackedFeatureId::edges([2, 4, 6, 8]);
84 out_features.fid = PackedFeatureId::face(9);
85 out_features.num_vertices = 4;
86 out_features.vids = PackedFeatureId::vertices([1, 3, 5, 7]);
87 } else {
88 out_features.eids = PackedFeatureId::edges([12, 14, 16, 18]);
89 out_features.fid = PackedFeatureId::face(19);
90 out_features.num_vertices = 4;
91 out_features.vids = PackedFeatureId::vertices([11, 13, 15, 17]);
92 }
93 }
94 }
95}
96
97#[cfg(feature = "dim3")]
98impl PolygonalFeatureMap for Cone {
99 fn local_support_feature(&self, dir: Vector, out_features: &mut PolygonalFeature) {
100 use crate::math::Vector2;
101
102 let dir2 = Vector2::new(dir.x, dir.z)
115 .try_normalize()
116 .unwrap_or(Vector2::X);
117
118 if dir.y > 0.0 {
119 out_features.vertices[0] = Vector::new(
121 dir2.x * self.radius,
122 -self.half_height,
123 dir2.y * self.radius,
124 );
125 out_features.vertices[1] = Vector::new(0.0, self.half_height, 0.0);
126 out_features.eids = PackedFeatureId::edges([0, 0, 0, 0]);
127 out_features.fid = PackedFeatureId::face(0);
128 out_features.num_vertices = 2;
129 out_features.vids = PackedFeatureId::vertices([1, 11, 11, 11]);
130 } else {
131 let y = -self.half_height;
133 out_features.vertices[0] = Vector::new(dir2.x * self.radius, y, dir2.y * self.radius);
134 out_features.vertices[1] = Vector::new(-dir2.y * self.radius, y, dir2.x * self.radius);
135 out_features.vertices[2] = Vector::new(-dir2.x * self.radius, y, -dir2.y * self.radius);
136 out_features.vertices[3] = Vector::new(dir2.y * self.radius, y, -dir2.x * self.radius);
137
138 out_features.eids = PackedFeatureId::edges([2, 4, 6, 8]);
139 out_features.fid = PackedFeatureId::face(9);
140 out_features.num_vertices = 4;
141 out_features.vids = PackedFeatureId::vertices([1, 3, 5, 7]);
142 }
143 }
144}