Moved HashSet to field_of_view
@@ -5,7 +5,7 @@ use std::collections::HashSet;
/// Calculates field-of-view for a map that supports Algorithm2D.
pub fn field_of_view(start: Point, range: i32, fov_check: &dyn Algorithm2D) -> Vec<Point> {
- let mut result: Vec<Point> = Vec::new();
+ let mut result: HashSet<Point> = HashSet::new();
let left = start.x - range;
let right = start.x + range;
@@ -15,23 +15,27 @@ pub fn field_of_view(start: Point, range: i32, fov_check: &dyn Algorithm2D) -> V
for x in left..=right {
for pt in scan_fov_line(start, Point::new(x, top), range_squared, fov_check) {
- result.push(pt);
+ result.insert(pt);
}
for pt in scan_fov_line(start, Point::new(x, bottom), range_squared, fov_check) {
- result.push(pt);
+ result.insert(pt);
}
}
for y in top+1..bottom {
for pt in scan_fov_line(start, Point::new(left, y), range_squared, fov_check) {
- result.push(pt);
+ result.insert(pt);
}
for pt in scan_fov_line(start, Point::new(right, y), range_squared, fov_check) {
- result.push(pt);
+ result.insert(pt);
}
}
- result
+ let mut dedupe = Vec::new();
+ for p in result.iter() {
+ dedupe.push(*p);
+ }
+ dedupe
}
/// Helper method to scan along a line.
@@ -41,27 +45,21 @@ fn scan_fov_line(
range_squared: f32,
fov_check: &dyn Algorithm2D,
) -> Vec<Point> {
- let mut result: HashSet<Point> = HashSet::new();
+ let mut result: Vec<Point> = Vec::new();
let line = super::line2d(super::LineAlg::Bresenham, start, end);
- let mut blocked = false;
-
for target in line.iter() {
- if !blocked {
let dsq = DistanceAlg::PythagorasSquared.distance2d(start, *target);
if dsq <= range_squared {
+ result.push(*target);
if fov_check.is_opaque(fov_check.point2d_to_index(*target)) {
- blocked = true;
+ // FoV is blocked
+ break;
}
- result.insert(*target);
} else {
- blocked = true;
- }
+ // FoV is out of range
+ break;
}
}
- let mut dedupe = Vec::new();
- for p in result.iter() {
- dedupe.push(*p);
- }
- dedupe
+ result
}
