Newton's Third Law

This commit is contained in:
mars 2022-11-04 23:06:59 -06:00
parent 69355204d7
commit 351a85f484
1 changed files with 35 additions and 9 deletions

View File

@ -18,7 +18,7 @@ impl Default for Body {
position: Vec2::ZERO,
velocity: Vec2::ZERO,
acceleration: Vec2::ZERO,
friction: 0.015,
friction: 0.001,
mass: 1.0,
fixed: false,
}
@ -241,7 +241,7 @@ pub struct Constraint {
impl Constraint {
pub fn apply(&self, mut delta: Vec2) -> Vec2 {
const ALPHA: f32 = 0.4;
const ALPHA: f32 = 0.99;
let distance = delta.length();
let displacement = distance - self.length;
delta *= displacement / distance * self.strength * ALPHA;
@ -276,6 +276,24 @@ impl ForceGraph {
}
}
pub fn reaction(&self, from: usize, to: usize, delta: Vec2) -> (Vec2, Vec2) {
let from_fixed = self.nodes[from].body.fixed;
let to_fixed = self.nodes[to].body.fixed;
if from_fixed {
let from = Vec2::ZERO;
let to = if to_fixed { Vec2::ZERO } else { -delta };
(from, to)
} else if to_fixed {
let to = Vec2::ZERO;
let from = if from_fixed { Vec2::ZERO } else { delta };
(from, to)
} else {
let half_delta = delta / 2.0;
(half_delta, -half_delta)
}
}
pub fn with_unhidden<R>(
&self,
from: usize,
@ -294,7 +312,10 @@ impl ForceGraph {
pub fn apply_springs(&mut self, dt: f32) {
for spring in self.springs.iter() {
let vel = self.with_unhidden(spring.from, spring.to, |from, to| {
let from = spring.from;
let to = spring.to;
let vel = self.with_unhidden(from, to, |from, to| {
let from = from.body.position + from.body.velocity * dt;
let to = to.body.position + to.body.velocity * dt;
let delta = to - from;
@ -302,8 +323,9 @@ impl ForceGraph {
});
if let Some(vel) = vel {
self.nodes[spring.from].body.apply_velocity(vel);
self.nodes[spring.to].body.apply_velocity(-vel);
let (from_vel, to_vel) = self.reaction(from, to, vel);
self.nodes[from].body.apply_velocity(from_vel);
self.nodes[to].body.apply_velocity(to_vel);
}
}
}
@ -311,8 +333,11 @@ impl ForceGraph {
pub fn apply_repulsion(&mut self) {
for i in 1..self.nodes.len() {
for j in i..self.nodes.len() {
let force = self.with_unhidden(i - 1, j, |from, to| {
const REPULSION_CONSTANT: f32 = 500.0;
let from = i - 1;
let to = j;
let force = self.with_unhidden(from, to, |from, to| {
const REPULSION_CONSTANT: f32 = 1000.0;
let delta = to.body.position - from.body.position;
let proximity = delta.length().max(0.1);
let force = -(REPULSION_CONSTANT / (proximity * proximity));
@ -320,8 +345,9 @@ impl ForceGraph {
});
if let Some(force) = force {
self.nodes[i - 1].body.apply_force(force);
self.nodes[j].body.apply_force(-force);
let (from_force, to_force) = self.reaction(from, to, force);
self.nodes[from].body.apply_force(from_force);
self.nodes[to].body.apply_force(to_force);
}
}
}