sketch-gravity/src/main.rs

124 lines
2.9 KiB
Rust
Raw Permalink Normal View History

2021-08-24 04:26:58 +00:00
use nannou::prelude::*;
use rayon::prelude::*;
2021-08-28 01:22:58 +00:00
mod recording;
2021-08-24 04:26:58 +00:00
fn main() {
2021-08-28 01:22:58 +00:00
nannou::app(model)
.size(1440, 1440)
.update(update)
.simple_window(view)
.run();
2021-08-24 04:26:58 +00:00
}
#[derive(Clone)]
struct Body {
pos: DVec2,
vel: DVec2,
2021-08-28 01:22:58 +00:00
mass: i64,
2021-08-28 04:58:04 +00:00
color: Rgb,
2021-08-24 04:26:58 +00:00
}
struct Model {
bodies: Vec<Body>,
}
fn model(_app: &App) -> Model {
let mut bodies = Vec::new();
2021-08-28 04:58:04 +00:00
const MASS_SUN: i64 = 50000000000000000;
2021-08-24 04:26:58 +00:00
2021-08-28 01:22:58 +00:00
bodies.push(Body {
pos: (0.0, 0.0).into(),
vel: (0.0, 0.0).into(),
mass: MASS_SUN,
2021-08-28 04:58:04 +00:00
color: rgb(1.0, 1.0, 1.0),
2021-08-28 01:22:58 +00:00
});
const G: f64 = 6.67408e-11;
const COPIES: i32 = 1;
2021-08-24 04:26:58 +00:00
2021-08-28 01:22:58 +00:00
let d_theta: f64 = (360.0 / COPIES as f64).to_radians();
2021-08-28 04:58:04 +00:00
let palette = &[
rgb(85.0 / 255.0, 205.0 / 255.0, 252.0 / 255.0),
rgb(1.0, 1.0, 1.0),
rgb(247.0 / 255.0, 168.0 / 255.0, 184.0 / 255.0),
];
2021-08-28 01:22:58 +00:00
for i in 0..COPIES {
2021-08-28 04:58:04 +00:00
let mut theta = i as f64 * d_theta;
2021-08-28 01:22:58 +00:00
2021-08-28 04:58:04 +00:00
for i in 1..=256 {
let r = 25.0 + 5.0 * i as f64;
let m = 50000000000u64 / i;
let curr_color = palette[i as usize % palette.len()];
2021-08-28 01:22:58 +00:00
bodies.push(Body {
pos: (r * theta.cos(), r * theta.sin()).into(),
vel: (0.0, (G * MASS_SUN as f64 / r).sqrt()).into(),
2021-08-28 04:58:04 +00:00
mass: m as i64,
color: curr_color,
2021-08-28 01:22:58 +00:00
});
2021-08-28 04:58:04 +00:00
theta += 1.94161103873;
2021-08-28 01:22:58 +00:00
}
2021-08-24 04:26:58 +00:00
}
Model { bodies }
}
fn update(app: &App, model: &mut Model, _update: Update) {
const G: f64 = 6.67408e-11;
let bodies = model.bodies.clone();
2021-08-28 01:22:58 +00:00
let delta_t = recording::delta_t(&app);
2021-08-24 04:26:58 +00:00
model
.bodies
.par_iter_mut()
.enumerate()
.for_each(|(i, body)| {
let mut acc: DVec2 = (0.0, 0.0).into();
bodies.iter().enumerate().for_each(|(j, other_body)| {
if i == j {
return;
}
let delta = other_body.pos - body.pos;
let dist_sq = body.pos.distance_squared(other_body.pos);
2021-08-28 04:58:04 +00:00
if dist_sq <= (body.mass as f64).log10() {
2021-08-24 04:26:58 +00:00
return;
}
2021-08-28 01:22:58 +00:00
let acceleration = G * other_body.mass as f64 / dist_sq;
2021-08-24 04:26:58 +00:00
2021-08-28 01:22:58 +00:00
acc += delta * acceleration / dist_sq.sqrt();
2021-08-24 04:26:58 +00:00
});
body.vel += acc * delta_t;
body.pos += body.vel * delta_t;
});
}
fn view(app: &App, model: &Model, frame: Frame) {
// let t = app.duration.since_start.as_secs_f64();
2021-08-28 04:58:04 +00:00
let draw = app.draw().scale(1.0);
2021-08-24 04:26:58 +00:00
draw.background().color(BLACK);
for body in model.bodies.iter() {
2021-08-28 04:58:04 +00:00
let diameter = (body.mass as f32).log10() * 2.0; // should be proportional to cuberoot but this is so we can actually see the small ones
draw.ellipse()
.w_h(diameter, diameter)
.xy(body.pos.as_f32())
.color(body.color);
2021-08-24 04:26:58 +00:00
}
draw.to_frame(app, &frame).unwrap();
2021-08-28 01:22:58 +00:00
recording::record(app, &frame);
2021-08-24 04:26:58 +00:00
}