top of page
Search
  • cedarcantab

Verlet Physics Rigid Body



class Dot extends Phaser.Geom.Point {

constructor(scene, x, y, vx, vy) {

super(x, y);

this.scene = scene;

this.pos = new Phaser.Math.Vector2(x, y);

this.oldpos = new Phaser.Math.Vector2(x + (vx||0), y + (vy||0)); // velocity x, y

this.friction = 0.97;

this.groundFriction = 0.7;

this.gravity = new Phaser.Math.Vector2(0, 1);

this.radius = 5;

this.color = '0xe62a4f';

this.mass = 1;

}

update() {

let vel = this.pos.clone().subtract(this.oldpos);

vel.scale(this.friction);

// if the point touches the ground set groundFriction

if (this.pos.y >= CANVAS_HEIGHT - this.radius && vel.lengthSq() > 0.000001) {

var m = vel.length();

vel.x /= m;

vel.y /= m;

vel.scale(m * this.groundFriction);

}

this.oldpos.set(this.pos.x, this.pos.y);

this.pos.add(vel);

this.pos.add(this.gravity);

}

constrain() {

if (this.pos.x > CANVAS_WIDTH - this.radius) {

this.pos.x = CANVAS_WIDTH - this.radius;

}

if (this.pos.x < this.radius) {

this.pos.x = this.radius;

}

if (this.pos.y > CANVAS_HEIGHT - this.radius) {

this.pos.y = CANVAS_HEIGHT - this.radius;

}

if (this.pos.y < this.radius) {

this.pos.y = this.radius;

}

};

render() {

this.graphics.fillStyle(this.color);

this.graphics.fillCircle(this.pos.x, this.pos.y, this.radius)

}

}





class Stick {

constructor(scene, p1, p2, length) {

this.scene = scene;

this.startPoint = p1;

this.endPoint = p2;

this.stiffness = 2;

this.color = '#f5476a';

// if the length is not given then calculate the distance based on position

if (!length) {

this.length = Phaser.Math.Distance.BetweenPoints(this.startPoint.pos, this.endPoint.pos);

} else {

this.length = length;

}

}

update() {

// calculate the distance between two dots

let dx = this.endPoint.pos.x - this.startPoint.pos.x;

let dy = this.endPoint.pos.y - this.startPoint.pos.y;

// pythagoras theorem

let dist = Math.sqrt(dx dx + dy dy);

// calculate the resting distance betwen the dots

let diff = (this.length - dist) / dist * this.stiffness;

// getting the offset of the points

let offsetx = dx diff 0.5;

let offsety = dy diff 0.5;

// calculate mass

let m1 = this.startPoint.mass + this.endPoint.mass;

let m2 = this.startPoint.mass / m1;

m1 = this.endPoint.mass / m1;

// and finally apply the offset with calculated mass

if (!this.startPoint.pinned) {

this.startPoint.pos.x -= offsetx * m1;

this.startPoint.pos.y -= offsety * m1;

}

if (!this.endPoint.pinned) {

this.endPoint.pos.x += offsetx * m2;

this.endPoint.pos.y += offsety * m2;

}

}

render() {

this.graphics.lineStyle(1,this.color).lineBetween(this.startPoint.pos.x, this.startPoint.pos.y, this.endPoint.pos.x, this.endPoint.pos.y);

}

}





class Game extends Phaser.Scene {

constructor() {

super({key: "Game"});

this.dots = [];

this.sticks = [];

this.ITERATION = 100;

}

create() {

// forming a BOX

this.dots.push(new Dot(this, 100, 100, (Math.random() - 0.5) * 100.0)); // x, y, vx, vy

this.dots.push(new Dot(this, 200, 100));

this.dots.push(new Dot(this, 200, 200));

this.dots.push(new Dot(this, 100, 200));

// sticks

this.sticks.push(new Stick(this, this.dots[0], this.dots[1]))

this.sticks.push(new Stick(this, this.dots[1], this.dots[2]))

this.sticks.push(new Stick(this, this.dots[2], this.dots[3]))

this.sticks.push(new Stick(this, this.dots[3], this.dots[0]))

this.sticks.push(new Stick(this, this.dots[3], this.dots[1]))

}

update(t, dt) {

this.graphics.clear()

// update

for (let i = 0; i < this.ITERATION; i++) {

for (let d of this.dots) {

d.constrain();

}

for (let s of this.sticks) {

s.update();

}

}

for (let d of this.dots) {

d.update();

d.render();

}

for (let s of this.sticks) {

s.update();

s.render();

}

}

}



Useful References






4 views0 comments

Recent Posts

See All

p2 naive broadphase

var Broadphase = require('../collision/Broadphase'); module.exports = NaiveBroadphase; /** * Naive broadphase implementation. Does N^2 tests. * * @class NaiveBroadphase * @constructor * @extend

Extending Box2D-Lite in Javascript: Revolute Joint

/// Revolute joint definition. This requires defining an anchor point where the /// bodies are joined. The definition uses local anchor points so that the /// initial configuration can violate the con

sopiro motor constranit

import { Matrix2, Vector2 } from "./math.js"; import { RigidBody } from "./rigidbody.js"; import { Settings } from "./settings.js"; import * as Util from "./util.js"; import { Joint } from "./joint.js

記事: Blog2_Post
bottom of page