diff options
| author | Ruben Beltran del Rio <jj@r.bdr.sh> | 2025-12-16 16:35:08 +0100 |
|---|---|---|
| committer | Ruben Beltran del Rio <jj@r.bdr.sh> | 2025-12-16 17:38:30 +0100 |
| commit | bf4b51af43005415deac6ba475992c83b5f2f82e (patch) | |
| tree | 4bdc419138a070096735a45a74ea5eaf8822c691 /src/geometry.rs | |
| parent | afd0794104228cd20e177f41dc68e9ae7ecaabda (diff) | |
Adapt to edition 2024
Diffstat (limited to 'src/geometry.rs')
| -rw-r--r-- | src/geometry.rs | 63 |
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 { |