use std::f32::consts::PI; use rand::Rng; use crate::system::Position; use crate::system::spaces::continuous_2d::P2; use crate::system::spaces::continuous_3d::P3; use crate::system::spaces::hexagonal::HexPosition; use crate::system::spaces::square_grid::{Grid2D, Grid3D}; pub trait Spawner { fn spawn(&self, rng: &mut R, radius: f32) -> P; } pub struct UniformSpawner; impl Spawner for UniformSpawner { fn spawn(&self, rng: &mut R, radius: f32) -> Grid2D { let theta = rng.gen_range(0f32..1.0) * 2.0 * PI; let (x, y) = (radius * theta.cos(), radius * theta.sin()); Grid2D::from_cartesian([x, y]) } } impl Spawner for UniformSpawner { fn spawn(&self, rng: &mut R, radius: f32) -> HexPosition { let theta = rng.gen_range(0f32..1.0) * 2.0 * PI; let (x, y) = (radius * theta.cos(), radius * theta.sin()); HexPosition::from_cartesian([x, y]) } } impl Spawner for UniformSpawner { fn spawn(&self, rng: &mut R, radius: f32) -> Grid3D { let theta = rng.gen_range(0f32..1.0) * 2.0 * PI; let phi = rng.gen_range(0f32..1.0) * 2.0 * PI; let (x, y, z) = ( radius * theta.sin() * phi.cos(), radius * theta.sin() * phi.sin(), radius * theta.cos() ); Grid3D::from_cartesian([x, y, z]) } } impl Spawner for UniformSpawner { fn spawn(&self, rng: &mut R, radius: f32) -> P3 { P3::random_with_radius(rng, radius) } } impl Spawner for UniformSpawner { fn spawn(&self, rng: &mut R, radius: f32) -> P2 { P2::random_with_radius(rng, radius) } }