Initial commit of canvas with two planets

This commit is contained in:
Marco 2024-07-07 01:47:03 +02:00
commit 75bed957c4
7 changed files with 2475 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

2293
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

14
Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "phuesicks"
version = "0.1.0"
edition = "2021"
author = "Marco Groß"
[[bin]]
name = "phuesicks"
[dependencies]
piston = "1.0.0"
piston2d-graphics = "0.44.0"
pistoncore-glutin_window = "0.72.0"
piston2d-opengl_graphics = "0.85.0"

41
src/canvas.rs Normal file
View File

@ -0,0 +1,41 @@
use opengl_graphics::GlGraphics;
use piston::{RenderArgs, UpdateArgs};
use super::planet::Planet;
pub struct Canvas {
pub gl: GlGraphics,
pub planets: Vec<Planet>,
}
impl Canvas {
pub fn render(&mut self, args: &RenderArgs) {
use graphics::*;
const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];
const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0];
let middle = (args.window_size[0] / 2.0, args.window_size[1] / 2.0);
self.gl.draw(args.viewport(), |c, gl| {
clear(BLACK, gl);
//get all planets and draw them here
for planet in &self.planets {
let circle = ellipse::circle(0.0, 0.0, planet.radius);
let transform = c
.transform
.trans(middle.0, middle.1)
.trans(planet.pos[0], planet.pos[1]);
ellipse(RED, circle, transform, gl);
}
});
}
pub fn update(&mut self, args: &UpdateArgs) {
for planet in self.planets.iter_mut() {
planet.pos = vec![planet.pos[0] + 1.0 * args.dt, planet.pos[1] + 1.0 * args.dt];
}
}
}

51
src/main.rs Normal file
View File

@ -0,0 +1,51 @@
extern crate glutin_window;
extern crate graphics;
extern crate opengl_graphics;
extern crate piston;
mod canvas;
mod physics;
mod planet;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{GlGraphics, OpenGL};
use piston::event_loop::{EventSettings, Events};
use piston::input::{RenderEvent, UpdateEvent};
use piston::window::WindowSettings;
fn main() {
let opengl = OpenGL::V4_5;
let mut window: Window = WindowSettings::new("phuesicks", [200, 200])
.graphics_api(opengl)
.exit_on_esc(true)
.build()
.unwrap();
let mut canvas = canvas::Canvas {
gl: GlGraphics::new(opengl),
planets: vec![
planet::PlanetBuilder::new()
.with_positsion(-100.0, 0.0)
.with_mass(100.0)
.with_radius(40.0)
.build(),
planet::PlanetBuilder::new()
.with_positsion(100.0, 0.0)
.with_mass(10.0)
.with_radius(20.0)
.build(),
],
};
let mut events = Events::new(EventSettings::new());
while let Some(e) = events.next(&mut window) {
if let Some(args) = e.render_args() {
canvas.render(&args);
}
if let Some(args) = e.update_args() {
canvas.update(&args);
}
}
}

12
src/physics.rs Normal file
View File

@ -0,0 +1,12 @@
use crate::planet::Planet;
const GRAVITATIONAL_CONTANT: f64 = 6.67430e-11;
pub fn force_between(p1: &Planet, p2: &Planet) -> Vec<f64> {
let dist = p1.distance_to(p2);
let norm_vec = p1.normal_vec_to(p2);
let scalar_part = GRAVITATIONAL_CONTANT * p1.get_mass() * p2.get_mass() / dist.powf(2.0);
vec![scalar_part * norm_vec[0], scalar_part * norm_vec[1]]
}

63
src/planet.rs Normal file
View File

@ -0,0 +1,63 @@
pub struct Planet {
pub mass: f64,
pub pos: Vec<f64>,
pub radius: f64,
}
impl Planet {
pub fn get_mass(&self) -> f64 {
return self.mass;
}
pub fn distance_vec_to(&self, other: &Planet) -> Vec<f64> {
let res: Vec<f64> = vec![other.pos[0] - self.pos[0], other.pos[1] - self.pos[1]];
res
}
pub fn distance_to(&self, other: &Planet) -> f64 {
let as_vec = self.distance_vec_to(other);
(as_vec[0].powf(2.0) + as_vec[1].powf(2.0)).sqrt()
}
pub fn normal_vec_to(&self, other: &Planet) -> Vec<f64> {
let vec = self.distance_vec_to(other);
let dist = self.distance_to(other);
vec![vec[0] / dist, vec[1] / dist]
}
}
pub struct PlanetBuilder {
planet: Planet,
}
impl PlanetBuilder {
pub fn new() -> PlanetBuilder {
return PlanetBuilder {
planet: Planet {
mass: 0.0,
pos: vec![0.0, 0.0],
radius: 0.0,
},
};
}
pub fn with_mass(mut self, mass: f64) -> PlanetBuilder {
self.planet.mass = mass;
self
}
pub fn with_positsion(mut self, x: f64, y: f64) -> PlanetBuilder {
self.planet.pos = vec![x, y];
self
}
pub fn with_radius(mut self, r: f64) -> PlanetBuilder {
self.planet.radius = r;
self
}
pub fn build(self) -> Planet {
return self.planet;
}
}