Skip to content

Commit e122aa9

Browse files
committed
Refactor Bowyer-Watson
1 parent f46f2f6 commit e122aa9

File tree

2 files changed

+167
-65
lines changed

2 files changed

+167
-65
lines changed

src/delaunay_core/cell.rs

Lines changed: 112 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,50 @@ where
146146
})
147147
}
148148

149+
/// The function `from_facet_and_vertex` creates a new [Cell] object from a [Facet] and a [Vertex].
150+
///
151+
/// # Arguments:
152+
///
153+
/// * `facet`: The [Facet] to be used to create the [Cell].
154+
/// * `vertex`: The [Vertex] to be added to the [Cell].
155+
///
156+
/// # Returns:
157+
///
158+
/// A [Result] type containing the new [Cell] or an error message.
159+
///
160+
/// # Example
161+
///
162+
/// ```
163+
/// use d_delaunay::delaunay_core::cell::Cell;
164+
/// use d_delaunay::delaunay_core::facet::Facet;
165+
/// use d_delaunay::delaunay_core::vertex::Vertex;
166+
/// use d_delaunay::delaunay_core::point::Point;
167+
/// let vertex1: Vertex<f64, Option<()>, 3> = Vertex::new(Point::new([0.0, 0.0, 1.0]));
168+
/// let vertex2: Vertex<f64, Option<()>, 3> = Vertex::new(Point::new([0.0, 1.0, 0.0]));
169+
/// let vertex3: Vertex<f64, Option<()>, 3> = Vertex::new(Point::new([1.0, 0.0, 0.0]));
170+
/// let vertex4: Vertex<f64, Option<()>, 3> = Vertex::new(Point::new([1.0, 1.0, 1.0]));
171+
/// let cell: Cell<f64, Option<()>, Option<()>,3> = Cell::new(vec![vertex1, vertex2, vertex3, vertex4]).unwrap();
172+
/// let facet = Facet::new(cell.clone(), vertex4).unwrap();
173+
/// let vertex5 = Vertex::new(Point::new([0.0, 0.0, 0.0]));
174+
/// let new_cell = Cell::from_facet_and_vertex(facet, vertex5).unwrap();
175+
/// assert!(new_cell.vertices.contains(&vertex5));
176+
pub fn from_facet_and_vertex(
177+
mut facet: Facet<T, U, V, D>,
178+
vertex: Vertex<T, U, D>,
179+
) -> Result<Self, &'static str> {
180+
let mut vertices = facet.vertices();
181+
vertices.push(vertex);
182+
let uuid = make_uuid();
183+
let neighbors = None;
184+
let data = None;
185+
Ok(Cell {
186+
vertices,
187+
uuid,
188+
neighbors,
189+
data,
190+
})
191+
}
192+
149193
/// The function `into_hashmap` converts a [Vec] of cells into a [HashMap],
150194
/// using the [Cell] [Uuid]s as keys.
151195
pub fn into_hashmap(cells: Vec<Self>) -> HashMap<Uuid, Self> {
@@ -239,6 +283,34 @@ where
239283
self.vertices.contains(&vertex)
240284
}
241285

286+
/// The function `contains_vertex_of` checks if the [Cell] contains any [Vertex] of a given [Cell].
287+
///
288+
/// # Arguments:
289+
///
290+
/// * `cell`: The [Cell] to check.
291+
///
292+
/// # Returns:
293+
///
294+
/// Returns `true` if the given [Cell] has any [Vertex] in common with the [Cell].
295+
///
296+
/// # Example
297+
///
298+
/// ```
299+
/// use d_delaunay::delaunay_core::cell::Cell;
300+
/// use d_delaunay::delaunay_core::vertex::Vertex;
301+
/// use d_delaunay::delaunay_core::point::Point;
302+
/// let vertex1 = Vertex::new_with_data(Point::new([0.0, 0.0, 1.0]), 1);
303+
/// let vertex2 = Vertex::new_with_data(Point::new([0.0, 1.0, 0.0]), 1);
304+
/// let vertex3 = Vertex::new_with_data(Point::new([1.0, 0.0, 0.0]), 1);
305+
/// let vertex4 = Vertex::new_with_data(Point::new([1.0, 1.0, 1.0]), 2);
306+
/// let cell = Cell::new_with_data(vec![vertex1, vertex2, vertex3, vertex4], "three-one cell").unwrap();
307+
/// let vertex5 = Vertex::new_with_data(Point::new([0.0, 0.0, 0.0]), 0);
308+
/// let cell2 = Cell::new_with_data(vec![vertex1, vertex2, vertex3, vertex5], "one-three cell").unwrap();
309+
/// assert!(cell.contains_vertex_of(cell2));
310+
pub fn contains_vertex_of(&self, cell: Cell<T, U, V, D>) -> bool {
311+
self.vertices.iter().any(|v| cell.vertices.contains(v))
312+
}
313+
242314
/// The function `circumcenter` returns the circumcenter of the cell.
243315
///
244316
/// Using the approach from:
@@ -407,37 +479,6 @@ where
407479

