use sketchlib::nannou; 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, } 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 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), ]; 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 = palette[i as usize % palette.len()]; let speed = (G * MASS_SUN as f64 / r).sqrt(); println!("{}", speed); 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(); }