2024-04-07 19:15:39 +03:00
|
|
|
use rand::Rng;
|
2024-04-08 11:44:21 +03:00
|
|
|
use simple_delaunay_lib::delaunay_3d::delaunay_struct_3d::ExtendedTetrahedron;
|
2024-04-07 19:15:39 +03:00
|
|
|
use simple_delaunay_lib::delaunay_3d::simplicial_struct_3d::Node;
|
|
|
|
|
use std::cmp::{min, max};
|
|
|
|
|
use std::collections::HashSet;
|
|
|
|
|
|
|
|
|
|
use super::{Edge, Xenobalanus};
|
|
|
|
|
|
2024-04-08 11:44:21 +03:00
|
|
|
#[derive(Debug, Clone, Copy)]
|
2024-04-07 19:15:39 +03:00
|
|
|
pub struct Point3D {
|
|
|
|
|
x: f32,
|
|
|
|
|
y: f32,
|
|
|
|
|
z: f32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Point3D {
|
|
|
|
|
|
|
|
|
|
pub fn new(coords: (f32, f32, f32)) -> Point3D {
|
|
|
|
|
Point3D {x: coords.0, y: coords.1, z: coords.2 }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn arr(&self) -> [f64; 3] {
|
|
|
|
|
[self.x as f64, self.y as f64, self.z as f64]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn distance(&self,point: &Point3D) -> f32 {
|
|
|
|
|
(
|
|
|
|
|
(point.x - &self.x).powi(2) +
|
|
|
|
|
(point.y - &self.y).powi(2) +
|
|
|
|
|
(point.z - &self.z).powi(2)
|
|
|
|
|
).sqrt()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Xenobalanus {
|
|
|
|
|
|
2024-04-08 11:44:21 +03:00
|
|
|
pub fn point_3d(&self, index: usize) -> Point3D {
|
|
|
|
|
self.nodes[index]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn points_3d(&self) -> Vec<(f32, f32, f32)> {
|
|
|
|
|
self.nodes.iter()
|
|
|
|
|
.map(|point| (point.x, point.y, point.z))
|
|
|
|
|
.collect()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn tetrahedra(&self) -> Vec<[[f32; 3]; 2]> {
|
|
|
|
|
let total = self.tetrahedra.get_simplicial().get_nb_tetrahedra();
|
|
|
|
|
let mut edges: Vec<[[f32; 3]; 2]> = vec![];
|
|
|
|
|
for idx in 0..total {
|
|
|
|
|
match self.tetrahedra.get_extended_tetrahedron(idx) {
|
|
|
|
|
Ok(tet) => {
|
|
|
|
|
match tet {
|
|
|
|
|
ExtendedTetrahedron::Tetrahedron(te) => {
|
|
|
|
|
edges.push([
|
|
|
|
|
[te[0][0] as f32, te[0][1] as f32, te[0][2] as f32],
|
|
|
|
|
[te[1][0] as f32, te[1][1] as f32, te[1][2] as f32]
|
|
|
|
|
]);
|
|
|
|
|
edges.push([
|
|
|
|
|
[te[1][0] as f32, te[1][1] as f32, te[1][2] as f32],
|
|
|
|
|
[te[2][0] as f32, te[2][1] as f32, te[2][2] as f32]
|
|
|
|
|
]);
|
|
|
|
|
edges.push([
|
|
|
|
|
[te[2][0] as f32, te[2][1] as f32, te[2][2] as f32],
|
|
|
|
|
[te[0][0] as f32, te[0][1] as f32, te[0][2] as f32]
|
|
|
|
|
]);
|
|
|
|
|
edges.push([
|
|
|
|
|
[te[3][0] as f32, te[3][1] as f32, te[3][2] as f32],
|
|
|
|
|
[te[0][0] as f32, te[0][1] as f32, te[0][2] as f32]
|
|
|
|
|
]);
|
|
|
|
|
edges.push([
|
|
|
|
|
[te[3][0] as f32, te[3][1] as f32, te[3][2] as f32],
|
|
|
|
|
[te[1][0] as f32, te[1][1] as f32, te[1][2] as f32]
|
|
|
|
|
]);
|
|
|
|
|
edges.push([
|
|
|
|
|
[te[3][0] as f32, te[3][1] as f32, te[3][2] as f32],
|
|
|
|
|
[te[2][0] as f32, te[2][1] as f32, te[2][2] as f32]
|
|
|
|
|
]);
|
|
|
|
|
},
|
|
|
|
|
ExtendedTetrahedron::Triangle(te) => {
|
|
|
|
|
edges.push([
|
|
|
|
|
[te[0][0] as f32, te[0][1] as f32, te[0][2] as f32],
|
|
|
|
|
[te[1][0] as f32, te[1][1] as f32, te[1][2] as f32]
|
|
|
|
|
]);
|
|
|
|
|
edges.push([
|
|
|
|
|
[te[1][0] as f32, te[1][1] as f32, te[1][2] as f32],
|
|
|
|
|
[te[2][0] as f32, te[2][1] as f32, te[2][2] as f32]
|
|
|
|
|
]);
|
|
|
|
|
edges.push([
|
|
|
|
|
[te[2][0] as f32, te[2][1] as f32, te[2][2] as f32],
|
|
|
|
|
[te[0][0] as f32, te[0][1] as f32, te[0][2] as f32]
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
Err(_) => {
|
|
|
|
|
println!("Error getting tetrahedron at index {}", idx);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
edges
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-08 11:48:00 +03:00
|
|
|
pub fn random_points_3d(&mut self, center: (f32, f32, f32), side_length: f32, num_points: u32) {
|
2024-04-07 19:15:39 +03:00
|
|
|
|
|
|
|
|
// generate random points in a cube
|
|
|
|
|
let min_x = center.0 - side_length / 2.0;
|
|
|
|
|
let max_x = center.0 + side_length / 2.0;
|
|
|
|
|
let min_y = center.1 - side_length / 2.0;
|
|
|
|
|
let max_y = center.1 + side_length / 2.0;
|
2024-04-08 11:48:00 +03:00
|
|
|
let min_z = center.2 - side_length / 2.0;
|
|
|
|
|
let max_z = center.2 + side_length / 2.0;
|
2024-04-07 19:15:39 +03:00
|
|
|
let mut rng: rand::prelude::ThreadRng = rand::thread_rng();
|
|
|
|
|
for _ in 0..num_points {
|
|
|
|
|
let x = min_x + rng.gen_range(0.0..=1.0) as f32 * ( max_x - min_x);
|
|
|
|
|
let y: f32 = min_y + rng.gen_range(0.0..=1.0) as f32 * ( max_y - min_y);
|
|
|
|
|
let z: f32 = min_y + rng.gen_range(0.0..=1.0) as f32 * ( max_z - min_z);
|
|
|
|
|
self.nodes.push(Point3D {x, y, z});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn delaunay_3d(&mut self) {
|
|
|
|
|
|
|
|
|
|
let vertices: Vec<[f64; 3]> = self.nodes.iter().map(|node| {
|
|
|
|
|
node.arr()
|
|
|
|
|
}).collect();
|
2024-04-08 11:44:21 +03:00
|
|
|
self.tetrahedra.insert_vertices(&vertices, true).unwrap_or_default();
|
2024-04-07 19:15:39 +03:00
|
|
|
}
|
|
|
|
|
|
2024-04-07 19:26:41 +03:00
|
|
|
pub fn add_triangle(&mut self, vertex1: usize, vertex2: usize, vertex3: usize) {
|
2024-04-07 19:15:39 +03:00
|
|
|
|
2024-04-08 11:44:21 +03:00
|
|
|
let p1 = self.tetrahedra.get_vertices()[vertex1];
|
|
|
|
|
let p2 = self.tetrahedra.get_vertices()[vertex2];
|
|
|
|
|
let p3 = self.tetrahedra.get_vertices()[vertex3];
|
2024-04-07 19:15:39 +03:00
|
|
|
|
|
|
|
|
let n1 = Point3D::new((p1[0] as f32, p1[1] as f32, p1[2] as f32));
|
|
|
|
|
let n2 = Point3D::new((p2[0] as f32, p2[1] as f32, p2[2] as f32));
|
|
|
|
|
let n3 = Point3D::new((p3[0] as f32, p3[1] as f32, p3[2] as f32));
|
|
|
|
|
|
|
|
|
|
let l12 = n1.distance(&n2);
|
|
|
|
|
let l23 = n2.distance(&n3);
|
|
|
|
|
let l31 = n3.distance(&n1);
|
|
|
|
|
|
2024-04-07 19:26:41 +03:00
|
|
|
let edge12 = Edge(min(vertex1, vertex2), max(vertex1, vertex2));
|
|
|
|
|
let edge23 = Edge(min(vertex2, vertex3), max(vertex2, vertex3));
|
|
|
|
|
let edge31 = Edge(min(vertex3, vertex1), max(vertex3, vertex1));
|
2024-04-07 19:15:39 +03:00
|
|
|
|
2024-04-07 19:26:41 +03:00
|
|
|
self.geometry_data.edge_lengths.insert(edge12, l12);
|
|
|
|
|
self.geometry_data.edge_lengths.insert(edge23, l23);
|
|
|
|
|
self.geometry_data.edge_lengths.insert(edge31, l31);
|
2024-04-07 19:15:39 +03:00
|
|
|
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex1).or_insert_with(HashSet::new).insert(vertex2);
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex2).or_insert_with(HashSet::new).insert(vertex1);
|
2024-04-07 19:26:41 +03:00
|
|
|
|
2024-04-07 19:15:39 +03:00
|
|
|
self.geometry_data.vertex_connections.entry(vertex2).or_insert_with(HashSet::new).insert(vertex3);
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex3).or_insert_with(HashSet::new).insert(vertex2);
|
2024-04-07 19:26:41 +03:00
|
|
|
|
2024-04-07 19:15:39 +03:00
|
|
|
self.geometry_data.vertex_connections.entry(vertex3).or_insert_with(HashSet::new).insert(vertex1);
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex1).or_insert_with(HashSet::new).insert(vertex3);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn add_tetrahedron(&mut self, vertex1: usize, vertex2: usize, vertex3: usize, vertex4: usize) {
|
|
|
|
|
|
2024-04-08 11:44:21 +03:00
|
|
|
let p1 = self.tetrahedra.get_vertices()[vertex1];
|
|
|
|
|
let p2 = self.tetrahedra.get_vertices()[vertex2];
|
|
|
|
|
let p3 = self.tetrahedra.get_vertices()[vertex3];
|
|
|
|
|
let p4 = self.tetrahedra.get_vertices()[vertex4];
|
2024-04-07 19:15:39 +03:00
|
|
|
|
|
|
|
|
let n1 = Point3D::new((p1[0] as f32, p1[1] as f32, p1[2] as f32));
|
|
|
|
|
let n2 = Point3D::new((p2[0] as f32, p2[1] as f32, p2[2] as f32));
|
|
|
|
|
let n3 = Point3D::new((p3[0] as f32, p3[1] as f32, p3[2] as f32));
|
|
|
|
|
let n4 = Point3D::new((p4[0] as f32, p4[1] as f32, p4[2] as f32));
|
|
|
|
|
|
|
|
|
|
let l12 = &n1.distance(&n2);
|
|
|
|
|
let l23 = &n2.distance(&n3);
|
2024-04-07 19:26:41 +03:00
|
|
|
let l31 = &n3.distance(&n1);
|
2024-04-07 19:15:39 +03:00
|
|
|
let l41 = &n4.distance(&n1);
|
2024-04-07 19:26:41 +03:00
|
|
|
let l42 = &n4.distance(&n2);
|
|
|
|
|
let l43 = &n4.distance(&n3);
|
|
|
|
|
|
|
|
|
|
let edge12 = Edge(min(vertex1, vertex2), max(vertex1, vertex2));
|
|
|
|
|
let edge23 = Edge(min(vertex2, vertex3), max(vertex2, vertex3));
|
|
|
|
|
let edge31 = Edge(min(vertex3, vertex1), max(vertex3, vertex1));
|
|
|
|
|
let edge41 = Edge(min(vertex4, vertex1), max(vertex4, vertex1));
|
|
|
|
|
let edge42 = Edge(min(vertex4, vertex2), max(vertex4, vertex2));
|
|
|
|
|
let edge43 = Edge(min(vertex4, vertex3), max(vertex4, vertex3));
|
|
|
|
|
|
|
|
|
|
self.geometry_data.edge_lengths.insert(edge12, *l12);
|
|
|
|
|
self.geometry_data.edge_lengths.insert(edge23, *l23);
|
|
|
|
|
self.geometry_data.edge_lengths.insert(edge31, *l31);
|
|
|
|
|
self.geometry_data.edge_lengths.insert(edge41, *l41);
|
|
|
|
|
self.geometry_data.edge_lengths.insert(edge42, *l42);
|
|
|
|
|
self.geometry_data.edge_lengths.insert(edge43, *l43);
|
2024-04-07 19:15:39 +03:00
|
|
|
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex1).or_insert_with(HashSet::new).insert(vertex2);
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex2).or_insert_with(HashSet::new).insert(vertex1);
|
2024-04-07 19:26:41 +03:00
|
|
|
|
2024-04-07 19:15:39 +03:00
|
|
|
self.geometry_data.vertex_connections.entry(vertex2).or_insert_with(HashSet::new).insert(vertex3);
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex3).or_insert_with(HashSet::new).insert(vertex2);
|
2024-04-07 19:26:41 +03:00
|
|
|
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex3).or_insert_with(HashSet::new).insert(vertex1);
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex1).or_insert_with(HashSet::new).insert(vertex3);
|
|
|
|
|
|
2024-04-07 19:15:39 +03:00
|
|
|
self.geometry_data.vertex_connections.entry(vertex4).or_insert_with(HashSet::new).insert(vertex1);
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex1).or_insert_with(HashSet::new).insert(vertex4);
|
2024-04-07 19:26:41 +03:00
|
|
|
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex4).or_insert_with(HashSet::new).insert(vertex2);
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex2).or_insert_with(HashSet::new).insert(vertex4);
|
|
|
|
|
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex4).or_insert_with(HashSet::new).insert(vertex3);
|
|
|
|
|
self.geometry_data.vertex_connections.entry(vertex3).or_insert_with(HashSet::new).insert(vertex4);
|
2024-04-07 19:15:39 +03:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn preprocess_3d(&mut self) {
|
2024-04-08 11:44:21 +03:00
|
|
|
let structure = self.tetrahedra.get_simplicial();
|
2024-04-07 19:15:39 +03:00
|
|
|
let num_tetras = structure.get_nb_tetrahedra();
|
|
|
|
|
|
|
|
|
|
for tetra_idx in 0..num_tetras {
|
2024-04-08 11:44:21 +03:00
|
|
|
let tetrahedron = match self.tetrahedra.get_simplicial().get_tetrahedron(tetra_idx) {
|
2024-04-07 19:15:39 +03:00
|
|
|
Ok(tetra) => tetra.nodes(),
|
|
|
|
|
Err(_) => {
|
|
|
|
|
println!("Error getting tetrahedron at index {}", tetra_idx);
|
|
|
|
|
continue; // Skip this iteration and proceed with the next one
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let [node1, node2, node3, node4] = tetrahedron;
|
|
|
|
|
match (node1, node2, node3, node4) {
|
|
|
|
|
(Node::Infinity, Node::Value(ind_v2), Node::Value(ind_v3), Node::Value(ind_v4)) => {
|
2024-04-07 19:26:41 +03:00
|
|
|
self.add_triangle(ind_v2, ind_v3, ind_v4);
|
2024-04-07 19:15:39 +03:00
|
|
|
},
|
|
|
|
|
(Node::Value(ind_v1), Node::Infinity, Node::Value(ind_v3), Node::Value(ind_v4)) => {
|
2024-04-07 19:26:41 +03:00
|
|
|
self.add_triangle(ind_v3, ind_v4, ind_v1);
|
2024-04-07 19:15:39 +03:00
|
|
|
},
|
|
|
|
|
(Node::Value(ind_v1), Node::Value(ind_v2), Node::Infinity, Node::Value(ind_v4)) => {
|
2024-04-07 19:26:41 +03:00
|
|
|
self.add_triangle(ind_v4, ind_v1, ind_v2);
|
2024-04-07 19:15:39 +03:00
|
|
|
},
|
|
|
|
|
(Node::Value(ind_v1), Node::Value(ind_v2), Node::Value(ind_v3), Node::Infinity) => {
|
2024-04-07 19:26:41 +03:00
|
|
|
self.add_triangle(ind_v1, ind_v2, ind_v3);
|
2024-04-07 19:15:39 +03:00
|
|
|
},
|
|
|
|
|
(Node::Value(ind_v1), Node::Value(ind_v2), Node::Value(ind_v3), Node::Value(ind_v4)) => {
|
|
|
|
|
self.add_tetrahedron(ind_v1, ind_v2, ind_v3, ind_v4);
|
|
|
|
|
},
|
|
|
|
|
(_, _, _, _) => {
|
|
|
|
|
println!("Encountered an unexpected pattern of nodes");
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|