408480
facets
409481
}
410-
411-
/// The function `contains_facet` checks if a given [Facet] is present in
412-
/// the [Cell].
413-
///
414-
/// # Arguments:
415-
///
416-
/// * facet: The [Facet] to check.
417-
///
418-
/// # Returns:
419-
///
420-
/// Returns `true` if the given [Facet] is present in the [Cell], and
421-
/// `false` otherwise.
422-
///
423-
/// # Example
424-
///
425-
/// ```
426-
/// use d_delaunay::delaunay_core::cell::Cell;
427-
/// use d_delaunay::delaunay_core::facet::Facet;
428-
/// use d_delaunay::delaunay_core::vertex::Vertex;
429-
/// use d_delaunay::delaunay_core::point::Point;
430-
/// let vertex1 = Vertex::new_with_data(Point::new([0.0, 0.0, 1.0]), 1);
431-
/// let vertex2 = Vertex::new_with_data(Point::new([0.0, 1.0, 0.0]), 1);
432-
/// let vertex3 = Vertex::new_with_data(Point::new([1.0, 0.0, 0.0]), 1);
433-
/// let vertex4 = Vertex::new_with_data(Point::new([1.0, 1.0, 1.0]), 2);
434-
/// let cell = Cell::new_with_data(vec![vertex1, vertex2, vertex3, vertex4], "three-one cell").unwrap();
435-
/// let facet = Facet::new(cell.clone(), vertex1).unwrap();
436-
/// assert!(cell.contains_facet(facet));
437-
/// ```
438-
pub fn contains_facet(&self, facet: Facet<T, U, V, D>) -> bool {
439-
self.facets().contains(&facet)
440-
}
441482
}
442483

443484
/// Equality of cells is based on equality of sorted vector of vertices.
@@ -577,6 +618,27 @@ mod tests {
577618
assert_eq!(cell1, cell2);
578619
}
579620

