Skip to content

Commit

Permalink
PartialEq, Eq, and PartialOrd on Cells
Browse files Browse the repository at this point in the history
  • Loading branch information
acgetchell committed Jan 19, 2024
1 parent 1430ce1 commit 530cd68
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 6 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ the [Rust] ecosystem.

## Features

- [ ] d-dimensional [Delaunay triangulations]
- [x] Arbitrary data types associated with vertices and cells
- [x] Serialization/Deserialization of all data structures to/from [JSON]
- [ ] d-dimensional [Delaunay triangulations]
- [x] Arbitrary data types associated with vertices and cells
- [x] Serialization/Deserialization of all data structures to/from [JSON]

At some point I may merge into another library, such as [Spade] or [delaunay],
but for now I am developing this to use in my [research] without trying to
Expand Down
85 changes: 84 additions & 1 deletion src/delaunay_core/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::{collections::HashMap, fmt::Debug, iter::Sum, ops::Div};
use uuid::Uuid;

#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize, PartialOrd)]
#[derive(Clone, Debug, Default, Deserialize, Eq, Serialize)]
/// The `Cell` struct represents a d-dimensional
/// [simplex](https://en.wikipedia.org/wiki/Simplex) with vertices, a unique
/// identifier, optional neighbors, and optional data.
Expand Down Expand Up @@ -391,6 +391,40 @@ where
}
}

impl<T, U, V, const D: usize> PartialEq for Cell<T, U, V, D>
where
T: Clone + Copy + Default + PartialEq + PartialOrd,
U: Clone + Copy + PartialEq,
V: Clone + Copy + PartialEq,
[T; D]: Default + DeserializeOwned + Serialize + Sized,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
let mut left = self.vertices.clone();
left.sort_by(|a, b| a.partial_cmp(b).unwrap());
let mut right = other.vertices.clone();
right.sort_by(|a, b| a.partial_cmp(b).unwrap());
left == right
}
}

impl<T, U, V, const D: usize> PartialOrd for Cell<T, U, V, D>
where
T: Clone + Copy + Default + PartialEq + PartialOrd,
U: Clone + Copy + PartialEq,
V: Clone + Copy + PartialEq,
[T; D]: Default + DeserializeOwned + Serialize + Sized,
{
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
let mut left = self.vertices.clone();
left.sort_by(|a, b| a.partial_cmp(b).unwrap());
let mut right = other.vertices.clone();
right.sort_by(|a, b| a.partial_cmp(b).unwrap());
left.partial_cmp(&right)
}
}

#[cfg(test)]
mod tests {

Expand Down Expand Up @@ -668,4 +702,53 @@ mod tests {
// Human readable output for cargo test -- --nocapture
println!("Serialized: {:?}", serialized);
}

#[test]
fn cell_partial_eq() {
let vertex1 = Vertex::new(Point::new([0.0, 0.0, 1.0]));
let vertex2 = Vertex::new(Point::new([0.0, 1.0, 0.0]));
let vertex3 = Vertex::new(Point::new([1.0, 0.0, 0.0]));
let vertex4 = Vertex::new(Point::new([0.0, 0.0, 0.0]));
let vertex5 = Vertex::new(Point::new([1.0, 1.0, 1.0]));
let cell1: Cell<f64, Option<()>, Option<()>, 3> =
Cell::new(vec![vertex1, vertex2, vertex3, vertex4]).unwrap();
let cell2: Cell<f64, Option<()>, Option<()>, 3> =
Cell::new(vec![vertex1, vertex2, vertex3, vertex4]).unwrap();
let cell3: Cell<f64, Option<()>, Option<()>, 3> =
Cell::new(vec![vertex4, vertex2, vertex3, vertex1]).unwrap();
let cell4: Cell<f64, Option<()>, Option<()>, 3> =
Cell::new(vec![vertex5, vertex4, vertex3, vertex2]).unwrap();

assert_eq!(cell1, cell2);
// Two cells with the same vertices but different uuids are equal
assert_ne!(cell1.uuid, cell2.uuid);
assert_eq!(cell1.vertices, cell2.vertices);
assert_eq!(cell2, cell3);
assert_ne!(cell3, cell4);
}

#[test]
fn cell_partial_ord() {
let vertex1 = Vertex::new(Point::new([0.0, 0.0, 0.0]));
let vertex2 = Vertex::new(Point::new([1.0, 0.0, 0.0]));
let vertex3 = Vertex::new(Point::new([0.0, 1.0, 0.0]));
let vertex4 = Vertex::new(Point::new([0.0, 0.0, 1.0]));
let vertex5 = Vertex::new(Point::new([1.0, 1.0, 1.0]));
let cell1: Cell<f64, Option<()>, Option<()>, 3> =
Cell::new(vec![vertex1, vertex2, vertex3, vertex4]).unwrap();
let cell2: Cell<f64, Option<()>, Option<()>, 3> =
Cell::new(vec![vertex4, vertex3, vertex2, vertex1]).unwrap();
let cell3: Cell<f64, Option<()>, Option<()>, 3> =
Cell::new(vec![vertex5, vertex4, vertex3, vertex2]).unwrap();

assert!(cell1 < cell3);
assert_eq!(cell1, cell2);
// These should fail
// assert!(cell1 < cell2);
// assert!(cell2 < cell1);
assert!(cell1 < cell3);
assert!(cell2 < cell3);
assert!(cell3 > cell1);
assert!(cell3 > cell2);
}
}
4 changes: 2 additions & 2 deletions src/delaunay_core/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use super::{point::Point, utilities::make_uuid};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::{collections::HashMap, option::Option};
use std::{cmp::Ordering, collections::HashMap, option::Option};
use uuid::Uuid;

#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Serialize)]
Expand Down Expand Up @@ -198,7 +198,7 @@ where
[T; D]: Copy + Default + DeserializeOwned + Serialize + Sized,
{
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.point.partial_cmp(&other.point)
}
}
Expand Down

0 comments on commit 530cd68

Please sign in to comment.