use crate::coordinate_systems::{Face, Polar};
use crate::core::constants::TWO_PI_OVER_5;
use crate::core::hilbert::{Anchor, NO, YES};
use crate::core::pentagon::{basis, pentagon, triangle, v, w, Mat2};
use crate::geometry::PentagonShape;
const TRIANGLE_MODE: bool = false;
fn shift_right() -> Face {
w()
}
fn shift_left() -> Face {
let w_vec = w();
Face::new(-w_vec.x(), -w_vec.y())
}
fn quintant_rotations() -> [Mat2; 5] {
let mut rotations = [Mat2::new(1.0, 0.0, 0.0, 1.0); 5];
for (quintant, rotation) in rotations.iter_mut().enumerate() {
let angle = (TWO_PI_OVER_5).0 * quintant as f64;
let cos_angle = angle.cos();
let sin_angle = angle.sin();
*rotation = Mat2::new(cos_angle, -sin_angle, sin_angle, cos_angle);
}
rotations
}
fn transform_pentagon(pentagon: &mut PentagonShape, matrix: &Mat2) {
let vertices = pentagon.get_vertices_vec();
let mut transformed_vertices = Vec::new();
for vertex in vertices {
let transformed_x = matrix.m00 * vertex.x() + matrix.m01 * vertex.y();
let transformed_y = matrix.m10 * vertex.x() + matrix.m11 * vertex.y();
transformed_vertices.push(Face::new(transformed_x, transformed_y));
}
if transformed_vertices.len() == 5 {
let pentagon_vertices: [Face; 5] = [
transformed_vertices[0],
transformed_vertices[1],
transformed_vertices[2],
transformed_vertices[3],
transformed_vertices[4],
];
*pentagon = PentagonShape::new(pentagon_vertices);
} else if transformed_vertices.len() == 3 {
let pentagon_vertices: [Face; 3] = [
transformed_vertices[0],
transformed_vertices[1],
transformed_vertices[2],
];
*pentagon = PentagonShape::new_triangle(pentagon_vertices);
}
}
pub fn get_pentagon_vertices(resolution: i32, quintant: usize, anchor: &Anchor) -> PentagonShape {
let mut pentagon_shape = if TRIANGLE_MODE {
triangle().clone()
} else {
pentagon().clone()
};
let basis_mat = basis();
let translation_x = basis_mat.m00 * anchor.offset.x() + basis_mat.m01 * anchor.offset.y();
let translation_y = basis_mat.m10 * anchor.offset.x() + basis_mat.m11 * anchor.offset.y();
let translation = Face::new(translation_x, translation_y);
if anchor.flips[0] == NO && anchor.flips[1] == YES {
pentagon_shape.rotate180();
}
let k = anchor.q;
let f = anchor.flips[0] + anchor.flips[1];
if
((f == -2 || f == 2) && k > 1) ||
(f == 0 && (k == 0 || k == 3))
{
pentagon_shape.reflect_y();
}
if anchor.flips[0] == YES && anchor.flips[1] == YES {
pentagon_shape.rotate180();
} else if anchor.flips[0] == YES {
pentagon_shape.translate(shift_left());
} else if anchor.flips[1] == YES {
pentagon_shape.translate(shift_right());
}
pentagon_shape.translate(translation);
pentagon_shape.scale(1.0 / (2.0_f64.powi(resolution)));
let rotations = quintant_rotations();
transform_pentagon(&mut pentagon_shape, &rotations[quintant]);
pentagon_shape
}
pub fn get_quintant_vertices(quintant: usize) -> crate::geometry::pentagon::PentagonShape {
let triangle_verts = triangle().get_vertices();
let triangle_3_verts = [triangle_verts[0], triangle_verts[1], triangle_verts[2]];
let mut pentagon_shape =
crate::geometry::pentagon::PentagonShape::new_triangle(triangle_3_verts);
let rotations = quintant_rotations();
transform_pentagon(&mut pentagon_shape, &rotations[quintant]);
pentagon_shape
}
pub fn get_face_vertices() -> PentagonShape {
let mut vertices = Vec::new();
let v_vertex = v();
let rotations = quintant_rotations();
for rotation in &rotations {
let transformed_x = rotation.m00 * v_vertex.x() + rotation.m01 * v_vertex.y();
let transformed_y = rotation.m10 * v_vertex.x() + rotation.m11 * v_vertex.y();
vertices.push(Face::new(transformed_x, transformed_y));
}
vertices.reverse();
let pentagon_vertices: [Face; 5] = [
vertices[0],
vertices[1],
vertices[2],
vertices[3],
vertices[4],
];
PentagonShape::new(pentagon_vertices)
}
pub fn get_quintant_polar(polar: Polar) -> usize {
let gamma = polar.gamma().0; ((gamma / (TWO_PI_OVER_5).0).round() as i32 + 5) as usize % 5
}
pub type PentagonFlavor = u8;
pub fn get_pentagon_flavor(anchor: &Anchor) -> PentagonFlavor {
let mut f: u8 = 0;
if anchor.flips[1] == YES {
f += 2;
}
let q = anchor.q;
let sum = anchor.flips[0] + anchor.flips[1];
if
((sum == -2 || sum == 2) && q > 1) ||
(sum == 0 && (q == 0 || q == 3))
{
f += 1;
}
if sum == -2 || sum == 2 {
f += 4;
}
f
}