very late init
This commit is contained in:
182
src/bin/2-5-grav-attraction-point.rs
Normal file
182
src/bin/2-5-grav-attraction-point.rs
Normal file
@@ -0,0 +1,182 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user