Skip to content

Commit

Permalink
Add handling of z values for xy-duplicates
Browse files Browse the repository at this point in the history
  • Loading branch information
hugoledoux committed Jan 15, 2024
1 parent f98d669 commit 5e9f626
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
41 changes: 39 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ pub enum InsertionStrategy {
// ConBRIO,
}

/// Handling of xy-duplicates (which z do we keep?)
pub enum DuplicateHandling {
First,
Last,
Highest,
Lowest,
// Average not possible I guess,
}

/// A Triangle is a triplet of indices
#[derive(Debug, PartialEq, Clone)]
pub struct Triangle {
Expand Down Expand Up @@ -325,6 +334,7 @@ pub struct Triangulation {
jump_and_walk: bool,
robust_predicates: bool,
removed_indices: Vec<usize>,
duplicates_handling: DuplicateHandling,
}

impl Triangulation {
Expand All @@ -342,16 +352,19 @@ impl Triangulation {
jump_and_walk: false,
robust_predicates: true,
removed_indices: es,
duplicates_handling: DuplicateHandling::First,
}
}

fn insert_one_pt_init_phase(&mut self, x: f64, y: f64, z: f64) -> Result<usize, usize> {
let p: [f64; 3] = [x, y, z];
for i in 1..self.stars.len() {
if geom::distance2d_squared(&self.stars[i].pt, &p) <= (self.snaptol * self.snaptol) {
self.update_z_value(i, z);
return Err(i);
}
}

self.collect_garbage();
//-- add point to Triangulation and create its empty star
self.stars.push(Star::new(x, y, z));
Expand Down Expand Up @@ -445,6 +458,12 @@ impl Triangulation {
self.robust_predicates = b;
}

/// Set the method to used to handle duplicates
/// (Last by default)
pub fn set_duplicates_handling(&mut self, method: DuplicateHandling) {
self.duplicates_handling = method;
}

/// Insert a [`Vec`] of [`array`] (`[f64; 3]`) values.
/// If [`InsertionStrategy::AsIs`] is used, then [`Triangulation::insert_one_pt()`] is called
/// for each point in the order given.
Expand Down Expand Up @@ -504,14 +523,16 @@ impl Triangulation {
//-- walk
let p: [f64; 3] = [px, py, pz];
let tr = self.walk(&p);
// println!("STARTING TR: {}", tr);
if geom::distance2d_squared(&self.stars[tr.v[0]].pt, &p) <= (self.snaptol * self.snaptol) {
self.update_z_value(tr.v[0], pz);
return Err(tr.v[0]);
}
if geom::distance2d_squared(&self.stars[tr.v[1]].pt, &p) <= (self.snaptol * self.snaptol) {
self.update_z_value(tr.v[1], pz);
return Err(tr.v[1]);
}
if geom::distance2d_squared(&self.stars[tr.v[2]].pt, &p) <= (self.snaptol * self.snaptol) {
self.update_z_value(tr.v[1], pz);
return Err(tr.v[2]);
}
//-- ok we now insert the point in the data structure
Expand All @@ -530,11 +551,27 @@ impl Triangulation {
self.flip13(pi, &tr);
//-- update_dt()
self.update_dt(pi);

self.cur = pi;
Ok(pi)
}

fn update_z_value(&mut self, pi: usize, newz: f64) {
match self.duplicates_handling {
DuplicateHandling::Last => self.stars[pi].pt[2] = newz,
DuplicateHandling::Highest => {
if newz > self.stars[pi].pt[2] {
self.stars[pi].pt[2] = newz;
}
}
DuplicateHandling::Lowest => {
if newz < self.stars[pi].pt[2] {
self.stars[pi].pt[2] = newz;
}
}
DuplicateHandling::First => (),
}
}

fn update_dt(&mut self, pi: usize) {
// println!("--> Update DT");
let mut mystack: Vec<Triangle> = Vec::new();
Expand Down
52 changes: 52 additions & 0 deletions tests/duplicates.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::startin::Triangulation;

use startin;

fn five_points() -> Triangulation {
let mut pts: Vec<[f64; 3]> = Vec::new();
pts.push([0.0, 0.0, 1.0]);
pts.push([10.0, 0.0, 2.0]);
pts.push([10.0, 10.0, 3.0]);
pts.push([0.0, 10.0, 4.0]);
pts.push([5.0, 5.0, 10.0]);
let mut dt = startin::Triangulation::new();
dt.insert(&pts, startin::InsertionStrategy::AsIs);
dt
}

#[test]
fn duplicate_alltests() {
let mut dt = five_points();

dt.set_duplicates_handling(startin::DuplicateHandling::First);
let re = dt.insert_one_pt(5.0, 5.0, 20.0);
assert_eq!(Err(5), re);
match re {
Ok(_) => (),
Err(i) => assert_eq!(dt.get_point(i).unwrap()[2], 10.0),
}

dt.set_duplicates_handling(startin::DuplicateHandling::Last);
let re = dt.insert_one_pt(5.0, 5.0, 20.0);
assert_eq!(Err(5), re);
match re {
Ok(_) => (),
Err(i) => assert_eq!(dt.get_point(i).unwrap()[2], 20.0),
}

dt.set_duplicates_handling(startin::DuplicateHandling::Highest);
let re = dt.insert_one_pt(5.0, 5.0, 20.0);
assert_eq!(Err(5), re);
match re {
Ok(_) => (),
Err(i) => assert_eq!(dt.get_point(i).unwrap()[2], 20.0),
}

dt.set_duplicates_handling(startin::DuplicateHandling::Lowest);
let re = dt.insert_one_pt(5.0, 5.0, 5.0);
assert_eq!(Err(5), re);
match re {
Ok(_) => (),
Err(i) => assert_eq!(dt.get_point(i).unwrap()[2], 5.0),
}
}

0 comments on commit 5e9f626

Please sign in to comment.