Skip to content

Commit

Permalink
Merge pull request #12 from ben9583/0.4.0
Browse files Browse the repository at this point in the history
Release 0.4.0
  • Loading branch information
ben9583 committed Jun 17, 2022
2 parents ab2b0ea + 5979db7 commit 481325a
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 56 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "solar-sim"
version = "0.3.1"
version = "0.4.0"
authors = ["Ben Plate <bplate9583@gmail.com>"]
edition = "2018"
description = "Physics simulator written in Rust WASM for use in Solar Sim website"
Expand Down
85 changes: 42 additions & 43 deletions rust-src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ extern crate lazy_static;

mod utils;

use std::ptr;
use std::sync::RwLock;
use wasm_bindgen::prelude::*;
use js_sys::Array;
Expand All @@ -15,10 +14,11 @@ use js_sys::Array;
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

const BIG_G: f64 = 0.00000000006674;
const TIME_STEP: f64 = 1.0;

lazy_static! {
static ref UNIVERSE: RwLock<Vec<Body<'static>>> = RwLock::new(vec![]);
static ref UNIVERSE: RwLock<Vec<Body>> = RwLock::new(vec![]);
static ref TIME_STEP: RwLock<f64> = RwLock::new(0.2);
static ref NUM_SIMS_PER_STEP: RwLock<i32> = RwLock::new(5);
}

#[derive(Clone, Copy)]
Expand All @@ -27,71 +27,62 @@ pub struct Vector2D {
y: f64,
}

pub struct Body<'a> {
#[derive(Clone, Copy)]
pub struct Body {
mass: f64,
position: Vector2D,
velocity: Vector2D,
scene: &'a RwLock<Vec<Body<'a>>>,
}