621+
#[test]
622+
fn cell_from_facet_and_vertex() {
623+
let vertex1 = Vertex::new_with_data(Point::new([0.0, 0.0, 1.0]), 1);
624+
let vertex2 = Vertex::new_with_data(Point::new([0.0, 1.0, 0.0]), 1);
625+
let vertex3 = Vertex::new_with_data(Point::new([1.0, 0.0, 0.0]), 1);
626+
let vertex4 = Vertex::new_with_data(Point::new([1.0, 1.0, 1.0]), 2);
627+
let cell: Cell<f64, i32, Option<()>, 3> =
628+
Cell::new(vec![vertex1, vertex2, vertex3, vertex4]).unwrap();
629+
let facet = Facet::new(cell.clone(), vertex4).unwrap();
630+
let vertex5 = Vertex::new(Point::new([0.0, 0.0, 0.0]));
631+
let new_cell = Cell::from_facet_and_vertex(facet, vertex5).unwrap();
632+
633+
assert!(new_cell.vertices.contains(&vertex1));
634+
assert!(new_cell.vertices.contains(&vertex2));
635+
assert!(new_cell.vertices.contains(&vertex3));
636+
assert!(new_cell.vertices.contains(&vertex5));
637+
638+
// Human readable output for cargo test -- --nocapture
639+
println!("New Cell: {:?}", new_cell);
640+
}
641+
580642
#[test]
581643
fn cell_into_hashmap() {
582644
let vertex1 = Vertex::new_with_data(Point::new([0.0, 0.0, 1.0]), 1);
@@ -636,6 +698,24 @@ mod tests {
636698
println!("Cell: {:?}", cell);
637699
}
638700

701+
#[test]
702+
fn cell_contains_vertex_of() {
703+
let vertex1 = Vertex::new_with_data(Point::new([0.0, 0.0, 1.0]), 1);
704+
let vertex2 = Vertex::new_with_data(Point::new([0.0, 1.0, 0.0]), 1);
705+
let vertex3 = Vertex::new_with_data(Point::new([1.0, 0.0, 0.0]), 1);
706+
let vertex4 = Vertex::new_with_data(Point::new([1.0, 1.0, 1.0]), 2);
707+
let cell = Cell::new_with_data(vec![vertex1, vertex2, vertex3, vertex4], "three-one cell")
708+
.unwrap();
709+
let vertex5 = Vertex::new_with_data(Point::new([0.0, 0.0, 0.0]), 0);
710+
let cell2 = Cell::new_with_data(vec![vertex1, vertex2, vertex3, vertex5], "one-three cell")
711+
.unwrap();
712+
713+
assert!(cell.contains_vertex_of(cell2));
714+
715+
// Human readable output for cargo test -- --nocapture
716+
println!("Cell: {:?}", cell);
717+
}
718+
639719
#[test]
640720
fn cell_circumcenter() {
641721
let points = vec![
@@ -742,7 +822,7 @@ mod tests {
742822

743823
assert_eq!(facets.len(), 4);
744824
for facet in facets.iter() {
745-
assert!(cell.contains_facet(facet.clone()));
825+
assert!(cell.facets().contains(facet))
746826
}
747827

748828
// Human readable output for cargo test -- --nocapture

src/delaunay_core/triangulation_data_structure.rs

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -265,51 +265,73 @@ where
265265
let mut bad_cells: Vec<Cell<T, U, V, D>> = Vec::new();
266266

267267
for cell in &triangulation {
268-
// TODO: understand why we're getting singular matrices here
269268
if cell.circumsphere_contains(*vertex)? {
270269
bad_cells.push((*cell).clone());
271270
}
272271
}
273272

274-
// Find the boundary of the polygonal hole
275-
let mut polygonal_hole: Vec<Facet<T, U, V, D>> = Vec::new();
276-
for cell in bad_cells.iter() {
277-
// Create Facets from the Cell
278-
for vertex in cell.vertices.iter() {
279-
let facet = Facet::new(cell.clone(), *vertex)?;
280-
polygonal_hole.push(facet);
273+
// Find the boundary of the hole left by the bad cells
274+
let mut boundary_facets: Vec<Facet<T, U, V, D>> = Vec::new();
275+
for bad_cell in &bad_cells {
276+
for facet in bad_cell.facets() {
277+
if !bad_cells.iter().any(|c| c.facets().contains(&facet)) {
278+
boundary_facets.push(facet);
279+
}
281280
}
282-
283-
// for vertex in cell.vertices.iter() {
284-
// if bad_cells.iter().any(|c| c.contains_vertex(vertex)) {
285-
// polygonal_hole.push(vertex.clone());
286-
// }
287-
// }
288281
}
289282

290-
// Remove duplicate facets
291-
polygonal_hole.sort_by(|a, b| a.partial_cmp(b).unwrap());
292-
polygonal_hole.dedup();
293-
294-
// Remove bad cells from the triangulation
295-
for cell in bad_cells.iter() {
296-
triangulation.remove(triangulation.iter().position(|c| c == cell).unwrap());
283+
// Create new cells from the boundary facets and new vertex
284+
for facet in boundary_facets {
285+
let new_cell = Cell::from_facet_and_vertex(facet, *vertex)?;
286+
triangulation.push(new_cell);
297287
}
298288

299-
// Re-triangulate the polygonal hole
300-
for mut facet in polygonal_hole.iter().cloned() {
301-
let mut new_cell_vertices: Vec<Vertex<T, U, D>> = Vec::new();
302-
for facet_vertex in facet.vertices().iter() {
303-
new_cell_vertices.push(*facet_vertex);
304-
}
305-
new_cell_vertices.push(*vertex);
306-
triangulation.push(Cell::new(new_cell_vertices)?);
307-
}
289+
// Remove bad cells from triangulation
290+
triangulation.retain(|cell| !bad_cells.contains(cell));
308291
}
309292

310-
// Remove all cells containing vertices from the supercell
311-
triangulation
312-
.retain(|c| !c.contains_vertex(supercell.vertices.clone().into_iter().next().unwrap()));
293+
// // Find the boundary of the polygonal hole
294+
// let mut polygonal_hole: Vec<Facet<T, U, V, D>> = Vec::new();
295+
// for cell in bad_cells.iter() {
296+
// // Create Facets from the Cell
297+
// for vertex in cell.vertices.iter() {
298+
// let facet = Facet::new(cell.clone(), *vertex)?;
299+
// polygonal_hole.push(facet);
300+
// }
301+
302+
// // for vertex in cell.vertices.iter() {
303+
// // if bad_cells.iter().any(|c| c.contains_vertex(vertex)) {
304+
// // polygonal_hole.push(vertex.clone());
305+
// // }
306+
// // }
307+
// }
308+
309+
// // Remove duplicate facets
310+
// polygonal_hole.sort_by(|a, b| a.partial_cmp(b).unwrap());
311+
// polygonal_hole.dedup();
312+
313+
// // Remove bad cells from the triangulation
314+
// for cell in bad_cells.iter() {
315+
// triangulation.remove(triangulation.iter().position(|c| c == cell).unwrap());
316+
// }
317+
318+
// // Re-triangulate the polygonal hole
319+
// for mut facet in polygonal_hole.iter().cloned() {
320+
// let mut new_cell_vertices: Vec<Vertex<T, U, D>> = Vec::new();
321+
// for facet_vertex in facet.vertices().iter() {
322+
// new_cell_vertices.push(*facet_vertex);
323+
// }
324+
// new_cell_vertices.push(*vertex);
325+
// triangulation.push(Cell::new(new_cell_vertices)?);
326+
// }
327+
// }
328+
329+
// // Remove all cells containing vertices from the supercell
330+
// triangulation
331+
// .retain(|c| !c.contains_vertex(supercell.vertices.clone().into_iter().next().unwrap()));
332+
333+
// Remove any cells that contain a vertex of the supercell
334+
triangulation.retain(|cell| !cell.contains_vertex_of(supercell.clone()));
313335

314336
Ok(triangulation)
315337
}

0 commit comments

Comments
 (0)