use itertools::Itertools;
pub(crate) fn transform_coords(points: &mut [f64], fun: &impl Fn((f64, f64)) -> (f64, f64)) {
for (first, second) in points.iter_mut().tuples() {
(*first, *second) = fun((*first, *second));
}
}
pub(crate) fn create_triangle_mapper(v0: usize, v1: usize) -> impl Fn((f64, f64)) -> (f64, f64) {
let get_reference_vertex = |index| -> Result<(f64, f64), ()> {
match index {
0 => Ok((0.0, 0.0)),
1 => Ok((1.0, 0.0)),
2 => Ok((0.0, 1.0)),
_ => Err(()),
}
};
let p0 = get_reference_vertex(v0).unwrap();
let p1 = get_reference_vertex(v1).unwrap();
let p2 = get_reference_vertex(3 - v0 - v1).unwrap();
let col0 = (p1.0 - p0.0, p1.1 - p0.1);
let col1 = (p2.0 - p1.0, p2.1 - p1.1);
move |point: (f64, f64)| -> (f64, f64) {
(
p0.0 + col0.0 * point.0 + col1.0 * point.1,
p0.1 + col0.1 * point.0 + col1.1 * point.1,
)
}
}
pub(crate) fn create_quadrilateral_mapper(
v0: usize,
v1: usize,
) -> impl Fn((f64, f64)) -> (f64, f64) {
let v2 = match (v0, v1) {
(0, 1) => 2,
(1, 0) => 3,
(1, 3) => 0,
(3, 1) => 2,
(3, 2) => 1,
(2, 3) => 0,
(0, 2) => 1,
(2, 0) => 3,
_ => panic!("({v0}, {v1}) is not an edge of the unit quadrilateral."),
};
let get_reference_vertex = |index| -> Result<(f64, f64), ()> {
match index {
0 => Ok((0.0, 0.0)),
1 => Ok((1.0, 0.0)),
2 => Ok((0.0, 1.0)),
3 => Ok((1.0, 1.0)),
_ => Err(()),
}
};
let p0 = get_reference_vertex(v0).unwrap();
let p1 = get_reference_vertex(v1).unwrap();
let p2 = get_reference_vertex(v2).unwrap();
let col0 = (p1.0 - p0.0, p1.1 - p0.1);
let col1 = (p2.0 - p0.0, p2.1 - p0.1);
move |point: (f64, f64)| -> (f64, f64) {
(
p0.0 + col0.0 * point.0 + col1.0 * point.1,
p0.1 + col0.1 * point.0 + col1.1 * point.1,
)
}
}
pub(crate) fn next_triangle_vertex(index: usize) -> usize {
(index + 1) % 3
}
pub(crate) fn next_quadrilateral_vertex(index: usize) -> usize {
match index {
0 => 1,
1 => 3,
2 => 0,
3 => 2,
_ => panic!("Unknown vertex index."),
}
}