Approximate trigonometry without LUTs.
This commit is contained in:
parent
6a2d19e984
commit
fe795b536f
@ -1,6 +1,7 @@
|
|||||||
mod blur;
|
mod blur;
|
||||||
mod grid;
|
mod grid;
|
||||||
mod model;
|
mod model;
|
||||||
|
mod trig;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let model = model::Model::new(4, 4, 20, 1);
|
let model = model::Model::new(4, 4, 20, 1);
|
||||||
|
|||||||
28
src/model.rs
28
src/model.rs
@ -1,4 +1,4 @@
|
|||||||
use crate::grid::Grid;
|
use crate::{grid::Grid, trig};
|
||||||
|
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
@ -12,6 +12,7 @@ struct Agent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Agent {
|
impl Agent {
|
||||||
|
/// Construct a new agent with random parameters.
|
||||||
fn new(width: usize, height: usize) -> Self {
|
fn new(width: usize, height: usize) -> Self {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let (x, y, angle) = rng.gen::<(f32, f32, f32)>();
|
let (x, y, angle) = rng.gen::<(f32, f32, f32)>();
|
||||||
@ -48,7 +49,7 @@ impl PopulationConfig {
|
|||||||
const DECAY_FACTOR_MIN: f32 = 0.1;
|
const DECAY_FACTOR_MIN: f32 = 0.1;
|
||||||
const DECAY_FACTOR_MAX: f32 = 0.1;
|
const DECAY_FACTOR_MAX: f32 = 0.1;
|
||||||
|
|
||||||
/// Generate a random configuration.
|
/// Construct a random configuration.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
@ -83,6 +84,7 @@ pub struct Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
|
/// Construct a new model with random initial conditions and random configuration.
|
||||||
pub fn new(width: usize, height: usize, n_particles: usize, diffusivity: usize) -> Self {
|
pub fn new(width: usize, height: usize, n_particles: usize, diffusivity: usize) -> Self {
|
||||||
Model {
|
Model {
|
||||||
agents: (0..n_particles)
|
agents: (0..n_particles)
|
||||||
@ -94,4 +96,26 @@ impl Model {
|
|||||||
iteration: 0,
|
iteration: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn step(&mut self) {
|
||||||
|
let sensor_distance = self.config.sensor_distance;
|
||||||
|
let sensor_angle = self.config.sensor_angle;
|
||||||
|
|
||||||
|
for agent in self.agents.iter_mut() {
|
||||||
|
let xc = agent.x + trig::cos(agent.angle) * sensor_distance;
|
||||||
|
let yc = agent.y + trig::sin(agent.angle) * sensor_distance;
|
||||||
|
let xl = agent.x + trig::cos(agent.angle - sensor_angle) * sensor_distance;
|
||||||
|
let yl = agent.y + trig::sin(agent.angle - sensor_angle) * sensor_distance;
|
||||||
|
let xr = agent.x + trig::cos(agent.angle + sensor_angle) * sensor_distance;
|
||||||
|
let yr = agent.y + trig::sin(agent.angle + sensor_angle) * sensor_distance;
|
||||||
|
|
||||||
|
// Sense
|
||||||
|
let trail_c = self.grid.get(xc, yc);
|
||||||
|
let trail_l = self.grid.get(xl, yl);
|
||||||
|
let trail_r = self.grid.get(xr, yr);
|
||||||
|
// Rotate
|
||||||
|
// Move
|
||||||
|
}
|
||||||
|
// Deposit + Diffuse + Decay
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/trig.rs
Normal file
27
src/trig.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/// From https://bits.stephan-brumme.com/absFloat.html
|
||||||
|
pub(crate) fn abs(x: f32) -> f32 {
|
||||||
|
f32::from_bits(x.to_bits() & 0x7FFF_FFFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Branchless floor implementation
|
||||||
|
pub(crate) fn floor(x: f32) -> f32 {
|
||||||
|
let mut x_trunc = (x as i32) as f32;
|
||||||
|
x_trunc -= (x < x_trunc) as i32 as f32;
|
||||||
|
x_trunc
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Approximates `cos(x)` in radians with the maximum error of `0.002`
|
||||||
|
/// https://stackoverflow.com/posts/28050328/revisions
|
||||||
|
pub(crate) fn cos(mut x: f32) -> f32 {
|
||||||
|
const ALPHA: f32 = 0.5 * std::f32::consts::FRAC_1_PI;
|
||||||
|
x *= ALPHA;
|
||||||
|
x -= 0.25_f32 + floor(x + 0.25_f32);
|
||||||
|
x *= 16.0_f32 * (abs(x) - 0.5_f32);
|
||||||
|
x += 0.225_f32 * x * (abs(x) - 1.0_f32);
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Approximates `sin(x)` in radians with the maximum error of `0.002`
|
||||||
|
pub(crate) fn sin(x: f32) -> f32 {
|
||||||
|
cos(x - std::f32::consts::FRAC_PI_2)
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user