Merge branch 'dev'
This commit is contained in:
commit
7733b5262a
2
deploy
2
deploy
@ -15,4 +15,4 @@ elif [[ $(hostname) == "lentilz" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo >&2
|
echo >&2
|
||||||
echo >&2 "Deployed to https://laddhoffman.com/gravity/"
|
echo >&2 "Deployed to https://gravity.laddhoffman.com"
|
||||||
|
|||||||
@ -31,6 +31,9 @@ export class MassObject {
|
|||||||
forces = []; // [{x, y}]
|
forces = []; // [{x, y}]
|
||||||
history = [];
|
history = [];
|
||||||
alive = true;
|
alive = true;
|
||||||
|
kineticEnergy = 0;
|
||||||
|
workDoneByPointer = 0;
|
||||||
|
workDoneByForces = 0;
|
||||||
|
|
||||||
currentPosition = undefined;
|
currentPosition = undefined;
|
||||||
currentAcceleration = undefined;
|
currentAcceleration = undefined;
|
||||||
@ -56,7 +59,8 @@ export class MassObject {
|
|||||||
color: this.color,
|
color: this.color,
|
||||||
timeCreated: this.timeCreated,
|
timeCreated: this.timeCreated,
|
||||||
alive: this.alive,
|
alive: this.alive,
|
||||||
// TODO: optional export history
|
workDoneByPointer: this.workDoneByPointer,
|
||||||
|
workDoneByForces: this.workDoneByForces,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,8 +73,9 @@ export class MassObject {
|
|||||||
this.color = obj.color;
|
this.color = obj.color;
|
||||||
this.timeCreated = obj.timeCreated;
|
this.timeCreated = obj.timeCreated;
|
||||||
this.alive = obj.alive;
|
this.alive = obj.alive;
|
||||||
// TODO: optional import history
|
|
||||||
this.history = [];
|
this.history = [];
|
||||||
|
this.workDoneByPointer = obj.workDoneByPointer;
|
||||||
|
this.workDoneByForces = obj.workDoneByForces;
|
||||||
}
|
}
|
||||||
|
|
||||||
get age() {
|
get age() {
|
||||||
|
|||||||
@ -30,13 +30,12 @@ export class Panning {
|
|||||||
toJSON() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
velocity: this.velocity,
|
velocity: this.velocity,
|
||||||
paused: this.paused,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fromJSON({velocity, paused}) {
|
fromJSON({velocity}) {
|
||||||
this.velocity = copy(velocity);
|
this.velocity = copy(velocity);
|
||||||
this.paused = paused;
|
this.paused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePointerDown({x, y}) {
|
handlePointerDown({x, y}) {
|
||||||
|
|||||||
@ -46,10 +46,10 @@ export class Pointer {
|
|||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('focus', () => {
|
window.addEventListener('focus', () => {
|
||||||
console.log('window focus');
|
// console.log('window focus');
|
||||||
});
|
});
|
||||||
window.addEventListener('blur', () => {
|
window.addEventListener('blur', () => {
|
||||||
console.log('window blur');
|
// console.log('window blur');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -141,6 +141,7 @@ export class Sim {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fromJSON(state) {
|
fromJSON(state) {
|
||||||
|
this.pause();
|
||||||
this.system.fromJSON(state.system);
|
this.system.fromJSON(state.system);
|
||||||
this.panning.fromJSON(state.panning);
|
this.panning.fromJSON(state.panning);
|
||||||
this.display.fromJSON(state.display);
|
this.display.fromJSON(state.display);
|
||||||
|
|||||||
4
sync
4
sync
@ -16,9 +16,9 @@ do_rsync() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do_rsync ~/code/gravity-dev/ lentilz:code/gravity-dev/
|
do_rsync ~/code/gravity-dev/ lentilz:code/gravity-dev/
|
||||||
do_rsync lentilz:code/gravity-dev/ ~/code/gravity-dev/
|
# do_rsync lentilz:code/gravity-dev/ ~/code/gravity-dev/
|
||||||
|
|
||||||
git status
|
git status
|
||||||
|
|
||||||
echo >&2
|
echo >&2
|
||||||
echo >&2 "Synced with https://laddhoffman.com/gravity-dev/"
|
echo >&2 "Synced with https://gravity.dev.laddhoffman.com"
|
||||||
|
|||||||
19
system.js
19
system.js
@ -68,7 +68,11 @@ export class System {
|
|||||||
const obj = this.getSelectedOrCreating();
|
const obj = this.getSelectedOrCreating();
|
||||||
if (obj === undefined) return;
|
if (obj === undefined) return;
|
||||||
const start = this.selectedObjectStart;
|
const start = this.selectedObjectStart;
|
||||||
obj.position = add(start, sub(r, start.pointer));
|
const delta = sub(r, start.pointer);
|
||||||
|
// TODO: Calculate work done by pointer here?
|
||||||
|
// Either interpolate the acceleration and use m*a, or
|
||||||
|
// measure the change in the object's kinetic energy
|
||||||
|
obj.position = add(start, delta);
|
||||||
obj.velocity = zero;
|
obj.velocity = zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,8 +175,8 @@ export class System {
|
|||||||
const delta = sub(obj.currentPosition, obj.position);
|
const delta = sub(obj.currentPosition, obj.position);
|
||||||
const netForce = mult(obj.acceleration, obj.mass);
|
const netForce = mult(obj.acceleration, obj.mass);
|
||||||
const work = dot(netForce, delta);
|
const work = dot(netForce, delta);
|
||||||
console.log('work', work);
|
|
||||||
obj.position = obj.currentPosition;
|
obj.position = obj.currentPosition;
|
||||||
|
obj.workDoneByPointer += work;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append to object history
|
// Append to object history
|
||||||
@ -408,11 +412,20 @@ export class System {
|
|||||||
// Equal and opposite forces
|
// Equal and opposite forces
|
||||||
A.forces.push({x: Fx, y: Fy});
|
A.forces.push({x: Fx, y: Fy});
|
||||||
B.forces.push({x: -Fx, y: -Fy});
|
B.forces.push({x: -Fx, y: -Fy});
|
||||||
|
if (A.currentPosition && B.currentPosition) {
|
||||||
|
A.workDoneByForces += dot({x: Fx, y: Fy}, sub(A.position, A.currentPosition));
|
||||||
|
B.workDoneByForces += dot({x: Fx, y: Fy}, sub(B.position, B.currentPosition));
|
||||||
|
}
|
||||||
}, {alive: true, startWith: i + 1});
|
}, {alive: true, startWith: i + 1});
|
||||||
});
|
});
|
||||||
// Also compute acceleration
|
|
||||||
|
// Additional computations
|
||||||
this.forEachObject(obj => {
|
this.forEachObject(obj => {
|
||||||
|
// Acceleration
|
||||||
obj.acceleration = obj.getAcceleration();
|
obj.acceleration = obj.getAcceleration();
|
||||||
|
|
||||||
|
// Kinetic Energy
|
||||||
|
obj.kineticEnergy = obj.mass * square(obj.velocity) / 2;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import {hide, show} from '../helper.js';
|
import {hide, show} from '../helper.js';
|
||||||
import {Tool} from '../tool.js';
|
import {Tool} from '../tool.js';
|
||||||
import {add, magnitude, sub} from '../vector.js';
|
|
||||||
|
|
||||||
export class ObjectsTool extends Tool {
|
export class ObjectsTool extends Tool {
|
||||||
objects = [];
|
objects = [];
|
||||||
@ -58,17 +57,22 @@ export class ObjectsTool extends Tool {
|
|||||||
obj.objectsToolEl = objectEl;
|
obj.objectsToolEl = objectEl;
|
||||||
const {r, g, b} = obj.color;
|
const {r, g, b} = obj.color;
|
||||||
// Distance from center of screen
|
// Distance from center of screen
|
||||||
const distance = magnitude(sub(obj.position, add(this.sim.display.viewOrigin, {
|
// const distance = magnitude(sub(obj.position, add(this.sim.display.viewOrigin, {
|
||||||
x: this.sim.display.width / 2,
|
// x: this.sim.display.width / 2,
|
||||||
y: this.sim.display.height / 2,
|
// y: this.sim.display.height / 2,
|
||||||
})));
|
// })));
|
||||||
objectEl.innerHTML = `
|
objectEl.innerHTML =
|
||||||
<span style="background-color: rgb(${r},${g},${b});">` +
|
`<span style="background-color: rgb(${r},${g},${b});"> </span>` +
|
||||||
' </span>' +
|
`E<sub>k</sub>: ${obj.kineticEnergy.toFixed(0)}` +
|
||||||
`${obj.mass.toPrecision(3)} ` +
|
`<br> W<sub>p</sub>: ${obj.workDoneByPointer.toFixed(0)}` +
|
||||||
`${distance.toPrecision(3)}`;
|
`<br> W<sub>f</sub>: ${obj.workDoneByForces.toFixed(0)}`;
|
||||||
|
|
||||||
|
// `${obj.mass.toPrecision(3)} ` +
|
||||||
|
// `${distance.toPrecision(3)}`;
|
||||||
|
|
||||||
// `${magnitude(obj.velocity).toExponential(0)} ` +
|
// `${magnitude(obj.velocity).toExponential(0)} ` +
|
||||||
// `${-degrees(direction(obj.velocity)).toFixed(0)}°`;
|
// `${-degrees(direction(obj.velocity)).toFixed(0)}°`;
|
||||||
|
|
||||||
if (!obj.hidden) {
|
if (!obj.hidden) {
|
||||||
show({
|
show({
|
||||||
items: this.objects,
|
items: this.objects,
|
||||||
|
|||||||
@ -56,7 +56,6 @@ export class StateTool extends Tool {
|
|||||||
throw new Error('state query parameter does not match digest query parameter');
|
throw new Error('state query parameter does not match digest query parameter');
|
||||||
}
|
}
|
||||||
// Tools in this system can be very powerful
|
// Tools in this system can be very powerful
|
||||||
this.sim.pause();
|
|
||||||
this.sim.fromJSON(state);
|
this.sim.fromJSON(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +98,6 @@ export class StateTool extends Tool {
|
|||||||
load.addEventListener('click', (e) => {
|
load.addEventListener('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// Tools in this system can wield great power
|
// Tools in this system can wield great power
|
||||||
this.sim.pause();
|
|
||||||
this.sim.fromJSON(state);
|
this.sim.fromJSON(state);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user