impl Body<'_> {
fn next_velocity(&self) -> Vector2D {
impl Body {
fn next_velocity(&mut self, uni: &Vec<Body>) {
if self.mass.abs() < 0.000001 {
return self.velocity;
return;
}

let mut out: Vector2D = self.velocity;
let ts = *(TIME_STEP.read().unwrap());

let uni = self.scene.read().unwrap();
for i in 0..uni.len() {
if !ptr::eq(&uni[i], self) && uni[i].mass.abs() > 0.000001 {
if uni[i].mass.abs() > 0.000001 {
let dx = self.position.x - uni[i].position.x;
let dy = self.position.y - uni[i].position.y;

let dist = dx.powf(2.0) + dy.powf(2.0);
if dist < 0.0001 { continue; }

let angle = dy.atan2(dx);

let delta_v = BIG_G * uni[i].mass / (dx.powf(2.0) + dy.powf(2.0)) * TIME_STEP; // (G(m1)(m2)/d^2) / m1 * t = G(m2)/d^2 * t = at = delta_v
let delta_v = (BIG_G * uni[i].mass / dist) * ts; // (G(m1)(m2)/d^2) / m1 * t = G(m2)/d^2 * t = at = delta_v

out.x += delta_v * -angle.cos();
out.y += delta_v * -angle.sin();
self.velocity.x += delta_v * -angle.cos();
self.velocity.y += delta_v * -angle.sin();
}
}

return out;
}

fn next_position(&self) -> Vector2D {
return Vector2D { x: self.position.x + self.velocity.x * TIME_STEP, y: self.position.y + self.velocity.y * TIME_STEP }; // x_new = x_old + vt
fn next_position(&mut self) {
let ts = *(TIME_STEP.read().unwrap());

self.position.x += self.velocity.x * ts;
self.position.y += self.velocity.y * ts;
}
}

#[wasm_bindgen]
pub fn step_time() {
let mut next_velocities: Vec<Vector2D> = vec![];
let mut next_positions: Vec<Vector2D> = vec![];

{
let uni = UNIVERSE.read().unwrap();
for i in 0..uni.len() {
next_velocities.push(uni[i].next_velocity());
}
}
{
let mut uni = UNIVERSE.write().unwrap();
for i in 0..uni.len() {
uni[i].velocity = next_velocities[i];
}
}
{
let uni = UNIVERSE.read().unwrap();
for i in 0..uni.len() {
next_positions.push(uni[i].next_position());
let mut uni = UNIVERSE.write().unwrap();
let num_bodies = uni.len();

let nsps = *(NUM_SIMS_PER_STEP.read().unwrap());

for _ in 0..nsps {
for i in 0..num_bodies {
let mut body = uni[i];
body.next_velocity(&uni);
uni[i] = body;
}
}
{
let mut uni = UNIVERSE.write().unwrap();
for i in 0..uni.len() {
uni[i].position = next_positions[i];
for i in 0..num_bodies {
uni[i].next_position();
}
}
}
Expand All @@ -108,7 +99,6 @@ pub fn add_body(mass: f64, position_x: f64, position_y: f64, velocity_x: f64, ve
x: velocity_x,
y: velocity_y,
},
scene: &UNIVERSE,
};

UNIVERSE.write().unwrap().push(new_body);
Expand Down Expand Up @@ -139,3 +129,12 @@ pub fn get_positions() -> Array {

return out;
}

#[wasm_bindgen]
pub fn set_simulation_accuracy(time_step: f64, num_sims_per_step: i32) {
let mut ts = TIME_STEP.write().unwrap();
*ts = time_step;

let mut nsps = NUM_SIMS_PER_STEP.write().unwrap();
*nsps = num_sims_per_step;
}
27 changes: 27 additions & 0 deletions website-src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,33 @@
<button id="spawn">Spawn</button>
</div>

<p>Settings:</p>
<div style="color:white;float:left;padding-right:25px">
<p>Trail quality:</p>
<div>
<input type="radio" id="highTrailQuality" name="trailQuality" value="high" checked="checked"/>
<label for="highTrailQuality">High</label><br />
<input type="radio" id="mediumTrailQuality" name="trailQuality" value="medium" />
<label for="mediumTrailQuality">Medium</label><br />
<input type="radio" id="lowTrailQuality" name="trailQuality" value="low" />
<label for="lowTrailQuality">Low</label><br />
<input type="radio" id="noneTrailQuality" name="trailQuality" value="none" />
<label for="noneTrailQuality">None</label><br />
</div>
</div>
<div style="color:white;float:left;padding-right:25px">
<p>Simulation Accuracy:</p>
<div>
<input type="radio" id="highSimAccuracy" name="simAccuracy" value="high" />
<label for="highSimAccuracy">High</label><br />
<input type="radio" id="mediumSimAccuracy" name="simAccuracy" value="medium" checked="checked" />
<label for="mediumSimAccuracy">Medium</label><br />
<input type="radio" id="lowSimAccuracy" name="simAccuracy" value="low" />
<label for="lowSimAccuracy">Low</label><br />
</div>
</div>
<div style="clear:left;height:50px"></div>

<input type="checkbox" id="debug" /><span style="color:white">Enable Debug (slightly lowers performance)</span>
<div id="debugSection" style="color:white">
<p># of bodies: <span id="numBodies">6</span></p>
Expand Down
53 changes: 44 additions & 9 deletions website-src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,23 @@ let bodies = [
name: "L1",
mass: 1,
radius: 4,
position: [WIDTH / 2 + 173.9772874357808, HEIGHT / 2],
initialVelocity: [0, 1.592],
position: [WIDTH / 2 + 174.3684756886812, HEIGHT / 2],
initialVelocity: [0, 1.57386005],
color: "#969696",
},
{
name: "L2",
mass: 1,
radius: 4,
position: [WIDTH / 2 + 147, HEIGHT / 2],
initialVelocity: [0, 1.29],
position: [WIDTH / 2 + 146.4437229236931, HEIGHT / 2],
initialVelocity: [0, 1.321809565],
color: "#969696",
},
{
name: "L3",
mass: 1,
radius: 4,
position: [WIDTH / 2 - 160, HEIGHT / 2],
position: [WIDTH / 2 - 159.813705852, HEIGHT / 2],
initialVelocity: [0, -1.444169311403618],
color: "#4b964b",
},
Expand All @@ -49,15 +49,15 @@ let bodies = [
mass: 1,
radius: 4,
position: [WIDTH / 2 + 80, HEIGHT / 2 + (Math.sqrt(3)/2) * 160],
initialVelocity: [-1.444169311403618 * Math.sqrt(3) / 2, 1.444169311403618 * 1/2],
initialVelocity: [-1.25180591705918, 0.7227304831872841],
color: "#4b964b",
},
{
name: "L5",
mass: 1,
radius: 4,
position: [WIDTH / 2 + 80, HEIGHT / 2 - (Math.sqrt(3)/2) * 160],
initialVelocity: [1.444169311403618 * Math.sqrt(3) / 2, 1.444169311403618 * 1/2],
initialVelocity: [1.25180591705918, 0.7227304831872841],
color: "#4b964b",
},
];
Expand Down Expand Up @@ -92,11 +92,46 @@ debugElem.addEventListener("click", (elem, e) => {
else document.getElementById("debugSection").style.visibility = "hidden";
})

const highTrailQualityElem = document.getElementById("highTrailQuality");
const mediumTrailQualityElem = document.getElementById("mediumTrailQuality");
const lowTrailQualityElem = document.getElementById("lowTrailQuality");
const noneTrailQualityElem = document.getElementById("noneTrailQuality");
const highSimAccuracyElem = document.getElementById("highSimAccuracy");
const mediumSimAccuracyElem = document.getElementById("mediumSimAccuracy");
const lowSimAccuracyElem = document.getElementById("lowSimAccuracy");

const canvas = document.getElementById("scene");
const canvas2 = document.getElementById("trails");
const ctx = canvas.getContext("2d");
const ctx2 = canvas2.getContext("2d");

let numTrailParticles = highTrailQualityElem.checked ? 100 : mediumTrailQualityElem.checked ? 50 : lowTrailQualityElem.checked ? 10 : 0;

highTrailQualityElem.addEventListener("click", (elem, e) => {
numTrailParticles = 100;
for(let i = 0; i < trails.length; i++) trails[i] = [];
ctx2.clearRect(0, 0, WIDTH, HEIGHT);
});
mediumTrailQualityElem.addEventListener("click", (elem, e) => {
numTrailParticles = 50;
for(let i = 0; i < trails.length; i++) trails[i] = [];
ctx2.clearRect(0, 0, WIDTH, HEIGHT);
});
lowTrailQualityElem.addEventListener("click", (elem, e) => {
numTrailParticles = 10;
for(let i = 0; i < trails.length; i++) trails[i] = [];
ctx2.clearRect(0, 0, WIDTH, HEIGHT);
});
noneTrailQualityElem.addEventListener("click", (elem, e) => {
numTrailParticles = 0;
for(let i = 0; i < trails.length; i++) trails[i] = [];
ctx2.clearRect(0, 0, WIDTH, HEIGHT);
});

highSimAccuracyElem.addEventListener("click", (elem, e) => { SolarSim.set_simulation_accuracy(0.05, 20) })
mediumSimAccuracyElem.addEventListener("click", (elem, e) => { SolarSim.set_simulation_accuracy(0.2, 5) })
lowSimAccuracyElem.addEventListener("click", (elem, e) => { SolarSim.set_simulation_accuracy(1.0, 1) })

let playing = true;
let tickTime = performance.now();

Expand Down Expand Up @@ -130,8 +165,8 @@ function step(simulate) {
ctx.fill();
}

if(simulate) {
if(trails[i].length >= 100 || (!inBounds && trails[i].length > 0)) {
if(simulate && numTrailParticles > 0 && count % (100 / numTrailParticles) == 0) {
if(trails[i].length >= numTrailParticles || (!inBounds && trails[i].length > 0)) {
let toRemove = trails[i].shift();
ctx2.fillStyle = "black";
ctx2.fillRect(toRemove[0] - 1, toRemove[1] - 1, 5, 5);
Expand Down
4 changes: 2 additions & 2 deletions website-src/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion website-src/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "solar-sim-app",
"version": "0.3.1",
"version": "0.4.0",
"description": "Creates the Solar Sim website.",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit 481325a

Please sign in to comment.