extern crate sdl2; use sdl2::pixels::Color; use sdl2::event::Event; use sdl2::keyboard::Keycode; use sdl2::rect::{Rect}; use sdl2::render::WindowCanvas; use std::time::Duration; use rand::Rng; fn magnitude(x: f64,y: f64) -> f64 { ((x).powi(2) + (y).powi(2)).sqrt() } fn set_mag(x: &f64,y: &f64, mag: &f64) -> Vec{ let getmag: f64 = magnitude(*x, *y); let rx = (*x / getmag) * mag; let ry = (*y / getmag) * mag; return vec![rx,ry] } //i know i can use sdl points but i wanna make my own thing. //plus this is more independant. struct Point{ x: f64, y: f64, } impl Point{ fn add(&mut self, addvec: &Point){ self.x = self.x + addvec.x; self.y = self.y + addvec.y; } fn sub(&mut self, subvec: &Point){ self.x = self.x - subvec.x; self.y = self.y - subvec.y; } fn set_mag(&mut self, mag: &f64) { let smag = set_mag(&self.x, &self.y, &mag); self.x = smag[0]; self.y = smag[1]; } } struct ObjectG{ pos: Point, vel: Point, acc: Point, size: i32, mass: f64, } impl ObjectG{ fn apply_force(&mut self, force: &Point){ let force = Point { x: force.x / self.mass, y: force.y / self.mass }; self.acc.add(&force); } fn walk(&mut self) { self.vel.add(&self.acc); self.pos.add(&self.vel); self.acc=Point{x:0.0, y:0.0} } } struct Attractor{ pos: Point, size: i32, mass: f64, } impl Attractor{ fn attract(&mut self, obj: &mut ObjectG){ let mut force = Point{x: self.pos.x, y: self.pos.y}; force.sub(&obj.pos); let dist = magnitude(force.x, force.y); let mut dist = dist * dist; if dist < 100.0 { dist = 100.0 } if dist > 1000.0 { dist = 1000.0 } let g = 5.0; let strength = g * (self.mass * obj.mass) / dist; force.set_mag(&strength); obj.apply_force(&force); } } fn draw(canvas: &mut WindowCanvas, obj_arr: &mut Vec, atr: &mut Attractor){ canvas.set_draw_color(Color::RGBA(0,0,0,50)); canvas.fill_rect(Rect::new(0,0,600,600)).err(); //canvas.clear(); for obj in obj_arr{ obj.walk(); canvas.set_draw_color(Color::RGBA(150,50,255,150)); canvas.fill_rect(Rect::new(obj.pos.x as i32 - obj.size, obj.pos.y as i32 - obj.size, (obj.size * 2) as u32, (obj.size * 2) as u32)).err(); canvas.set_draw_color(Color::RGB(150,50,255)); canvas.draw_rect(Rect::new(obj.pos.x as i32 - obj.size, obj.pos.y as i32 - obj.size, (obj.size * 2) as u32, (obj.size * 2) as u32)).err(); atr.attract(obj); } canvas.set_draw_color(Color::RGB(255,50,150)); canvas.fill_rect(Rect::new(atr.pos.x as i32 - atr.size, atr.pos.y as i32 - atr.size, (atr.size * 2) as u32, (atr.size * 2) as u32)).err(); canvas.present(); } fn main() { let sdl2_context = sdl2::init().unwrap(); let video_subsystem = sdl2_context.video().unwrap(); let width: u32=600; let height: u32=600; let window = video_subsystem.window("grav-attraction-point", width, height) .position_centered() .build() .unwrap(); let mut canvas = window.into_canvas().build().unwrap(); canvas.default_pixel_format(); canvas.set_blend_mode(sdl2::render::BlendMode::Blend); let mut obj_arr: Vec = Vec::new(); for _ in 0..10{ let mut rng = rand::rng(); let mut obj = ObjectG{ pos: Point { x: rng.random_range(6.0..width as f64 -1.0), y: rng.random_range(6.0..width as f64 -1.0)}, vel: Point { x: rng.random_range(-11.0..10.0), y: rng.random_range(-11.0..10.0)}, acc: Point { x: 0.0, y: 0.0 }, size: 0, mass: rng.random_range(50.0..150.0), }; obj.size = (obj.mass.sqrt() * 2.0) as i32; obj_arr.push(obj); } let mut atr = Attractor{ pos: Point{x: width as f64 /2.0, y: height as f64 /2.0}, size: 0, mass: 100.0, }; atr.size = (atr.mass.sqrt() * 2.0) as i32; canvas.set_draw_color(Color::RGB(0,0,0)); canvas.clear(); let mut event_pump = sdl2_context.event_pump().unwrap(); draw(&mut canvas, &mut obj_arr, &mut atr); 'running: loop { draw(&mut canvas, &mut obj_arr, &mut atr); for event in event_pump.poll_iter() { match event { Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => { break 'running }, _ => {} } } ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)); } }