Skip to content

Commit 173c613

Browse files
author
mlund
committed
Refactor area/weight functions
1 parent 1f4cb00 commit 173c613

File tree

2 files changed

+43
-39
lines changed

2 files changed

+43
-39
lines changed

src/icosphere.rs

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -83,37 +83,6 @@ pub fn extract_vertices(icosphere: &IcoSphere) -> Vec<Vector3> {
8383
pub 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)]
148152
mod tests {
149153
use super::*;

src/sample.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ impl Sample {
7070
}
7171
/// Free energy (kJ / mol)
7272
pub fn free_energy(&self) -> f64 {
73-
(self.exp_energy / self.degeneracy as f64).ln().neg() * self.thermal_energy
73+
(self.exp_energy / self.degeneracy).ln().neg() * self.thermal_energy
7474
}
7575
/// Mean <exp(-U/kT)-1>
7676
pub fn mean_exp_energy_m1(&self) -> f64 {
77-
self.exp_energy_m1 / self.degeneracy as f64
77+
self.exp_energy_m1 / self.degeneracy
7878
}
7979
/// Number of samples
8080
pub fn n(&self) -> u64 {

0 commit comments

Comments
 (0)