pub const HEX_MESH_3X3: [[[(i32, i32); 6]; 3]; 3] = [
[
[
(87, -50),
(0, -100),
(-87, -50),
(-87, 50),
(0, 100),
(87, 50),
],
[
(260, -50),
(173, -100),
(87, -50),
(87, 50),
(173, 100),
(260, 50),
],
[
(433, -50),
(346, -100),
(260, -50),
(260, 50),
(346, 100),
(433, 50),
],
],
[
[
(173, 100),
(87, 50),
(0, 100),
(0, 200),
(87, 250),
(173, 200),
],
[
(346, 100),
(260, 50),
(173, 100),
(173, 200),
(260, 250),
(346, 200),
],
[
(520, 100),
(433, 50),
(346, 100),
(346, 200),
(433, 250),
(520, 200),
],
],
[
[
(87, 250),
(0, 200),
(-87, 250),
(-87, 350),
(0, 400),
(87, 350),
],
[
(260, 250),
(173, 200),
(87, 250),
(87, 350),
(173, 400),
(260, 350),
],
[
(433, 250),
(346, 200),
(260, 250),
(260, 350),
(346, 400),
(433, 350),
],
],
];
#[macro_export]
macro_rules! init_dcel_with_3x3_hex_mesh {
($dcel_type:ty) => {{
let mesh: Vec<Vec<(i32, i32)>> = $crate::test_common::HEX_MESH_3X3
.iter()
.flat_map(|row| row.iter())
.map(|face| face.iter().copied().collect())
.collect();
let mut dcel: $dcel_type = <$dcel_type>::new();
dcel.insert_mesh(mesh);
dcel
}};
}
#[macro_export]
macro_rules! assert_vertex_rim {
($dcel:expr, $id:expr, $count:expr) => {{
use $crate::{EdgeId, HalfEdgeId, VertexId};
let vertex_rim_vertices: Vec<VertexId> =
$dcel.vertex_rim_vertices(VertexId::new($id)).collect();
assert_eq!(vertex_rim_vertices.len(), $count);
let vertex_rim_vertices_reverse: Vec<VertexId> = $dcel
.vertex_rim_vertices_reverse(VertexId::new($id))
.collect();
assert_eq!(
vertex_rim_vertices,
vertex_rim_vertices_reverse
.into_iter()
.rev()
.collect::<Vec<VertexId>>()
);
let vertex_rim_half_edges: Vec<HalfEdgeId> =
$dcel.vertex_rim_half_edges(VertexId::new($id)).collect();
assert_eq!(vertex_rim_half_edges.len(), $count);
let vertex_rim_half_edges_reverse: Vec<HalfEdgeId> = $dcel
.vertex_rim_half_edges_reverse(VertexId::new($id))
.collect();
assert_eq!(
vertex_rim_half_edges,
vertex_rim_half_edges_reverse
.into_iter()
.rev()
.collect::<Vec<HalfEdgeId>>()
);
let vertex_rim_edges: Vec<EdgeId> = $dcel.vertex_rim_edges(VertexId::new($id)).collect();
assert_eq!(vertex_rim_edges.len(), $count);
let vertex_rim_edges_reverse: Vec<EdgeId> =
$dcel.vertex_rim_edges_reverse(VertexId::new($id)).collect();
assert_eq!(
vertex_rim_edges,
vertex_rim_edges_reverse
.into_iter()
.rev()
.collect::<Vec<EdgeId>>()
);
}};
}
#[macro_export]
macro_rules! assert_vertex_spokes_interspokes {
($dcel:expr, $id:expr, $count:expr) => {{
use $crate::{EdgeId, FaceId, HalfEdgeId, VertexId};
let vertex_half_spokes: Vec<HalfEdgeId> =
$dcel.vertex_half_spokes(VertexId::new($id)).collect();
assert_eq!(vertex_half_spokes.len(), $count);
let vertex_half_spokes_reverse: Vec<HalfEdgeId> = $dcel
.vertex_half_spokes_reverse(VertexId::new($id))
.collect();
assert_eq!(
vertex_half_spokes.first(),
vertex_half_spokes_reverse.first()
);
assert_eq!(
vertex_half_spokes
.into_iter()
.skip(1)
.collect::<Vec<HalfEdgeId>>(),
vertex_half_spokes_reverse
.into_iter()
.skip(1)
.rev()
.collect::<Vec<HalfEdgeId>>()
);
let vertex_spokes: Vec<EdgeId> = $dcel.vertex_spokes(VertexId::new($id)).collect();
assert_eq!(vertex_spokes.len(), $count);
let vertex_spokes_reverse: Vec<EdgeId> =
$dcel.vertex_spokes_reverse(VertexId::new($id)).collect();
assert_eq!(vertex_spokes.first(), vertex_spokes_reverse.first());
assert_eq!(
vertex_spokes.into_iter().skip(1).collect::<Vec<EdgeId>>(),
vertex_spokes_reverse
.into_iter()
.skip(1)
.rev()
.collect::<Vec<EdgeId>>()
);
let vertex_interspokes: Vec<FaceId> =
$dcel.vertex_interspokes(VertexId::new($id)).collect();
assert_eq!(vertex_interspokes.len(), $count);
let vertex_interspokes_reverse: Vec<FaceId> = $dcel
.vertex_interspokes_reverse(VertexId::new($id))
.collect();
assert_eq!(
vertex_interspokes.first(),
vertex_interspokes_reverse.first()
);
assert_eq!(
vertex_interspokes
.into_iter()
.skip(1)
.collect::<Vec<FaceId>>(),
vertex_interspokes_reverse
.into_iter()
.skip(1)
.rev()
.collect::<Vec<FaceId>>()
);
}};
}
#[macro_export]
macro_rules! assert_face_boundary {
($dcel:expr, $id:expr, $count:expr) => {{
use $crate::{EdgeId, FaceId, HalfEdgeId, VertexId};
let face_vertices: Vec<VertexId> = $dcel.face_vertices(FaceId::new($id)).collect();
assert_eq!(face_vertices.len(), $count);
let face_vertices_reverse: Vec<VertexId> =
$dcel.face_vertices_reverse(FaceId::new($id)).collect();
assert_eq!(face_vertices.first(), face_vertices_reverse.first());
assert_eq!(
face_vertices.into_iter().skip(1).collect::<Vec<VertexId>>(),
face_vertices_reverse
.into_iter()
.skip(1)
.rev()
.collect::<Vec<VertexId>>()
);
let face_half_edges: Vec<HalfEdgeId> = $dcel.face_half_edges(FaceId::new($id)).collect();
assert_eq!(face_half_edges.len(), $count);
let face_half_edges_reverse: Vec<HalfEdgeId> =
$dcel.face_half_edges_reverse(FaceId::new($id)).collect();
assert_eq!(face_half_edges.first(), face_half_edges_reverse.first());
assert_eq!(
face_half_edges
.into_iter()
.skip(1)
.collect::<Vec<HalfEdgeId>>(),
face_half_edges_reverse
.into_iter()
.skip(1)
.rev()
.collect::<Vec<HalfEdgeId>>()
);
let face_edges: Vec<EdgeId> = $dcel.face_edges(FaceId::new($id)).collect();
assert_eq!(face_edges.len(), $count);
let face_edges_reverse: Vec<EdgeId> = $dcel.face_edges_reverse(FaceId::new($id)).collect();
assert_eq!(face_edges.first(), face_edges_reverse.first());
assert_eq!(
face_edges.into_iter().skip(1).collect::<Vec<EdgeId>>(),
face_edges_reverse
.into_iter()
.skip(1)
.rev()
.collect::<Vec<EdgeId>>()
);
}};
}
#[macro_export]
macro_rules! assert_face_spokes_interspokes {
($dcel:expr, $id:expr, $count:expr) => {{
use $crate::{EdgeId, FaceId, HalfEdgeId};
fn are_rotations<T: PartialEq>(left: &[T], right: &[T]) -> bool {
if left.len() != right.len() {
return false;
}
if left.is_empty() {
return true;
}
(0..left.len())
.any(|offset| (0..left.len()).all(|i| left[(i + offset) % left.len()] == right[i]))
}
let face_half_spokes: Vec<HalfEdgeId> = $dcel.face_half_spokes(FaceId::new($id)).collect();
assert_eq!(face_half_spokes.len(), $count);
let face_half_spokes_reverse: Vec<HalfEdgeId> =
$dcel.face_half_spokes_reverse(FaceId::new($id)).collect();
let face_spokes: Vec<EdgeId> = $dcel.face_spokes(FaceId::new($id)).collect();
assert_eq!(face_spokes.len(), $count);
let face_spokes_reverse: Vec<EdgeId> =
$dcel.face_spokes_reverse(FaceId::new($id)).collect();
let face_interspokes: Vec<FaceId> = $dcel.face_interspokes(FaceId::new($id)).collect();
assert_eq!(face_spokes.len(), $count);
let face_spokes_reverse: Vec<FaceId> =
$dcel.face_interspokes_reverse(FaceId::new($id)).collect();
}};
}
#[macro_export]
macro_rules! assert_face_rim {
($dcel:expr, $id:expr, $count:expr) => {{
use $crate::{EdgeId, FaceId, HalfEdgeId, VertexId};
fn are_rotations<T: PartialEq>(left: &[T], right: &[T]) -> bool {
if left.len() != right.len() {
return false;
}
if left.is_empty() {
return true;
}
(0..left.len())
.any(|offset| (0..left.len()).all(|i| left[(i + offset) % left.len()] == right[i]))
}
let face_rim_vertices: Vec<VertexId> = $dcel.face_rim_vertices(FaceId::new($id)).collect();
assert_eq!(face_rim_vertices.len(), $count);
let face_rim_vertices_reverse: Vec<VertexId> =
$dcel.face_rim_vertices_reverse(FaceId::new($id)).collect();
assert_eq!(face_rim_vertices_reverse.len(), $count);
let mut face_rim_vertices_reverse_reverse = face_rim_vertices_reverse;
face_rim_vertices_reverse_reverse.reverse();
assert!(are_rotations(
&face_rim_vertices,
&face_rim_vertices_reverse_reverse
));
let face_rim_half_edges: Vec<HalfEdgeId> =
$dcel.face_rim_half_edges(FaceId::new($id)).collect();
assert_eq!(face_rim_half_edges.len(), $count);
let face_rim_half_edges_reverse: Vec<HalfEdgeId> = $dcel
.face_rim_half_edges_reverse(FaceId::new($id))
.collect();
let mut face_rim_half_edges_reverse_reverse = face_rim_half_edges_reverse;
face_rim_half_edges_reverse_reverse.reverse();
assert!(are_rotations(
&face_rim_half_edges,
&face_rim_half_edges_reverse_reverse
));
let face_rim_edges: Vec<EdgeId> = $dcel.face_rim_edges(FaceId::new($id)).collect();
assert_eq!(face_rim_edges.len(), $count);
let face_rim_edges_reverse: Vec<EdgeId> =
$dcel.face_rim_edges_reverse(FaceId::new($id)).collect();
let mut face_rim_edges_reverse_reverse = face_rim_edges_reverse;
face_rim_edges_reverse_reverse.reverse();
assert!(are_rotations(
&face_rim_edges,
&face_rim_edges_reverse_reverse
));
}};
}