1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use core::fmt::Debug;
use nalgebra as na;
use petgraph;
use petgraph::graph::NodeIndex;
use petgraph::stable_graph::StableGraph;
pub(crate) type Point = na::Point3<f32>;
pub type VertexGraph = StableGraph<Point, (), petgraph::Undirected>;
#[derive(PartialEq, Eq, Copy, Clone, Debug, PartialOrd, Hash)]
pub struct VertexHandle {
pub(crate) ix: NodeIndex,
}
impl VertexHandle {
pub(crate) fn new(ix: NodeIndex) -> Self {
Self { ix }
}
}
pub(crate) struct WeightedValue<T> {
pub value: T,
pub weight: f32,
}
pub(crate) fn weighted_centroid(weighted_points: &[WeightedValue<&Point>]) -> Point {
let (mut x, mut y, mut z) = (0.0_f32, 0.0_f32, 0.0_f32);
let mut w_sum = 0.0;
for wp in weighted_points.iter() {
let weight = wp.weight;
let p = wp.value;
w_sum += weight;
x += p.x * weight;
y += p.y * weight;
z += p.z * weight;
}
x /= w_sum;
y /= w_sum;
z /= w_sum;
Point::new(x, y, z)
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Face {
pub(crate) nodes: Vec<VertexHandle>,
}
impl Face {
pub fn new(nodes: &[VertexHandle]) -> Face {
Face {
nodes: Vec::from(nodes),
}
}
pub(crate) fn from_node_index(nodes: &[NodeIndex]) -> Face {
Face {
nodes: nodes.iter().map(|n_ix| VertexHandle::new(*n_ix)).collect(),
}
}
pub(crate) fn new_triangle(nodes: &[VertexHandle; 3]) -> Face {
Face {
nodes: vec![nodes[0], nodes[1], nodes[2]],
}
}
pub fn nodes(&self) -> &[VertexHandle] {
&self.nodes
}
pub fn edges(&self) -> Vec<(VertexHandle, VertexHandle)> {
let mut edges = Vec::new();
let node_count = self.nodes.len();
for i in 0..node_count {
let node_a = self.nodes[i % node_count];
let node_b = self.nodes[(i + 1) % node_count];
edges.push((node_a, node_b));
}
edges
}
pub(crate) fn center(&self, graph: &VertexGraph) -> Point {
let sum: Point = self
.nodes
.iter()
.map(|node| graph.node_weight(node.ix).expect("Illegal node access"))
.fold(Point::new(0., 0., 0.), |acc, p| {
Point::from(acc.coords + p.coords)
});
sum / (self.nodes.len() as f32)
}
}