corrected velocity verlet
This commit is contained in:
parent
3b2122d2e6
commit
b41d6dd488
@ -6,20 +6,21 @@ export const DISPLAY_CURRENT_MODE = false;
|
|||||||
export const DISPLAY_VELOCITY_VECTORS = true;
|
export const DISPLAY_VELOCITY_VECTORS = true;
|
||||||
export const DISPLAY_ACCELERATION_VECTORS = true;
|
export const DISPLAY_ACCELERATION_VECTORS = true;
|
||||||
|
|
||||||
export const MASS_CREATION_RATE = 0.001;
|
export const MASS_CREATION_RATE = 1E1;
|
||||||
export const POINTER_HISTORY_SIZE = 15;
|
export const POINTER_HISTORY_SIZE = 15;
|
||||||
|
|
||||||
export const VELOCITY_VECTOR_SCALE = 0.1;
|
export const VELOCITY_VECTOR_SCALE = 5E0;
|
||||||
export const VELOCITY_VECTOR_COLOR = 'rgb(150, 150, 150)'; // optionally set to 'object color'
|
export const VELOCITY_VECTOR_COLOR = 'rgb(150, 150, 150)'; // optionally set to 'object color'
|
||||||
export const VELOCITY_VECTOR_WIDTH = 1.5;
|
export const VELOCITY_VECTOR_WIDTH = 1.5;
|
||||||
export const VELOCITY_VECTOR_ARROWHEAD = true;
|
export const VELOCITY_VECTOR_ARROWHEAD = true;
|
||||||
|
|
||||||
export const ACCELERATION_VECTOR_SCALE = 1E-1;
|
export const ACCELERATION_VECTOR_SCALE = 5E0;
|
||||||
export const ACCELERATION_VECTOR_COLOR = 'rgb(0, 255, 0)'; // optionally set to 'object color'
|
export const ACCELERATION_VECTOR_COLOR = 'rgb(0, 255, 0)'; // optionally set to 'object color'
|
||||||
|
// export const ACCELERATION_VECTOR_COLOR = 'object color';
|
||||||
export const ACCELERATION_VECTOR_WIDTH = 1.5;
|
export const ACCELERATION_VECTOR_WIDTH = 1.5;
|
||||||
export const ACCELERATION_VECTOR_ARROWHEAD = true;
|
export const ACCELERATION_VECTOR_ARROWHEAD = true;
|
||||||
|
|
||||||
export const MOTION_TIME_SCALE = 5E-5;
|
export const MOTION_TIME_SCALE = 1E-4;
|
||||||
export const PAN_VELOCITY_SCALE_FACTOR = 1E-3;
|
export const PAN_VELOCITY_SCALE_FACTOR = 1E-3;
|
||||||
|
|
||||||
export const ARROWHEAD_LENGTH = 7;
|
export const ARROWHEAD_LENGTH = 7;
|
||||||
|
|||||||
16
display.js
16
display.js
@ -147,10 +147,11 @@ export class Display {
|
|||||||
|
|
||||||
// Draw arrow for the velocity
|
// Draw arrow for the velocity
|
||||||
if (DISPLAY_VELOCITY_VECTORS) {
|
if (DISPLAY_VELOCITY_VECTORS) {
|
||||||
const endVx = x + VELOCITY_VECTOR_SCALE * vx;
|
const speed = Math.sqrt(vx ** 2 + vy ** 2);
|
||||||
const endVy = y + VELOCITY_VECTOR_SCALE * vy;
|
const endVx = x + VELOCITY_VECTOR_SCALE * vx / speed * Math.log(speed);
|
||||||
|
const endVy = y + VELOCITY_VECTOR_SCALE * vy / speed * Math.log(speed);
|
||||||
const style = VELOCITY_VECTOR_COLOR === 'object color' ?
|
const style = VELOCITY_VECTOR_COLOR === 'object color' ?
|
||||||
ctx.fillStyle : VELOCITY_VECTOR_COLOR;
|
`rgb(${r}, ${g}, ${b})` : VELOCITY_VECTOR_COLOR;
|
||||||
this.drawArrow(x, y, endVx, endVy, {
|
this.drawArrow(x, y, endVx, endVy, {
|
||||||
style,
|
style,
|
||||||
width: VELOCITY_VECTOR_WIDTH,
|
width: VELOCITY_VECTOR_WIDTH,
|
||||||
@ -162,10 +163,13 @@ export class Display {
|
|||||||
|
|
||||||
// Draw arrow for acceleration
|
// Draw arrow for acceleration
|
||||||
if (DISPLAY_ACCELERATION_VECTORS) {
|
if (DISPLAY_ACCELERATION_VECTORS) {
|
||||||
const endAx = x + ACCELERATION_VECTOR_SCALE * acceleration.x;
|
const accelerationMagnitude = Math.sqrt(acceleration.x ** 2 + acceleration.y ** 2);
|
||||||
const endAy = y + ACCELERATION_VECTOR_SCALE * acceleration.y;
|
const endAx = x + ACCELERATION_VECTOR_SCALE * acceleration.x /
|
||||||
|
accelerationMagnitude * Math.log(accelerationMagnitude);
|
||||||
|
const endAy = y + ACCELERATION_VECTOR_SCALE * acceleration.y /
|
||||||
|
accelerationMagnitude * Math.log(accelerationMagnitude);
|
||||||
const style = ACCELERATION_VECTOR_COLOR === 'object color' ?
|
const style = ACCELERATION_VECTOR_COLOR === 'object color' ?
|
||||||
ctx.fillStyle : ACCELERATION_VECTOR_COLOR;
|
`rgb(${r}, ${g}, ${b})` : ACCELERATION_VECTOR_COLOR;
|
||||||
this.drawArrow(x, y, endAx, endAy, {
|
this.drawArrow(x, y, endAx, endAy, {
|
||||||
style,
|
style,
|
||||||
width: ACCELERATION_VECTOR_WIDTH,
|
width: ACCELERATION_VECTOR_WIDTH,
|
||||||
|
|||||||
@ -4,6 +4,7 @@ export class MassObject {
|
|||||||
density = 1;
|
density = 1;
|
||||||
position = {x: undefined, y: undefined};
|
position = {x: undefined, y: undefined};
|
||||||
velocity = {x: 0, y: 0};
|
velocity = {x: 0, y: 0};
|
||||||
|
acceleration = {x: 0, y: 0};
|
||||||
color = {r: undefined, g: undefined, b: undefined};
|
color = {r: undefined, g: undefined, b: undefined};
|
||||||
created = undefined;
|
created = undefined;
|
||||||
forces = []; // [{x, y}]
|
forces = []; // [{x, y}]
|
||||||
@ -28,7 +29,7 @@ export class MassObject {
|
|||||||
return Math.pow(this.mass / this.density, 1/3);
|
return Math.pow(this.mass / this.density, 1/3);
|
||||||
}
|
}
|
||||||
|
|
||||||
get acceleration() {
|
getAcceleration() {
|
||||||
let ax = 0;
|
let ax = 0;
|
||||||
let ay = 0;
|
let ay = 0;
|
||||||
for (let {x, y} of this.forces) {
|
for (let {x, y} of this.forces) {
|
||||||
|
|||||||
42
objects.js
42
objects.js
@ -114,7 +114,7 @@ export class Objects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
computeForces(elapsedTime) {
|
computeForces() {
|
||||||
if (this.objects.length < 2) return;
|
if (this.objects.length < 2) return;
|
||||||
for (let i = 0; i < this.objects.length; i++) {
|
for (let i = 0; i < this.objects.length; i++) {
|
||||||
this.objects[i].forces = [];
|
this.objects[i].forces = [];
|
||||||
@ -138,6 +138,7 @@ export class Objects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeFrame(elapsedTime) {
|
computeFrame(elapsedTime) {
|
||||||
|
elapsedTime = elapsedTime * MOTION_TIME_SCALE;
|
||||||
// If we're creating an object, increment its mass
|
// If we're creating an object, increment its mass
|
||||||
// with the mass creation rate accelerating over time
|
// with the mass creation rate accelerating over time
|
||||||
if (this.creatingObject !== undefined) {
|
if (this.creatingObject !== undefined) {
|
||||||
@ -146,42 +147,39 @@ export class Objects {
|
|||||||
obj.mass += rate * elapsedTime;
|
obj.mass += rate * elapsedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.sim.playing) {
|
// Calculate forces due to gravity.
|
||||||
// Calculate forces due to gravity.
|
this.computeForces();
|
||||||
this.computeForces(elapsedTime);
|
|
||||||
|
|
||||||
|
if (this.sim.playing) {
|
||||||
// Generate predicted positions (Velocity verlet method)
|
// Generate predicted positions (Velocity verlet method)
|
||||||
for (let i = 0; i < this.objects.length; i++) {
|
for (let i = 0; i < this.objects.length; i++) {
|
||||||
const obj = this.objects[i];
|
const obj = this.objects[i];
|
||||||
obj.currentAcceleration = {...obj.acceleration};
|
obj.currentAcceleration = obj.getAcceleration();
|
||||||
obj.projectedPosition = {
|
obj.position.x += elapsedTime *
|
||||||
x: obj.position.x + MOTION_TIME_SCALE * elapsedTime *
|
(obj.velocity.x + 1/2 * obj.currentAcceleration.x * elapsedTime);
|
||||||
(obj.velocity.x + 1/2 * obj.currentAcceleration.x * elapsedTime),
|
obj.position.y += elapsedTime *
|
||||||
y: obj.position.y + MOTION_TIME_SCALE * elapsedTime *
|
(obj.velocity.y + 1/2 * obj.currentAcceleration.y * elapsedTime);
|
||||||
(obj.velocity.y + 1/2 * obj.currentAcceleration.y * elapsedTime),
|
|
||||||
};
|
|
||||||
obj.currentPosition = {...obj.position};
|
|
||||||
obj.position = obj.projectedPosition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recompute forces
|
// Recompute forces
|
||||||
this.computeForces();
|
this.computeForces();
|
||||||
|
|
||||||
// Average first and second predicted accelerations
|
// Generated predicted velocities
|
||||||
for (let i = 0; i < this.objects.length; i++) {
|
for (let i = 0; i < this.objects.length; i++) {
|
||||||
const obj = this.objects[i];
|
const obj = this.objects[i];
|
||||||
const acceleration = {...obj.acceleration};
|
const acceleration = obj.getAcceleration();
|
||||||
const meanAcceleration = {
|
obj.acceleration = {
|
||||||
x: (obj.currentAcceleration.x + acceleration.x) / 2,
|
x: (obj.currentAcceleration.x + acceleration.x) / 2,
|
||||||
y: (obj.currentAcceleration.y + acceleration.y) / 2,
|
y: (obj.currentAcceleration.y + acceleration.y) / 2,
|
||||||
};
|
};
|
||||||
obj.velocity.x += meanAcceleration.x * MOTION_TIME_SCALE * elapsedTime;
|
obj.velocity.x += obj.acceleration.x * elapsedTime;
|
||||||
obj.velocity.y += meanAcceleration.y * MOTION_TIME_SCALE * elapsedTime;
|
obj.velocity.y += obj.acceleration.y * elapsedTime;
|
||||||
|
}
|
||||||
obj.position.x = obj.currentPosition.x + obj.velocity.x * MOTION_TIME_SCALE * elapsedTime;
|
} else {
|
||||||
obj.position.y = obj.currentPosition.y + obj.velocity.y * MOTION_TIME_SCALE * elapsedTime;
|
for (let i = 0; i < this.objects.length; i++) {
|
||||||
|
const obj = this.objects[i];
|
||||||
|
obj.acceleration = obj.getAcceleration();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display objects info
|
// Display objects info
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user