use super::functions::*;
#[derive(Debug, Clone)]
pub struct IsolineSegment {
pub start: [f64; 3],
pub end: [f64; 3],
}
#[derive(Debug, Clone)]
pub struct GeoVoronoiCell {
pub source_idx: usize,
pub source_vertex: usize,
pub vertices: Vec<usize>,
pub area: f64,
}
#[derive(Debug, Clone)]
pub struct IntrinsicDelaunay {
pub edge_lengths: Vec<[f64; 3]>,
pub faces: Vec<[usize; 3]>,
pub vertices: Vec<[f64; 3]>,
}
#[derive(Debug, Clone)]
pub struct GeoMesh {
pub vertices: Vec<[f64; 3]>,
pub faces: Vec<[usize; 3]>,
}
impl GeoMesh {
pub fn new(vertices: Vec<[f64; 3]>, faces: Vec<[usize; 3]>) -> Self {
Self { vertices, faces }
}
pub fn n_vertices(&self) -> usize {
self.vertices.len()
}
pub fn n_faces(&self) -> usize {
self.faces.len()
}
pub fn build_adjacency(&self) -> Vec<Vec<(usize, f64)>> {
let n = self.vertices.len();
let mut adj: Vec<Vec<(usize, f64)>> = vec![Vec::new(); n];
for face in &self.faces {
let [a, b, c] = *face;
let lab = dist3(self.vertices[a], self.vertices[b]);
let lbc = dist3(self.vertices[b], self.vertices[c]);
let lca = dist3(self.vertices[c], self.vertices[a]);
adj[a].push((b, lab));
adj[b].push((a, lab));
adj[b].push((c, lbc));
adj[c].push((b, lbc));
adj[c].push((a, lca));
adj[a].push((c, lca));
}
adj
}
pub fn face_area(&self, face_idx: usize) -> f64 {
let [a, b, c] = self.faces[face_idx];
let va = self.vertices[a];
let vb = self.vertices[b];
let vc = self.vertices[c];
let ab = sub3(vb, va);
let ac = sub3(vc, va);
len3(cross3(ab, ac)) * 0.5
}
pub fn face_normal_raw(&self, face_idx: usize) -> [f64; 3] {
let [a, b, c] = self.faces[face_idx];
let ab = sub3(self.vertices[b], self.vertices[a]);
let ac = sub3(self.vertices[c], self.vertices[a]);
cross3(ab, ac)
}
}
pub struct HeatGeodesicResult {
pub distances: Vec<f64>,
pub gradient: Vec<[f64; 3]>,
}
#[derive(PartialEq)]
pub(super) struct DijkEntry {
pub(super) dist: f64,
pub(super) vertex: usize,
}