|
|
|
|
@ -10,25 +10,11 @@
|
|
|
|
|
// Each antenna is tuned to a specific frequency indicated by a
|
|
|
|
|
// single lowercase letter, uppercase letter, or digit.
|
|
|
|
|
|
|
|
|
|
// an antinode occurs at any point that is perfectly in line with two antennas of the same
|
|
|
|
|
// frequency - but only when one of the antennas is twice as far away as the other
|
|
|
|
|
// This means that for any pair of antennas with the same frequency, there are two antinodes, one on either side of them.
|
|
|
|
|
|
|
|
|
|
// So, for these two antennas with frequency `a`, they create the two antinodes marked with `#`:
|
|
|
|
|
|
|
|
|
|
// ..........
|
|
|
|
|
// ...#......
|
|
|
|
|
// ..........
|
|
|
|
|
// ....a.....
|
|
|
|
|
// ..........
|
|
|
|
|
// .....a....
|
|
|
|
|
// ..........
|
|
|
|
|
// ......#...
|
|
|
|
|
// ..........
|
|
|
|
|
// ..........
|
|
|
|
|
|
|
|
|
|
use std::{collections::HashMap, mem};
|
|
|
|
|
|
|
|
|
|
use nalgebra_glm::Vec2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
|
|
|
|
pub enum MapCell
|
|
|
|
|
@ -51,6 +37,11 @@ impl PointIdx
|
|
|
|
|
{
|
|
|
|
|
PointIdx { i, j }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pub fn as_glm_vec(self: & PointIdx) -> I32Vec2
|
|
|
|
|
// {
|
|
|
|
|
// I32Vec2::new(self.i as i32, self.j as i32)
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
|
@ -142,7 +133,14 @@ impl Map
|
|
|
|
|
|
|
|
|
|
pub fn print(self: &Map, include_antinodes: bool)
|
|
|
|
|
{
|
|
|
|
|
print!("MAP:");
|
|
|
|
|
if include_antinodes
|
|
|
|
|
{
|
|
|
|
|
print!("MAP (w/ antinodes):")
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
print!("MAP:");
|
|
|
|
|
}
|
|
|
|
|
for (i, row) in self.map.iter().enumerate()
|
|
|
|
|
{
|
|
|
|
|
print!("\n\t");
|
|
|
|
|
@ -170,13 +168,82 @@ impl Map
|
|
|
|
|
println!("{:#?}", self.antenna_locations);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// an antinode occurs at any point that is perfectly in line with two antennas of the same
|
|
|
|
|
// frequency - but only when one of the antennas is twice as far away as the other
|
|
|
|
|
// This means that for any pair of antennas with the same frequency, there are two antinodes, one on either side of them.
|
|
|
|
|
|
|
|
|
|
// So, for these two antennas with frequency `a`, they create the two antinodes marked with `#`:
|
|
|
|
|
|
|
|
|
|
// ..........
|
|
|
|
|
// ...#......
|
|
|
|
|
// ..........
|
|
|
|
|
// ....a.....
|
|
|
|
|
// ..........
|
|
|
|
|
// .....a....
|
|
|
|
|
// ..........
|
|
|
|
|
// ......#...
|
|
|
|
|
// ..........
|
|
|
|
|
// ..........
|
|
|
|
|
|
|
|
|
|
pub fn find_antinodes(self: &mut Map) -> Vec<PointIdx>
|
|
|
|
|
{
|
|
|
|
|
for ant in &self.antenna_locations
|
|
|
|
|
let mut antinodes: Vec<PointIdx> = vec![];
|
|
|
|
|
for (_freq, locations) in &self.antenna_locations
|
|
|
|
|
{
|
|
|
|
|
let mut i = 0;
|
|
|
|
|
while i < locations.len()
|
|
|
|
|
{
|
|
|
|
|
let mut j = 0;
|
|
|
|
|
while j < locations.len()
|
|
|
|
|
{
|
|
|
|
|
if i == j
|
|
|
|
|
{
|
|
|
|
|
j += 1;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let x1 = locations[i].i as f32;
|
|
|
|
|
let y1 = locations[i].j as f32;
|
|
|
|
|
let x2 = locations[j].i as f32;
|
|
|
|
|
let y2 = locations[j].j as f32;
|
|
|
|
|
let dist = ((x2 - x1).powf(2.0) + (y2 - y1).powf(2.0)).sqrt() * 2.0;
|
|
|
|
|
|
|
|
|
|
let first_glm = Vec2::new(locations[i].i as f32, locations[i].j as f32);
|
|
|
|
|
let second_glm = Vec2::new(locations[j].i as f32, locations[j].j as f32);
|
|
|
|
|
|
|
|
|
|
let direction = (second_glm - first_glm).normalize();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let new_i = (locations[i].i as f32 + direction.x * dist);
|
|
|
|
|
let new_j = (locations[i].j as f32 + direction.y * dist);
|
|
|
|
|
|
|
|
|
|
if new_i < 0.0 || new_j < 0.0
|
|
|
|
|
{
|
|
|
|
|
j += 1;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if new_i >= self.map.len() as f32 ||
|
|
|
|
|
new_j >= self.map[0].len() as f32
|
|
|
|
|
{
|
|
|
|
|
j += 1;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let antinode_location = PointIdx::new(new_i as usize, new_j as usize);
|
|
|
|
|
|
|
|
|
|
if !antinodes.contains(&antinode_location)
|
|
|
|
|
{
|
|
|
|
|
antinodes.push(antinode_location);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
j += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vec![]
|
|
|
|
|
self.antinodes = antinodes;
|
|
|
|
|
self.antinodes.clone()
|
|
|
|
|
}
|
|
|
|
|
}
|