113 lines
2.7 KiB
Rust
113 lines
2.7 KiB
Rust
use sketchlib::nannou;
|
|
use sketchlib::palettes::TRANS_FLAG;
|
|
use sketchlib::prelude::*;
|
|
|
|
fn main() {
|
|
nannou::app(model)
|
|
.size(1260, 1260)
|
|
.update(update)
|
|
.simple_window(view)
|
|
.run();
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
struct Body {
|
|
pos: DVec2,
|
|
vel: DVec2,
|
|
mass: i64,
|
|
color: Rgb,
|
|
}
|
|
|
|
struct Model {
|
|
bodies: Vec<Body>,
|
|
}
|
|
|
|
fn model(_app: &App) -> Model {
|
|
let mut bodies = Vec::new();
|
|
|
|
const MASS_SUN: i64 = 50000000000000000;
|
|
|
|
bodies.push(Body {
|
|
pos: (0.0, 0.0).into(),
|
|
vel: (0.0, 0.0).into(),
|
|
mass: MASS_SUN,
|
|
color: rgb(1.0, 1.0, 1.0),
|
|
});
|
|
|
|
const G: f64 = 6.67408e-11;
|
|
|
|
let mut theta = 0.0;
|
|
|
|
for i in 1..=256 {
|
|
let r = 25.0 + 5.0 * i as f64;
|
|
let m = 50000000000u64 / i;
|
|
let curr_color = TRANS_FLAG[i as usize % TRANS_FLAG.len()];
|
|
|
|
let speed = (G * MASS_SUN as f64 / r).sqrt();
|
|
|
|
bodies.push(Body {
|
|
pos: (r * theta.cos(), r * theta.sin()).into(),
|
|
vel: (speed * theta.sin(), speed * -theta.cos()).into(),
|
|
mass: m as i64,
|
|
color: curr_color,
|
|
});
|
|
|
|
theta += 1.94161103873;
|
|
}
|
|
|
|
Model { bodies }
|
|
}
|
|
|
|
fn update(app: &App, model: &mut Model, _update: Update) {
|
|
const G: f64 = 6.67408e-11;
|
|
|
|
let bodies = model.bodies.clone();
|
|
let delta_t = delta_t(&app);
|
|
|
|
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);
|
|
|
|
if dist_sq <= (body.mass as f64).log10() {
|
|
return;
|
|
}
|
|
|
|
let acceleration = G * other_body.mass as f64 / dist_sq;
|
|
|
|
acc += delta * acceleration / dist_sq.sqrt();
|
|
});
|
|
|
|
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();
|
|
|
|
let draw = app.draw().scale(1.0);
|
|
draw.background().color(BLACK);
|
|
|
|
for body in model.bodies.iter() {
|
|
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);
|
|
}
|
|
|
|
draw.to_frame(app, &frame).unwrap();
|
|
dump_frame(app, &frame).unwrap();
|
|
}
|