96 lines
2.5 KiB
JavaScript
96 lines
2.5 KiB
JavaScript
import { MassObject } from './object.js';
|
|
import {
|
|
MASS_CREATION_RATE,
|
|
DISPLAY_OBJECTS_INFO,
|
|
MOTION_TIME_SCALE,
|
|
} from './config.js';
|
|
|
|
export class Objects {
|
|
objects = [];
|
|
creatingObject = undefined;
|
|
selectedObject = undefined;
|
|
|
|
constructor(sim) {
|
|
this.sim = sim;
|
|
}
|
|
|
|
// Create an object with mass that grows as pointer is held down
|
|
createObject(x, y) {
|
|
const idx = this.objects.length;
|
|
const obj = new MassObject(x, y, idx);
|
|
this.creatingObject = idx;
|
|
this.objects.push(obj);
|
|
}
|
|
|
|
doneCreatingObject() {
|
|
this.creatingObject = undefined;
|
|
}
|
|
|
|
object(i) {
|
|
return this.objects[i];
|
|
}
|
|
|
|
selectObject(i) {
|
|
this.selectedObject = i;
|
|
}
|
|
|
|
deselect() {
|
|
this.selectedObject = undefined;
|
|
}
|
|
|
|
getSelectedOrCreating() {
|
|
let i = this.creatingObject ?? this.selectedObject;
|
|
if (i !== undefined) {
|
|
return this.objects[i];
|
|
}
|
|
}
|
|
|
|
get length() {
|
|
return this.objects.length;
|
|
}
|
|
|
|
objectAtLocation(x, y) {
|
|
for (let i = 0; i < this.objects.length; i++) {
|
|
const obj = this.objects[i];
|
|
// If distance to object is less than object's radius, we are touching the object
|
|
const dist = Math.pow((obj.position.x - x)**2 + (obj.position.y - y)**2, 1/2);
|
|
if (dist <= obj.radius) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
|
|
computeFrame(elapsedTime) {
|
|
// If we're creating an object, increment its mass
|
|
// with the mass creation rate accelerating over time
|
|
if (this.creatingObject !== undefined) {
|
|
const obj = this.objects[this.creatingObject];
|
|
const rate = MASS_CREATION_RATE * obj.age;
|
|
obj.mass += rate * elapsedTime;
|
|
}
|
|
|
|
// Update positions. Simple Euler method for now.
|
|
for (let i = 0; i < this.objects.length; i++) {
|
|
const obj = this.objects[i];
|
|
obj.position.x += obj.velocity.x * MOTION_TIME_SCALE;
|
|
obj.position.y += obj.velocity.y * MOTION_TIME_SCALE;
|
|
}
|
|
|
|
// Display objects info
|
|
if (DISPLAY_OBJECTS_INFO) {
|
|
for (let i = 0; i < this.objects.length; i++) {
|
|
const obj = this.objects[i];
|
|
const speed = Math.pow(obj.velocity.x ** 2 + obj.velocity.y ** 2, 1/2);
|
|
// Invert y so that the angle is counterclockwise from x-axis
|
|
const direction = Math.atan2(-obj.velocity.y, obj.velocity.x) * 180 / Math.PI;
|
|
this.sim.info[`Object ${i}`] = [
|
|
`${obj.position.x}, `,
|
|
`${obj.position.y}, `,
|
|
`${obj.mass.toPrecision(6)} kg, `,
|
|
`${speed.toPrecision(2)} m/s, ${direction.toPrecision(2)}°`,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
}
|