<script> var Vector2d = function(x,y){ this.vec = { vx: x, vy: y, lengthSq: x * x + y * y }; return this; } //Translate Vector2d.prototype.add = function(vec2){ this.vec.vx += vec2.vec.vx; this.vec.vy += vec2.vec.vy; this.vec.lengthSq = this.vec.vx * this.vec.vx + this.vec.vy * this.vec.vy; return this; }; Vector2d.prototype.sub = function(vec2){ this.vec.vx -= vec2.vec.vx; this.vec.vy -= vec2.vec.vy; this.vec.lengthSq = this.vec.vx * this.vec.vx + this.vec.vy * this.vec.vy; return this; }; //Rotate Vector2d.prototype.rotate = function(angle){ var vx = this.vec.vx, vy = this.vec.vy, cosVal = Math.cos(angle), sinVal = Math.sin(angle); this.vec.vx = vx * cosVal - vy * sinVal; this.vec.vy = vx * sinVal + vy * cosVal; return this; }; //Scale Vector2d.prototype.scale = function(scale){ this.vec.vx *= scale; this.vec.vy *= scale; this.vec.lengthSq = this.vec.vx * this.vec.vx + this.vec.vy * this.vec.vy; return this; }; Vector2d.prototype.negate = function(){ this.vec.vx = -this.vec.vx; this.vec.vy = -this.vec.vy; return this; }; //Utility Vector2d.prototype.normalize = function(){ if(this.vec.lengthSq){ this.vec.vx /= this.vec.lengthSq; this.vec.vy /= this.vec.lengthSq; } this.vec.lengthSq = 1; return this; }; Vector2d.prototype.lengthSq = function(){ this.vec.lengthSq = this.vec.vx * this.vec.vx + this.vec.vy * this.vec.vy; return this; }; //Output Vector2d.prototype.print = function(){ console.log(`(x: ${this.vec.vx.toFixed(3)}, y: ${this.vec.vy.toFixed(3)}, lengthSq: ${this.vec.lengthSq})`); return this; }; var vec1 = new Vector2d(1,2); var vec2 = new Vector2d(3,4); vec1.add(vec2).negate().normalize().print(); </script>