Use `Vector2<i64>` instead of `[i64; 2]` in `navmesher.rs`

This commit is contained in:
Mikolaj Wielgus 2026-03-17 13:19:08 +01:00
parent 41dd0a91f8
commit 50b7dc26b0
1 changed files with 40 additions and 38 deletions

View File

@ -9,17 +9,18 @@ use crate::{
math, math,
Board, Board,
primitives::{Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Via, ViaId}, primitives::{Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Via, ViaId},
Vector2,
}; };
#[derive(Clone, Debug, Getters)] #[derive(Clone, Debug, Getters)]
pub struct LayerNavmesher { pub struct LayerNavmesher {
boundary: Vec<[i64; 2]>, boundary: Vec<Vector2<i64>>,
navmeshes: Vec<RecordingTriangulator<i64>>, navmeshes: Vec<RecordingTriangulator<i64>>,
inflation_factors: Vec<f64>, inflation_factors: Vec<f64>,
} }
impl LayerNavmesher { impl LayerNavmesher {
pub fn new(boundary: impl IntoIterator<Item = [i64; 2]>) -> Self { pub fn new(boundary: impl IntoIterator<Item = Vector2<i64>>) -> Self {
Self { Self {
boundary: boundary.into_iter().collect(), boundary: boundary.into_iter().collect(),
navmeshes: vec![RecordingTriangulator::new()], navmeshes: vec![RecordingTriangulator::new()],
@ -27,31 +28,33 @@ impl LayerNavmesher {
} }
} }
pub fn insert_polygon(&mut self, polygon: impl IntoIterator<Item = [i64; 2]>) { pub fn insert_polygon(&mut self, polygon: impl IntoIterator<Item = Vector2<i64>>) {
let polygon: Vec<[i64; 2]> = polygon.into_iter().collect(); let polygon: Vec<Vector2<i64>> = polygon.into_iter().collect();
for i in 0..self.navmeshes.len() { for i in 0..self.navmeshes.len() {
self.navmeshes[i].insert_polygon_and_rebuild( self.navmeshes[i].insert_polygon_and_rebuild(
Self::inflate_polygon(polygon.clone(), self.inflation_factors[i]), Self::inflate_polygon(polygon.clone(), self.inflation_factors[i])
self.boundary.clone(), .into_iter()
.map(Into::into),
self.boundary.iter().cloned().map(Into::into),
); );
} }
} }
fn inflate_polygon( fn inflate_polygon(
polygon: impl IntoIterator<Item = [i64; 2]>, polygon: Vec<Vector2<i64>>,
inflation_factor: f64, inflation_factor: f64,
) -> impl IntoIterator<Item = [i64; 2]> { ) -> impl IntoIterator<Item = Vector2<i64>> {
let polygon: Vec<[i64; 2]> = polygon.into_iter().collect();
// Centroid. // Centroid.
let cx = polygon.iter().map(|p| p[0] as f64).sum::<f64>() / polygon.len() as f64; let cx = polygon.iter().map(|p| p.x as f64).sum::<f64>() / polygon.len() as f64;
let cy = polygon.iter().map(|p| p[1] as f64).sum::<f64>() / polygon.len() as f64; let cy = polygon.iter().map(|p| p.y as f64).sum::<f64>() / polygon.len() as f64;
polygon.into_iter().map(move |[px, py]| { polygon.into_iter().map(move |p| {
let px = p.x as f64;
let py = p.y as f64;
// Delta. // Delta.
let dx = px as f64 - cx; let dx = px - cx;
let dy = py as f64 - cy; let dy = py - cy;
let d = (dx * dx + dy * dy).sqrt(); let d = (dx * dx + dy * dy).sqrt();
// Normalize delta. // Normalize delta.
@ -59,14 +62,14 @@ impl LayerNavmesher {
let ny = dy / d; let ny = dy / d;
// Shift away from centroid. // Shift away from centroid.
let fx = px as f64 + nx * inflation_factor; let fx = px + nx * inflation_factor;
let fy = py as f64 + ny * inflation_factor; let fy = py + ny * inflation_factor;
// Round away from centroid. // Round away from centroid.
let rx = if fx >= cx { fx.ceil() } else { fx.floor() }; let rx = if fx >= cx { fx.ceil() } else { fx.floor() };
let ry = if fy >= cy { fy.ceil() } else { fy.floor() }; let ry = if fy >= cy { fy.ceil() } else { fy.floor() };
[rx as i64, ry as i64] Vector2::new(rx as i64, ry as i64)
}) })
} }
} }
@ -77,8 +80,8 @@ pub struct Navmesher {
} }
impl Navmesher { impl Navmesher {
pub fn new(boundary: impl IntoIterator<Item = [i64; 2]>, layer_count: usize) -> Self { pub fn new(boundary: impl IntoIterator<Item = Vector2<i64>>, layer_count: usize) -> Self {
let boundary: Vec<[i64; 2]> = boundary.into_iter().collect(); let boundary: Vec<Vector2<i64>> = boundary.into_iter().collect();
Self { Self {
layers: std::iter::repeat_with(|| LayerNavmesher::new(boundary.clone())) layers: std::iter::repeat_with(|| LayerNavmesher::new(boundary.clone()))
@ -87,7 +90,7 @@ impl Navmesher {
} }
} }
pub fn insert_polygon(&mut self, layer: usize, polygon: impl IntoIterator<Item = [i64; 2]>) { pub fn insert_polygon(&mut self, layer: usize, polygon: impl IntoIterator<Item = Vector2<i64>>) {
self.layers[layer].insert_polygon(polygon); self.layers[layer].insert_polygon(polygon);
} }
} }
@ -101,7 +104,11 @@ pub struct NavmesherBoard {
impl NavmesherBoard { impl NavmesherBoard {
pub fn with_board(board: Board) -> Self { pub fn with_board(board: Board) -> Self {
let mut navmesher = Navmesher::new( let mut navmesher = Navmesher::new(
board.layout().boundary().clone(), board
.layout()
.boundary()
.iter()
.map(|p| Vector2::new(p[0], p[1])),
*board.layout().layer_count(), *board.layout().layer_count(),
); );
@ -129,20 +136,20 @@ impl NavmesherBoard {
navmesher.insert_polygon(joint.layer, Self::joint_circumscribed_octagon(joint)); navmesher.insert_polygon(joint.layer, Self::joint_circumscribed_octagon(joint));
} }
fn joint_circumscribed_octagon(joint: Joint) -> [[i64; 2]; 8] { fn joint_circumscribed_octagon(joint: Joint) -> [Vector2<i64>; 8] {
let cx = joint.position.x; let cx = joint.position.x;
let cy = joint.position.y; let cy = joint.position.y;
let r = joint.radius as i64; let r = joint.radius as i64;
[ [
[cx + r, cy + r / 2], Vector2::new(cx + r, cy + r / 2),
[cx + r / 2, cy + r], Vector2::new(cx + r / 2, cy + r),
[cx - r / 2, cy + r], Vector2::new(cx - r / 2, cy + r),
[cx - r, cy + r / 2], Vector2::new(cx - r, cy + r / 2),
[cx - r, cy - r / 2], Vector2::new(cx - r, cy - r / 2),
[cx - r / 2, cy - r], Vector2::new(cx - r / 2, cy - r),
[cx + r / 2, cy - r], Vector2::new(cx + r / 2, cy - r),
[cx + r, cy - r / 2], Vector2::new(cx + r, cy - r / 2),
] ]
} }
@ -169,9 +176,7 @@ impl NavmesherBoard {
endpoints[1].x, endpoints[1].x,
endpoints[1].y, endpoints[1].y,
segment.half_width, segment.half_width,
) ),
.into_iter()
.map(Into::into),
) )
} }
@ -186,9 +191,6 @@ impl NavmesherBoard {
} }
fn insert_polygon_in_navmesher(navmesher: &mut Navmesher, polygon: Polygon) { fn insert_polygon_in_navmesher(navmesher: &mut Navmesher, polygon: Polygon) {
navmesher.insert_polygon( navmesher.insert_polygon(polygon.layer, polygon.vertices);
polygon.layer,
polygon.vertices.into_iter().map(Into::into),
);
} }
} }