@@ -83,37 +83,6 @@ pub fn extract_vertices(icosphere: &IcoSphere) -> Vec<Vector3> {
8383pub fn make_weights ( icosphere : & IcoSphere ) -> Vec < f64 > {
8484 let indices = icosphere. get_all_indices ( ) ;
8585 let vertices = icosphere. raw_points ( ) ;
86-
87- // flat (euclidean) face area
88- let _flat_face_area = |a : usize , b : usize , c : usize | {
89- let a = vertices[ a] ;
90- let b = vertices[ b] ;
91- let c = vertices[ c] ;
92- let ab = b - a;
93- let ac = c - a;
94- 0.5 * ab. cross ( ac) . length ( )
95- } ;
96-
97- // spherical face area
98- #[ allow( non_snake_case) ]
99- let spherical_face_area = |a : usize , b : usize , c : usize | {
100- let a = & vertices[ a] . normalize ( ) ;
101- let b = & vertices[ b] . normalize ( ) ;
102- let c = & vertices[ c] . normalize ( ) ;
103-
104- let angle = |u : & Vec3A , v : & Vec3A , w : & Vec3A | {
105- let vu = ( u - v * v. dot ( * u) ) . normalize ( ) ;
106- let vw = ( w - v * v. dot ( * w) ) . normalize ( ) ;
107- vu. angle_between ( vw)
108- } ;
109-
110- let A = angle ( b, a, c) ;
111- let B = angle ( c, b, a) ;
112- let C = angle ( a, c, b) ;
113-
114- ( A + B + C ) as f64 - PI
115- } ;
116-
11786 let mut weights = Vec :: with_capacity ( vertices. len ( ) ) ;
11887 let mut adjency = AdjacencyBuilder :: new ( vertices. len ( ) ) ;
11988 adjency. add_indices ( & indices) ;
@@ -123,27 +92,62 @@ pub fn make_weights(icosphere: &IcoSphere) -> Vec<f64> {
12392 let mut areas = Vec :: with_capacity ( neighbors. len ( ) ) ;
12493 // Handle the face made of i with the first and last neighboring vertices
12594 areas. push ( spherical_face_area (
126- i ,
127- * neighbors. first ( ) . unwrap ( ) ,
128- * neighbors. last ( ) . unwrap ( ) ,
95+ & vertices [ i ] ,
96+ & vertices [ * neighbors. first ( ) . unwrap ( ) ] ,
97+ & vertices [ * neighbors. last ( ) . unwrap ( ) ] ,
12998 ) ) ;
130- // Handle the faces made of i with each remaining pair of neighboring vertices
99+ // Handle the faces made of i with each remaining pairs of neighboring vertices
131100 for j in 0 ..neighbors. len ( ) - 1 {
132- let area = spherical_face_area ( i, neighbors[ j] , neighbors[ j + 1 ] ) ;
101+ let area = spherical_face_area (
102+ & vertices[ i] ,
103+ & vertices[ neighbors[ j] ] ,
104+ & vertices[ neighbors[ j + 1 ] ] ,
105+ ) ;
133106 areas. push ( area) ;
134107 }
135108 let avg_area = areas. iter ( ) . sum :: < f64 > ( ) / areas. len ( ) as f64 ;
136109 weights. push ( avg_area) ;
137110 }
138111 assert_eq ! ( weights. len( ) , vertices. len( ) ) ;
139112
140- // Normalize the weights to that they fluctuate around 1.0
113+ // Normalize the weights so that they fluctuate around 1.0
141114 // (this has no effect on final results)
142115 let scale = vertices. len ( ) as f64 / weights. iter ( ) . sum :: < f64 > ( ) ;
143116 weights. iter_mut ( ) . for_each ( |w| * w *= scale) ;
144117 weights
145118}
146119
120+ /// Calculate the spherical face area of a triangle defined by three vertices
121+ #[ allow( non_snake_case) ]
122+ fn spherical_face_area ( a : & Vec3A , b : & Vec3A , c : & Vec3A ) -> f64 {
123+ let a = & a. normalize ( ) ;
124+ let b = & b. normalize ( ) ;
125+ let c = & c. normalize ( ) ;
126+
127+ let angle = |u : & Vec3A , v : & Vec3A , w : & Vec3A | {
128+ let vu = ( u - v * v. dot ( * u) ) . normalize ( ) ;
129+ let vw = ( w - v * v. dot ( * w) ) . normalize ( ) ;
130+ vu. angle_between ( vw)
131+ } ;
132+
133+ let A = angle ( b, a, c) ;
134+ let B = angle ( c, b, a) ;
135+ let C = angle ( a, c, b) ;
136+
137+ ( A + B + C ) as f64 - PI
138+ }
139+
140+ /// Calculate the euclidian (flat) face area of a triangle defined by three vertices
141+ #[ allow( unused) ]
142+ fn flat_face_area ( a : & Vec3A , b : & Vec3A , c : & Vec3A ) -> f64 {
143+ let a = a. normalize ( ) ;
144+ let b = b. normalize ( ) ;
145+ let c = c. normalize ( ) ;
146+ let ab = b - a;
147+ let ac = c - a;
148+ 0.5 * ab. cross ( ac) . length ( ) as f64
149+ }
150+
147151#[ cfg( test) ]
148152mod tests {
149153 use super :: * ;
0 commit comments