top of page
Search
cedarcantab

verly point / stick


point

class Point {
  /**
   * 
   * @param {number} x 
   * @param {number} y 
   * @param {number=} vx 
   * @param {number=} vy 
   * @param {number=} radius 
   */
  constructor(x, y, vx, vy, radius) {
    this.pos = new Vector(x, y);
    this.oldpos = new Vector(x + (vx || 0), y + (vy || 0));
    this.bounce = 0.99;
    this.friction = 0.97;
    this.groundFriction = 0.7;
    this.gravity = new Vector(0, 1);
    this.pinned = false;
    this.radius = radius || 5;
    this.color = '#e62a4f';
    this.mass = 1;
    this.sticks = [];
    // this.behaviors = [];
    this.forceAcc = 1;
    this.uid = ''
  }

  /**
   * 
   * @param {Vector} g 
   */
  setGravity(g) {
    this.gravity = g;
    return this;
  }
  /**
   * 
   * @param {number} f 
   */
  setFriction(f) {
    this.friction = f;
    return this;
  }
  /**
   * 
   * @param {number} f 
   */
  setGroundFriction(f) {
    this.groundFriction = f;
    return this;
  }
  /**
   * 
   * @param {number} b
   */
  setBounce(b) {
    this.bounce = b;
    return this;
  }
  /**
   * 
   * @param {number} f 
   * @returns {Point}
   */
  setForceAcc(f) {
    this.forceAcc = f;
    return this;
  }
  /**
   * 
   * @param {number} m 
   * @returns {Point}
   */
  setMass(m) {
    this.mass = m;
    return this;
  }
  /**
   * 
   * @param {number} radius 
   * @returns {Point}
   */
  setRadius(radius) {
    this.radius = radius;
    return this;
  }

  /**
   * @param {string} color 
   * @returns {Point}
   */
  setColor(color) {
    this.color = color;
    return this;
  }

  /**
   * @param {Vector} vel 
   * @returns {Point}
   */
  setVelocity(vel) {
    this.oldpos.setXY(vel.x, vel.y);
    return this;
  }

  /**
   * @returns {Point}
   */
  pin() {
    this.pinned = true;
    return this;
  }
  /**
   * @returns {Point}
   */
  unpin() {
    this.pinned = false;
    return this;
  }

  resetVelocity() {
    this.oldpos.setXY(this.pos.x, this.pos.y);
  }

  /**
   * 
   * @param {number} angle 
   * @param {number} offset 
   */
  rotate(angle, offset) {
    let x = offset.x + (this.pos.x - offset.x) * Math.cos(angle) - (this.pos.y - offset.y) * Math.sin(angle);
    let y = offset.y + (this.pos.x - offset.x) * Math.sin(angle) + (this.pos.y - offset.y) * Math.cos(angle);
    this.pos.setXY(x, y);
  }

  /**
   * 
   * @param {Point} p 
   * @param {number} radius 
   * @param {number} strength 
   */
  resolveBehaviors(p, radius = this.radius, strength = this.forceAcc) {
    var delta = Vector.sub(this.pos, p.pos);
    var dist = delta.magSq();

    let magR = radius * radius;
    if (dist < magR) {
      var f = delta.normalizeTo(1 - (dist / magR)).mult(strength);
      this.applyForce(f);
    }
  }

  /**
   * 
   * @param {number|Vector} f 
   */
  applyForce(f) {
    this.pos.add(f);
  }

  /**
   * 
   * @param {number} x 
   * @param {number} y 
   * @param {number} time 
   * @param {number} radius 
   * @param {number} speed 
   */
  addMotor(x, y, time, radius, speed) {
    this.pos.x = x + radius * Math.cos(time * speed);
    this.pos.y = y + radius * Math.sin(time * speed);
  }

  /**
   * @param {Verly} verlyInstance 
   */
  constrain(verlyInstance) {
    // if (this.pos.y > HEIGHT - 1) {
    //   this.pos.y = HEIGHT - 1;
    // }
    // if (this.pos.x < 0) {
    //   this.pos.x = 0;
    // }
    // if (this.pos.x > WIDTH - 1) {
    //   this.pos.x = WIDTH - 1;
    // }
    // let vel = Vector.sub(this.pos, this.oldpos);
    if (this.pos.x > verlyInstance.WIDTH - this.radius) {
      this.pos.x = verlyInstance.WIDTH - this.radius;
      // this.oldpos.x = (this.pos.x + vel.x) * this.bounce;
    }
    if (this.pos.x < this.radius) {
      this.pos.x = this.radius;
      // this.oldpos.x = (this.pos.x + vel.x) * this.bounce;
    }
    if (this.pos.y > verlyInstance.HEIGHT - this.radius) {
      this.pos.y = verlyInstance.HEIGHT - this.radius;
      // this.oldpos.y = (this.pos.y + vel.y) * this.bounce;
    }
    if (this.pos.y < this.radius) {
      this.pos.y = this.radius;
      // this.oldpos.y = (this.pos.y + vel.y) * this.bounce;
    }
  };


