parry3d/transformation/to_trimesh/
ball_to_trimesh.rs1use crate::math::{ComplexField, Real, RealField, Vector, Vector3, DIM};
2use crate::shape::Ball;
3use crate::transformation::utils;
4use alloc::vec::Vec;
5
6impl Ball {
7 pub fn to_trimesh(
9 &self,
10 ntheta_subdiv: u32,
11 nphi_subdiv: u32,
12 ) -> (Vec<Vector3>, Vec<[u32; 3]>) {
13 let diameter = self.radius * 2.0;
14 let (vtx, idx) = unit_sphere(ntheta_subdiv, nphi_subdiv);
15 (utils::scaled(vtx, Vector::splat(diameter)), idx)
16 }
17}
18
19fn unit_sphere(ntheta_subdiv: u32, nphi_subdiv: u32) -> (Vec<Vector3>, Vec<[u32; 3]>) {
20 let dtheta = Real::two_pi() / (ntheta_subdiv as Real);
21 let dphi = Real::pi() / (nphi_subdiv as Real);
22
23 let mut coords = Vec::new();
24 let mut curr_phi: Real = -Real::frac_pi_2() + dphi;
25
26 coords.push(Vector::new(0.0, -1.0, 0.0));
27
28 for _ in 1..nphi_subdiv {
29 utils::push_circle(
30 <Real as ComplexField>::cos(curr_phi),
31 ntheta_subdiv,
32 dtheta,
33 <Real as ComplexField>::sin(curr_phi),
34 &mut coords,
35 );
36 curr_phi += dphi;
37 }
38
39 coords.push(Vector::new(0.0, 1.0, 0.0));
40
41 let mut idx = Vec::new();
42
43 utils::push_degenerate_top_ring_indices(1, 0, ntheta_subdiv, &mut idx);
44 utils::reverse_clockwising(&mut idx);
45
46 for i in 0..nphi_subdiv - 2 {
47 utils::push_ring_indices(
48 1 + i * ntheta_subdiv,
49 1 + (i + 1) * ntheta_subdiv,
50 ntheta_subdiv,
51 &mut idx,
52 );
53 }
54
55 utils::push_degenerate_top_ring_indices(
56 coords.len() as u32 - 1 - ntheta_subdiv,
57 coords.len() as u32 - 1,
58 ntheta_subdiv,
59 &mut idx,
60 );
61
62 (utils::scaled(coords, Vector::splat(0.5)), idx)
63}
64
65pub(crate) fn unit_hemisphere(
67 ntheta_subdiv: u32,
68 nphi_subdiv: u32,
69) -> (Vec<Vector>, Vec<[u32; DIM]>) {
70 let two_pi = Real::two_pi();
71 let pi_two = Real::frac_pi_2();
72 let dtheta = two_pi / (ntheta_subdiv as Real);
73 let dphi = pi_two / (nphi_subdiv as Real);
74
75 let mut coords = Vec::new();
76 let mut curr_phi: Real = 0.0;
77
78 for _ in 0..nphi_subdiv {
79 utils::push_circle(
80 <Real as ComplexField>::cos(curr_phi),
81 ntheta_subdiv,
82 dtheta,
83 <Real as ComplexField>::sin(curr_phi),
84 &mut coords,
85 );
86 curr_phi += dphi;
87 }
88
89 coords.push(Vector::new(0.0, 1.0, 0.0));
90
91 let mut idx = Vec::new();
92
93 for i in 0..nphi_subdiv - 1 {
94 utils::push_ring_indices(
95 i * ntheta_subdiv,
96 (i + 1) * ntheta_subdiv,
97 ntheta_subdiv,
98 &mut idx,
99 );
100 }
101
102 utils::push_degenerate_top_ring_indices(
103 (nphi_subdiv - 1) * ntheta_subdiv,
104 coords.len() as u32 - 1,
105 ntheta_subdiv,
106 &mut idx,
107 );
108
109 (utils::scaled(coords, Vector::splat(0.5)), idx)
110}