com-example-ship.js

total 0
used 0
limit 0
/* title: Center of Mass. category: center files: ../point_src/core/head.js ../point_src/pointpen.js ../point_src/pointdraw.js ../point_src/math.js ../point_src/compass.js ../point_src/center.js ../point_src/pointlistpen.js ../point_src/pointlist.js ../point_src/point.js ../point_src/functions/clamp.js ../point_src/distances.js ../point_src/dragging.js ../point_src/events.js ../point_src/stage.js ../point_src/automouse.js ../point_src/extras.js ../point_src/setunset.js ../point_src/stroke.js --- */ class MainStage extends Stage { canvas = 'playspace' mounted(){ this.rawPointConf = { circle: { color: 'orange', width: 1}} this.generate() // update center indicator every 5 frames this.onTick(5, this.createMassPoints.bind(this)) } generate(pointCount=4){ /* Generate a list. In this random... */ this.randomPoints = PointList.generate.radius(pointCount, 100, point(200,200)) /* Customise the points, randomising the mass and rotation. */ this.randomPoints.forEach(p => { let mass = Math.random() * 10 // p.mass = mass p.rotation = Math.random() * 360 p.radius = Math.max(5, mass) }) // this.dragging.add(...this.randomPoints) this.dragging.addPoints(...this.randomPoints) this.velocity = point(0, 0); // Linear velocity (x, y) this.angularVelocity = 0; // Angular velocity (radians/sec) this.position = point(0, 0); // Center of mass position this.rotation = 0; // Orientation in radians this.createMassPoints() } createMassPoints(){ /* Call upon the list "center of mass" function */ this.comPoint = this.randomPoints.centerOfMass() /* In this case we cater for mass and rotation additions */ this.weightedComPoint = this.randomPoints.centerOfMass('deep') } draw(ctx){ this.clear(ctx) let dt = 1 / 60; // Or whatever your timestep is // Update center of mass position by velocity this.position.x += this.velocity.x * dt; this.position.y += this.velocity.y * dt; // Update rotation by angular velocity this.rotation += this.angularVelocity * dt; // For each engine: for (let p of this.randomPoints) { // Find engine's offset from center let dx = p.x - this.comPoint.x; let dy = p.y - this.comPoint.y; // Rotate offset by current orientation let cosA = Math.cos(this.rotation); let sinA = Math.sin(this.rotation); let px = this.position.x + dx * cosA - dy * sinA; let py = this.position.y + dx * sinA + dy * cosA; // Draw at (px, py) // e.g., ctx.circle(px, py, p.radius) } let totalMass = 0; let center = this.weightedComPoint // Moment of inertia (about center), for point masses: let I = 0; for (let p of this.randomPoints) { let dx = p.x - center.x; let dy = p.y - center.y; let mass = p.radius; // or p.mass if you store it totalMass += mass; I += mass * (dx * dx + dy * dy); } if (I === 0) I = 1; // hack to avoid NaN // 1. For each engine, calculate and apply force for (let p of this.randomPoints) { // Define your force here (e.g. thrust direction, magnitude) let force = {x:0, y:5} this.applyForceAtPoint(force, p, center, totalMass, I); } // 2. Update position & rotation this.position.x += this.velocity.x * dt; this.position.y += this.velocity.y * dt; this.rotation += this.angularVelocity * dt; // this.weightedComPoint.rotation = this.rotation // 3. Recompute center of mass, moment of inertia, etc if needed // 4. Draw points at their rotated/translated positions /* Use the pen to draw a simple circle at the Center of Mass.*/ this.comPoint.pen.circle(ctx, undefined, 'teal', 3) /* Draw an indicator at the _weighted_ Center of Mass. */ this.weightedComPoint.pen.indicator(ctx) /* Draw a circle at the origin points */ this.randomPoints.pen.indicators(ctx, this.rawPointConf) } applyForceAtPoint(force, point, center, totalMass, momentOfInertia) { // Linear acceleration this.velocity.x += force.x / totalMass; this.velocity.y += force.y / totalMass; // Torque (for angular acceleration) const rx = point.x - center.x; const ry = point.y - center.y; const torque = rx * force.y - ry * force.x; // 2D cross product const angularAcc = torque / momentOfInertia; this.angularVelocity += angularAcc; } } stage = MainStage.go()
Run
Meta Data
title Center of Mass.
imports ()
files ('../point_src/core/head.js', '../point_src/pointpen.js', '../point_src/pointdraw.js', '../point_src/math.js', '../point_src/compass.js', '../point_src/center.js', '../point_src/pointlistpen.js', '../point_src/pointlist.js', '../point_src/point.js', '../point_src/functions/clamp.js', '../point_src/distances.js', '../point_src/dragging.js', '../point_src/events.js', '../point_src/stage.js', '../point_src/automouse.js', '../point_src/extras.js', '../point_src/setunset.js', '../point_src/stroke.js')
unused_keys ()
unknown_keys ('category',)
category ['center']
filepath_exists True
path com-example-ship.js
filepath com-example-ship.js
clean_files ('../point_src/core/head.js', '../point_src/pointpen.js', '../point_src/pointdraw.js', '../point_src/math.js', '../point_src/compass.js', '../point_src/center.js', '../point_src/pointlistpen.js', '../point_src/pointlistdraw.js', '../point_src/pointlistgradient.js', '../point_src/pointlistshape.js', '../point_src/pointlistgenerator.js', '../point_src/unpack.js', '../point_src/pointlist.js', '../point_src/relative-xy.js', '../point_src/pointcast.js', '../point_src/point.js', '../point_src/functions/clamp.js', '../point_src/distances.js', '../point_src/protractor.js', '../point_src/text/beta.js', '../point_src/dragging.js', '../point_src/events.js', '../point_src/stage-resize.js', '../point_src/functions/resolve.js', '../point_src/stage.js', '../point_src/automouse.js', '../point_src/extras.js', '../point_src/setunset.js', '../point_src/stroke.js')
markdown {'html': '', 'content': 'title: Center of Mass.\ncategory: center\nfiles:\n ../point_src/core/head.js\n ../point_src/pointpen.js\n ../point_src/pointdraw.js\n ../point_src/math.js\n ../point_src/compass.js\n ../point_src/center.js\n ../point_src/pointlistpen.js\n ../point_src/pointlist.js\n ../point_src/point.js\n ../point_src/functions/clamp.js\n ../point_src/distances.js\n ../point_src/dragging.js\n ../point_src/events.js\n ../point_src/stage.js\n ../point_src/automouse.js\n ../point_src/extras.js\n ../point_src/setunset.js\n ../point_src/stroke.js\n---'}