/**
* @file Class Point
* @version March 12, 2017
*
* @author Olivier Pirson --- http://www.opimedia.be/
* @license GPLv3 --- Copyright (C) 2017 Olivier Pirson
*/
/**
* A point,
* represented by its cartesian coordinates.
*/
class Point {
/**
* Constructs a point of cartesian coordinates (x=a, y=b).
*
* @param {number} a
* @param {number} b
*/
constructor(a, b) {
assert(typeof a === "number", a);
assert(typeof b === "number", b);
this._x = a;
this._y = b;
}
/**
* Returns the horizontal coordinate of the cartesian coordinates.
*
* @returns {number}
*/
get x() {
if (this._x === null) {
this._x = this.r*Math.cos(this.phi);
}
return this._x;
}
/**
* Returns the vertical coordinate of the cartesian coordinates.
*
* @returns {number}
*/
get y() {
if (this._y === null) {
this._y = this.r*Math.sin(this.phi);
}
return this._y;
}
/**
* Returns a new point that is the sum.
*
* @param {Point} other
*
* @returns {Point}
*/
add(other) {
assert(other instanceof Point, other);
return new Point(this.x + other.x, this.y + other.y);
}
/**
* Compare two points before with x coordinate
* and maybe after with y coordinate.
*
* @param {Point} other
*
* @returns {number} -1, 0 or 1
*/
compare(other) {
assert(other instanceof Point, other);
const compX = compare(this.x, other.x);
return (compX !== 0
? compX
: compare(this.y, other.y));
}
/**
* Returns the distance between the two points.
*
* @param {Point} other
*
* @returns {number} >= 0
*/
distance(other) {
assert(other instanceof Point, other);
return Math.sqrt(this.distanceSqr(other));
}
/**
* Returns the square of the distance between the two points.
*
* @param {Point} other
*
* @returns {number} >= 0
*/
distanceSqr(other) {
assert(other instanceof Point, other);
const diffX = this._x - other._x;
const diffY = this._y - other._y;
return diffX*diffX + diffY*diffY;
}
/**
* Returns the distance to (0, 0).
*
* @returns {number} >= 0
*/
distanceTo0() {
return Math.sqrt(this.distanceTo0Sqr());
}
/**
* Returns the square of the distance to (0, 0).
*
* @returns {number} >= 0
*/
distanceTo0Sqr() {
return this._x*this._x + this._y*this._y;
}
/**
* Returns true iff the point is equals to the point other,
* namely iff they are same cartesian coordinates.
*
* @param {Point} other
*
* @returns {boolean}
*/
isEquals(other) {
assert(other instanceof Point, other);
return (this.x === other.x) && (this.y === other.y);
}
/**
* Returns a new point multiply by the scalar n.
*
* @returns {Point}
*/
mulScalar(n) {
assert(typeof n === "number", n);
return new Point(this.x*n, this.y*n);
}
/**
* Returns a new point that is the difference.
*
* @param {Point} other
*
* @returns {Point}
*/
sub(other) {
assert(other instanceof Point, other);
return new Point(this.x - other.x, this.y - other.y);
}
/**
* Returns a string cartesian representation of the point.
*
* Each number is represented with at most precision figures after the decimal point.
*
* @returns {String}
*/
toString(precision=2) {
assert(Number.isInteger(precision), precision);
assert(precision >= 0, precision);
function format(n) {
return (Number.isInteger(n)
? n.toString()
: n.toFixed(precision));
}
return "(" + format(this.x) + ", " + format(this.y) + ")";
}
}