Skip to content

Commit

Permalink
refactor spring as entity
Browse files Browse the repository at this point in the history
  • Loading branch information
gastonmorixe committed Oct 23, 2024
1 parent acf25b1 commit fff6e9a
Show file tree
Hide file tree
Showing 10 changed files with 1,123 additions and 754 deletions.
4 changes: 3 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
<title>Motion</title>
</head>
<body>
<div id="box"></div>
<div id="box1" class="box">1</div>
<div id="box2" class="box">2</div>
<div id="box3" class="box">3</div>
<canvas id="chart"></canvas>
<script type="module" src="/src/main.ts"></script>
</body>
Expand Down
202 changes: 202 additions & 0 deletions src/chart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import { Entity, System } from "./ecs";
import { AccumulatedForceComponent } from "./components";

import Chart, { ChartConfiguration, ChartItem } from "chart.js/auto";

export class ChartSystem extends System {
private chart: Chart;
private data: {
time: number;
// positionX: number;
// positionY: number;
// velocityX: number;
// velocityY: number;
// forceX: number;
// forceY: number;
accumulatedForceX: number;
accumulatedForceY: number;
}[] = [];
private time: number = 0;
private lastUpdateTime: number = 0;
private updateInterval: number = 20; // Update every X ms
private windowSize: number = 200; // Rolling window of X data points
private samplingRate: number = 2;

constructor(chartContext: ChartItem) {
super();
const chartConfig: ChartConfiguration<"line"> = {
type: "line",
data: {
datasets: [
// {
// // showLine: false,
// label: "Position X",
// borderColor: "red",
// borderWidth: 1,
// data: [],
// pointStyle: "circle",
// pointRadius: 3,
// pointBorderWidth: 0,
// },
// {
// // showLine: false,
// label: "Position Y",
// borderColor: "blue",
// borderWidth: 1,
// data: [],
// pointStyle: "circle",
// pointRadius: 3,
// pointBorderWidth: 0,
// },
// {
// // showLine: false,
// label: "Velocity X",
// borderColor: "red",
// borderWidth: 1,
// data: [],
// pointStyle: "circle",
// pointRadius: 3,
// pointBorderWidth: 0,
// },
// {
// // showLine: false,
// label: "Velocity Y",
// borderColor: "blue",
// borderWidth: 1,
// data: [],
// pointStyle: "circle",
// pointRadius: 3,
// pointBorderWidth: 0,
// },
// {
// // showLine: false,
// label: "Force X",
// borderColor: "orange",
// borderWidth: 1,
// data: [],
// pointStyle: "circle",
// pointRadius: 2,
// pointBorderWidth: 0,
// },
// {
// // showLine: false,
// label: "Force Y",
// borderColor: "brown",
// borderWidth: 1,
// data: [],
// pointStyle: "circle",
// pointRadius: 2,
// pointBorderWidth: 0,
// },
{
// showLine: false,
label: "Accumulated Force X",
borderColor: "red",
borderWidth: 1,
data: [],
pointStyle: "circle",
pointRadius: 2,
pointBorderWidth: 0,
},
{
// showLine: false,
label: "Accumulated Force Y",
borderColor: "blue",
borderWidth: 1,
data: [],
pointStyle: "circle",
pointRadius: 2,
pointBorderWidth: 0,
},
],
},
options: {
animation: false,
responsive: true,
// stacked: false,
interaction: { intersect: false },
scales: {
x: { type: "linear", title: { display: true, text: "Time" } },
y: { title: { display: true, text: "Value" } },
},
},
};
this.chart = new Chart(chartContext, chartConfig);
}

update(entities: Entity[]): void {
const currentTime = performance.now();

// Collect data at every update call
if (this.time % this.samplingRate === 0) {
entities
.filter((e) => e.name === "box1")
.forEach((entity) => {
// const position = entity.getComponent(PositionComponent);
// const velocity = entity.getComponent(VelocityComponent);
// const force = entity.getComponent(ForceComponent);
const accumulatedForce = entity.getComponent(
AccumulatedForceComponent,
);

// if (position && velocity && force) {
if (accumulatedForce) {
this.data.push({
time: this.time,
// positionX: position.x,
// positionY: position.y,
// velocityX: velocity.vx,
// velocityY: velocity.vy,
// forceX: force.fx,
// forceY: force.fy,
accumulatedForceX: accumulatedForce.accumulatedFx,
accumulatedForceY: accumulatedForce.accumulatedFy,
});
}
});
}

// Only update the chart every updateInterval (e.g., 1000ms)
if (currentTime - this.lastUpdateTime >= this.updateInterval) {
this.data.forEach((entry) => {
// this.chart.data.datasets[0].data.push({
// x: entry.time,
// y: entry.positionX,
// });
// this.chart.data.datasets[1].data.push({
// x: entry.time,
// y: entry.positionY,
// });
// this.chart.data.datasets[0].data.push({
// x: entry.time,
// y: entry.velocityX,
// });
// this.chart.data.datasets[1].data.push({
// x: entry.time,
// y: entry.velocityY,
// });
this.chart.data.datasets[0].data.push({
x: entry.time,
y: entry.accumulatedForceX,
});
this.chart.data.datasets[1].data.push({
x: entry.time,
y: entry.accumulatedForceY,
});
});

// Enforce rolling window by slicing the dataset to ensure it doesn't grow beyond windowSize
this.chart.data.datasets.forEach((dataset) => {
if (dataset.data.length > this.windowSize) {
dataset.data = dataset.data.slice(-this.windowSize);
}
});

this.chart.update();
this.data = []; // Clear the collected data after batching it to the chart
this.lastUpdateTime = currentTime; // Update the last update time
}

this.time++;
}
}
71 changes: 71 additions & 0 deletions src/components.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Component } from "./ecs";

export class PositionComponent extends Component {
x: number;
y: number;

constructor(x: number, y: number) {
super();
this.x = x;
this.y = y;
}
}

export class VelocityComponent extends Component {
vx: number;
vy: number;

constructor(vx: number = 0, vy: number = 0) {
super();
this.vx = vx;
this.vy = vy;
}
}

export class MassComponent extends Component {
mass: number;

constructor(mass: number) {
super();
this.mass = mass;
}
}

export class ForceComponent extends Component {
fx: number = 0;
fy: number = 0;
}

export class AccumulatedForceComponent extends Component {
accumulatedFx: number = 0;
accumulatedFy: number = 0;
}

export class FrictionComponent extends Component {
frictionCoefficient: number;

constructor(frictionCoefficient: number = 0.05) {
super();
this.frictionCoefficient = frictionCoefficient;
}
}

// export class SpringForceComponent extends Component {
// entityA: Entity;
// entityB: Entity;
// stiffness: number;
// damping: number;
//
// constructor(
// entityA: Entity,
// entityB: Entity,
// stiffness: number = 0.1,
// damping: number = 0.05,
// ) {
// super();
// this.entityA = entityA;
// this.entityB = entityB;
// this.stiffness = stiffness;
// this.damping = damping;
// }
// }
Loading

0 comments on commit fff6e9a

Please sign in to comment.