Newton's Third Law
This commit is contained in:
parent
69355204d7
commit
351a85f484
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue