From 29efe05010d0497db501e4daf97a99e21c278073 Mon Sep 17 00:00:00 2001 From: Antonio De Lucreziis Date: Fri, 10 Mar 2023 17:07:36 +0100 Subject: [PATCH] polished simulation code --- frontend/lib/math/math.js | 48 +++++++++++++++++++++++++++ frontend/src/components/KnotLayer.jsx | 12 +++---- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/frontend/lib/math/math.js b/frontend/lib/math/math.js index 9565469..e85d32f 100644 --- a/frontend/lib/math/math.js +++ b/frontend/lib/math/math.js @@ -51,6 +51,54 @@ export const Vec2 = { return [x / norm, y / norm] }, } +export const Vec3 = { + Mutate: { + add(target, [x, y, z]) { + target[0] += x + target[1] += y + target[2] += z + + return target + }, + scale(target, factor) { + target[0] *= factor + target[1] *= factor + target[2] *= factor + + return target + }, + normalize(target) { + const norm = Vec3.norm2(target) + target[0] /= norm + target[1] /= norm + target[2] /= norm + + return target + }, + }, + distance2(v1, v2) { + return Vec3.norm2(Vec3.sub(v1, v2)) + }, + add([x1, y1, z1], [x2, y2, z2]) { + return [x1 + x2, y1 + y2, z1 + z2] + }, + sub([x1, y1, z1], [x2, y2, z2]) { + return [x1 - x2, y1 - y2, z1 - z2] + }, + dot([x1, y1, z1], [x2, y2, z2]) { + return x1 * x2 + y1 * y2 + z1 * z2 + }, + scale([x, y, z], factor) { + return [x * factor, y * factor, z * factor] + }, + norm2([x, y, z]) { + return Math.sqrt(x ** 2 + y ** 2 + z ** 2) + }, + normalize([x, y, z]) { + const norm = Vec3.norm2([x, y, z]) + return [x / norm, y / norm, z / norm] + }, +} export function clamp(min, value, max) { return Math.min(max, Math.max(min, value)) diff --git a/frontend/src/components/KnotLayer.jsx b/frontend/src/components/KnotLayer.jsx index 79cf1be..e80fc67 100644 --- a/frontend/src/components/KnotLayer.jsx +++ b/frontend/src/components/KnotLayer.jsx @@ -1,8 +1,8 @@ import { useEffect, useRef, useState } from 'preact/hooks' import { resampleCurve, simplifyCurve } from '../../lib/math/curves.js' -import { clamp, Vec2 } from '../../lib/math/math.js' +import { Vec2 } from '../../lib/math/math.js' -function createSimulation(positions, velocities, accelerations) { +function createSimulation2d(positions, velocities, accelerations) { return { positions, velocities, @@ -14,10 +14,8 @@ function createSimulation(positions, velocities, accelerations) { const newVelocities = Array.from({ length: n }, () => []) for (let i = 0; i < n; i++) { - newPositions[i][0] = this.positions[i][0] + this.velocities[i][0] + this.accelerations[i][0] * 0.5 - newPositions[i][1] = this.positions[i][1] + this.velocities[i][1] + this.accelerations[i][1] * 0.5 - newVelocities[i][0] = this.velocities[i][0] + (this.accelerations[i][0] + newAccelerations[i][0]) * 0.5 - newVelocities[i][1] = this.velocities[i][1] + (this.accelerations[i][1] + newAccelerations[i][1]) * 0.5 + newPositions[i] = Vec2.add(Vec2.add(this.positions[i], this.velocities[i]), Vec2.scale(this.accelerations[i], 0.5)) + newVelocities[i] = Vec2.add(this.velocities[i], Vec2.scale(Vec2.add(this.accelerations[i], newAccelerations[i]), 0.5)) } this.positions = newPositions @@ -76,7 +74,7 @@ class KnotSimulation { } setPositions(positions) { - this.particleSimulation = createSimulation( + this.particleSimulation = createSimulation2d( positions, Array.from({ length: positions.length }, () => [0, 0]), Array.from({ length: positions.length }, () => [0, 0])