  /**
   * @param {Verly} verlyInstance 
   */
  update(verlyInstance) {
    if (this.pinned) return;
    let vel = Vector.sub(this.pos, this.oldpos);
    vel.mult(this.friction);
    // if the point touches the ground set groundFriction
    if (this.pos.y >= verlyInstance.HEIGHT - this.radius && vel.magSq() > 0.000001) {
      var m = vel.mag();
      vel.x /= m;
      vel.y /= m;
      vel.mult(m * this.groundFriction);
    }
    this.oldpos.setXY(this.pos.x, this.pos.y);
    this.pos.add(vel);
    this.pos.add(this.gravity);
  }

  /**
   * @param {CanvasRenderingContext2D} ctx 
   */
  render(ctx) {
    ctx.beginPath();
    ctx.fillStyle = this.color;
    ctx.arc(this.pos.x, this.pos.y, this.radius, 0, Math.PI * 2);
    ctx.fill();
    ctx.closePath();
  }
}


export default Point;

stick


class Stick {
  /**
   * creates a stick between two Point
   * takes optional length and stiffness 
   * @param {Point} p1 
   * @param {Point} p2 
   * @param {number=} length 
   * @param {number=} stiffness 
   * @param {boolean=} hidden 
   */
  constructor(p1, p2, length, stiffness, hidden) {
    this.startPoint = p1;
    this.endPoint = p2;
    this.stiffness = stiffness || 2;
    this.color = '#f5476a';
    this.hidden = hidden;
    if (!length) {
      this.length = this.startPoint.pos.dist(this.endPoint.pos);
    } else {
      this.length = length;
    }
    this.startPoint.sticks.push(this);
    this.endPoint.sticks.push(this);
  }

  /**
   * 
   * @param {number=} stepCoef 
   */
  update(stepCoef) {
    // not gonna use vectors for performance optimization
    // let dx = this.endPoint.pos.x - this.startPoint.pos.x;
    // let dy = this.endPoint.pos.y - this.startPoint.pos.y;
    // let dist = Math.sqrt(dx * dx + dy * dy);
    // let diff = this.length - dist;
    // let percent = diff / dist / 2;
    // let offsetx = (dx * percent);
    // let offsety = (dy * percent);
    // if (!this.startPoint.pinned) {
    //   this.startPoint.pos.x -= offsetx;
    //   this.startPoint.pos.y -= offsety;
    // }
    // if (!this.endPoint.pinned) {
    //   this.endPoint.pos.x += offsetx;
    //   this.endPoint.pos.y += offsety;
    // }
    // ----- algo two

    // algo three
    let dx = this.endPoint.pos.x - this.startPoint.pos.x;
    let dy = this.endPoint.pos.y - this.startPoint.pos.y;
    let dist = Math.sqrt(dx * dx + dy * dy);
    let diff = (this.length - dist) / dist * this.stiffness;

    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;

    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;
    }

    
    // calculate mass
    // var m1 = this.startPoint.mass + this.endPoint.mass;
    // var m2 = this.startPoint.mass / m1;
    // m1 = this.endPoint.mass / m1;
    
    // var normal = Vector.sub(this.startPoint.pos, this.endPoint.pos);
    // var m = normal.magSq();
    // let diff = ((this.length * this.length) - m);
    // normal.mult((diff / m) * this.stiffness * stepCoef);
    
    // if (!this.startPoint.pinned) {
    //   this.startPoint.pos.add(normal);
    // }
    // if (!this.endPoint.pinned) {
    //   this.endPoint.pos.sub(normal);
    // }
  }

  /**
   * @param {string} color
   * @returns {Stick}
   */
  setColor(color) {
    this.color = color;
    return this;
  }

  /**
   * @param {number} length
   * @returns {Stick}
   */
  setLength(length) {
    this.length = length;
    return this;
  }

  /**
   * @param {number} value
   * @returns {Stick}
   */
  setStiffness(value) {
    this.stiffness = value;
    return this;
  }

  /**
   * @param {boolean} value
   * @returns {Stick}
   */
  setHidden(value) {
    this.hidden = value;
    return this;
  }

  /**
   * 
   * @param {CanvasRenderingContext2D} ctx 
   */
  render(ctx) {
    if (this.hidden) return;
    ctx.beginPath();
    ctx.strokeStyle = this.color;
    ctx.moveTo(this.startPoint.pos.x, this.startPoint.pos.y);
    ctx.lineTo(this.endPoint.pos.x, this.endPoint.pos.y);
    ctx.stroke();
    ctx.closePath();
  }
}

export default Stick;

0 views0 comments

Recent Posts

See All

p2 naive broadphase

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

sopiro motor constranit

import { Matrix2, Vector2 } from "./math.js"; import { RigidBody } from "./rigidbody.js"; import { Settings } from "./settings.js";...

Comentarios


記事: Blog2_Post
bottom of page