183 lines
4.6 KiB
Rust
183 lines
4.6 KiB
Rust
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<f64>{
|
|
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<ObjectG>, 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<ObjectG> = 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));
|
|
}
|
|
}
|