59 lines
1.7 KiB
Rust
59 lines
1.7 KiB
Rust
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<P: Position> {
|
|
fn spawn<R: Rng>(&self, rng: &mut R, radius: f32) -> P;
|
|
}
|
|
|
|
pub struct UniformSpawner;
|
|
|
|
impl Spawner<Grid2D> for UniformSpawner {
|
|
fn spawn<R: Rng>(&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<HexPosition> for UniformSpawner {
|
|
fn spawn<R: Rng>(&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<Grid3D> for UniformSpawner {
|
|
fn spawn<R: Rng>(&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<P3> for UniformSpawner {
|
|
fn spawn<R: Rng>(&self, rng: &mut R, radius: f32) -> P3 {
|
|
P3::random_with_radius(rng, radius)
|
|
}
|
|
}
|
|
|
|
impl Spawner<P2> for UniformSpawner {
|
|
fn spawn<R: Rng>(&self, rng: &mut R, radius: f32) -> P2 {
|
|
P2::random_with_radius(rng, radius)
|
|
}
|
|
}
|