aboutsummaryrefslogtreecommitdiff
path: root/src/geometry.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/geometry.rs')
-rw-r--r--src/geometry.rs63
1 files changed, 45 insertions, 18 deletions
diff --git a/src/geometry.rs b/src/geometry.rs
index 0841183..358620f 100644
--- a/src/geometry.rs
+++ b/src/geometry.rs
@@ -103,8 +103,12 @@ pub struct SpatialGrid {
impl SpatialGrid {
/// Creates a new spatial grid for the given dimensions
pub fn new(width: f64, height: f64, cell_size: f64) -> Self {
- let columns = ((width / cell_size).ceil() as usize).max(1);
- let rows = ((height / cell_size).ceil() as usize).max(1);
+ // Safe cast: width and height are positive map dimensions, divided by cell_size and clamped to at least 1.0
+ // The resulting grid size will be reasonable (< millions of cells) for typical map sizes
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let columns = (width / cell_size).ceil().max(1.0) as usize;
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let rows = (height / cell_size).ceil().max(1.0) as usize;
let cells = vec![Vec::new(); columns * rows];
Self {
@@ -122,10 +126,17 @@ impl SpatialGrid {
let min_y = line.start.1.min(line.end.1);
let max_y = line.start.1.max(line.end.1);
- let start_column = ((min_x / self.cell_size).floor() as usize).min(self.columns - 1);
- let end_column = ((max_x / self.cell_size).floor() as usize).min(self.columns - 1);
- let start_row = ((min_y / self.cell_size).floor() as usize).min(self.rows - 1);
- let end_row = ((max_y / self.cell_size).floor() as usize).min(self.rows - 1);
+ // Safe cast: coordinates are clamped to [0.0, max] before casting, ensuring valid grid indices
+ // The .max(0.0) ensures non-negative, and .min(columns/rows - 1) ensures within bounds
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let start_column =
+ ((min_x / self.cell_size).floor().max(0.0) as usize).min(self.columns - 1);
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let end_column = ((max_x / self.cell_size).floor().max(0.0) as usize).min(self.columns - 1);
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let start_row = ((min_y / self.cell_size).floor().max(0.0) as usize).min(self.rows - 1);
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let end_row = ((max_y / self.cell_size).floor().max(0.0) as usize).min(self.rows - 1);
for row in start_row..=end_row {
for col in start_column..=end_column {
@@ -143,18 +154,34 @@ impl SpatialGrid {
let min_y = rect.y;
let max_y = rect.y + rect.height;
- let start_column = ((min_x / self.cell_size).floor() as isize)
- .max(0)
- .min(self.columns as isize - 1) as usize;
- let end_column = ((max_x / self.cell_size).floor() as isize)
- .max(0)
- .min(self.columns as isize - 1) as usize;
- let start_row = ((min_y / self.cell_size).floor() as isize)
- .max(0)
- .min(self.rows as isize - 1) as usize;
- let end_row = ((max_y / self.cell_size).floor() as isize)
- .max(0)
- .min(self.rows as isize - 1) as usize;
+ let max_column_idx = if self.columns > 0 {
+ self.columns - 1
+ } else {
+ 0
+ };
+ let max_row_idx = if self.rows > 0 { self.rows - 1 } else { 0 };
+
+ // Safe cast: grid indices are small (< thousands) for typical map sizes, well within f64 precision
+ // The coordinates are clamped to valid grid bounds before casting to usize
+ #[allow(clippy::cast_precision_loss)]
+ let max_column_f64 = max_column_idx as f64;
+ #[allow(clippy::cast_precision_loss)]
+ let max_row_f64 = max_row_idx as f64;
+
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let start_column = ((min_x / self.cell_size)
+ .floor()
+ .max(0.0)
+ .min(max_column_f64)) as usize;
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let end_column = ((max_x / self.cell_size)
+ .floor()
+ .max(0.0)
+ .min(max_column_f64)) as usize;
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let start_row = ((min_y / self.cell_size).floor().max(0.0).min(max_row_f64)) as usize;
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let end_row = ((max_y / self.cell_size).floor().max(0.0).min(max_row_f64)) as usize;
let mut line_indices = Vec::new();
for row in start_row..=end_row {