# Point

#####

declaration
Point

The point implementation of MathLib makes calculations with point in
arbitrary dimensions possible.

MathLib uses the homogeneous form of a point for calculations and storage.

To create the point (4, 2) on the two dimensional plane use
`new MathLib.Point([4, 2, 1])`
Alternatively you can use
`new MathLib.Point(4, 2)`
The 1 will be added for you.

    var Point = (function (_super) {
    		__extends(Point, _super);
    		function Point (coords) {
    			_super.call(this, arguments.length > 1 ? Array.prototype.slice.call(arguments).concat(1) : coords);
    			this.type = 'point';

    			this.dimension = 2;
    		}

# crossRatio

#####

method
Point.prototype.crossRatio() → number

Option name | Type | Description
--- | --- | ---
a | Point | The point A
b | Point | The point B
c | Point | The point C
d | Point | The point D

Calculates the distance crossratio (A,B,C,D) of four points
as seen from the current point.

    Point.prototype.crossRatio = function (a, b, c, d) {
    			var xa = this.vectorProduct(a), xb = this.vectorProduct(b);

    			return xa.scalarProduct(c) * xb.scalarProduct(d) / (xa.scalarProduct(d) * xb.scalarProduct(c));
    		};

# distanceTo

#####

method
Point.prototype.distanceTo() → number

Option name | Type | Description
--- | --- | ---
p | Point | The point to calculate the distance to

Calculates the distance to an other point.
If no other point is provided, it calculates the distance to the origin.

    Point.prototype.distanceTo = function (p

geom = MathLib.Geometry.active

    ) {
    			if (arguments.length === 0) {
    				return MathLib.hypot.apply(null, this.slice(0, -1)) / Math.abs(this[this.dimension]);
    			}

    			if (p.type === 'point' && this.dimension === p.dimension) {
    				return MathLib.hypot.apply(null, this.normalize().minus(p.normalize()).slice(0, -1));
    			}
    			//	if (p.type === 'point' && this.dimension === p.dimension) {
    			//		var Otp = this.times(geom.fundamentalConic.primal).times(p),
    			//				Ott = this.times(geom.fundamentalConic.primal).times(this),
    			//				Opp = p.times(geom.fundamentalConic.primal).times(p),
    			//				Dtp = Math.sqrt(Otp * Otp - Ott * Opp);
    			//
    			//		return MathLib.Geometry.active.cDist * Math.log((Otp + Dtp) / (Otp - Dtp));
    			//	}
    		};

# draw

#####

method
Point.prototype.draw() → Point

Option name | Type | Description
--- | --- | ---
screen | Screen | The screen to draw onto
options | object | Drawing options

Draws the point on a canvas or svg element.

    Point.prototype.draw = function (screen, options) {
    			if (Array.isArray(screen)) {
    				var point = this;
    				screen.forEach(function (x) {
    					x.point(point, options);
    				});
    			}
    			else {
    				screen.point(this, options);
    			}

    			return this;
    		};

# isEqual

#####

method
Point.prototype.isEqual() → boolean

Option name | Type | Description
--- | --- | ---
q | Point | The point to compare

Determines if the point has the same coordinates as an other point

    Point.prototype.isEqual = function (q) {
    			var p = this.normalize();
    			q = q.normalize();

    			if (this.length !== q.length) {
    				return false;
    			}

    			return p.every(function (x, i) {
    				return MathLib.isEqual(x, q[i]);
    			});
    		};

# isFinite

#####

method
Point.prototype.isFinite() → boolean

Determines if the point is finite

    Point.prototype.isFinite = function () {
    			return !MathLib.isZero(this[this.length - 1]);
    		};

# join

#####

method
Point.prototype.join() → Line

Option name | Type | Description
--- | --- | ---
q | Point | The point to calculate the line to

Calculates a line connecting two points

    Point.prototype.join = function (q) {
    			var line, p = this;

    			if (this.dimension === 2 && q.dimension === 2) {
    				line = new MathLib.Line(this.vectorProduct(q).toArray());

    				Object.defineProperties(line, {
    					'0': {
    						get: function () {
    							return p[1] * q[2] - p[2] * q[1];
    						},
    						set: function () {
    							MathLib.warning({message: 'Trying to change the coordinates of a completely dependent line.', method: 'Point#join'});
    						},
    						enumerable: true
    					},
    					'1': {
    						get: function () {
    							return p[2] * q[0] - p[0] * q[2];
    						},
    						set: function () {
    							MathLib.warning({message: 'Trying to change the coordinates of a completely dependent line.', method: 'Point#join'});
    						},
    						enumerable: true
    					},
    					'2': {
    						get: function () {
    							return p[0] * q[1] - p[1] * q[0];
    						},
    						set: function () {
    							MathLib.warning({message: 'Trying to change the coordinates of a completely dependent line.', method: 'Point#join'});
    						},
    						enumerable: true
    					}
    				});

    				return line;
    			}
    		};

# normalize

#####

method
Point.prototype.normalize() → Point

Normalizes the point.

    Point.prototype.normalize = function () {
    			var last = this[this.dimension] || 1;
    			return this.map(function (x) {
    				return x / last;
    			});
    		};

# reflectAt

#####

method
Point.prototype.reflectAt() → Point

Option name | Type | Description
--- | --- | ---
q | Point | The point to reflect the current point at.

Reflects the point at an other point

    Point.prototype.reflectAt = function (q) {
    			var i, ii, reflectedPoint = [], p = this.normalize();

    			if (q.type === 'point') {
    				if (this.dimension === q.dimension) {
    					q = q.normalize();
    					for (i = 0, ii = this.dimension; i < ii; i++) {
    						reflectedPoint.push(2 * q[i] - p[i]);
    					}
    					reflectedPoint.push(1);
    					return new MathLib.Point(reflectedPoint);
    				}
    			}
    		};

# restrictTo

#####

method
Point.prototype.restrictTo()

Option name | Type | Description
--- | --- | ---
l | Line | The line to restrict the point to.

Restricts the point to a line.

    Point.prototype.restrictTo = function (l) {
    			var p = this.slice();

    			Object.defineProperties(this, {
    				'0': {
    					get: function () {
    						return l[1] * l[1] * p[0] - l[0] * (l[1] * p[1] + l[2] * p[2]);
    					},
    					set: function (point) {
    						p[0] = point;
    					},
    					enumerable: true,
    					configurable: true
    				},
    				'1': {
    					get: function () {
    						return -l[1] * l[2] * p[2] + l[0] * (l[0] * p[1] - l[1] * p[0]);
    					},
    					set: function (point) {
    						p[1] = point;
    					},
    					enumerable: true,
    					configurable: true
    				},
    				'2': {
    					get: function () {
    						return l[1] * l[1] * p[2] + l[0] * l[0] * p[2];
    					},
    					set: function (point) {
    						p[2] = point;
    					},
    					enumerable: true,
    					configurable: true
    				}
    			});
    		};

# toComplex

#####

method
Point.prototype.toComplex() → Complex

Converts a two dimensional point to the corresponding complex number.

    Point.prototype.toComplex = function () {
    			if (this.dimension === 2) {
    				if (MathLib.isZero(this[2])) {
    					return new MathLib.Complex(Infinity);
    				}
    				return new MathLib.Complex(this[0] / this[2], this[1] / this[2]);
    			}
    		};

TODO: implement
Returns content MathML representation of the point

    // toContentMathML(opt) {
    		// }

# toLaTeX

#####

method
Point.prototype.toLaTeX() → string

Option name | Type | Description
--- | --- | ---
opt | boolean | Optional parameter to indicate if the output should be projective.

Returns LaTeX representation of the point

    Point.prototype.toLaTeX = function (opt) {
    			if (typeof opt === 'undefined') { opt = false; }
    			var p = opt ? this.toArray() : this.normalize().slice(0, -1);

    			return '\\begin{pmatrix}' + p.reduce(function (old, cur) {
    				return old + '\\\\' + MathLib.toLaTeX(cur);
    			}) + '\\end{pmatrix}';
    		};

# toMathML

#####

method
Point.prototype.toMathML() → string

Option name | Type | Description
--- | --- | ---
opt | boolean | Optional parameter to indicate if the output should be projective.

Returns (presentation) MathML representation of the point

    Point.prototype.toMathML = function (opt) {
    			if (typeof opt === 'undefined') { opt = false; }
    			var p = opt ? this.toArray() : this.normalize().slice(0, -1);

    			return p.reduce(function (old, cur) {
    				return old + '<mtr><mtd>' + MathLib.toMathML(cur) + '</mtd></mtr>';
    			}, '<mrow><mo>(</mo><mtable>') + '</mtable><mo>)</mo></mrow>';
    		};

# toString

#####

method
Point.prototype.toString() → string

Option name | Type | Description
--- | --- | ---
opt | boolean | Optional parameter to indicate if the output should be projective.

Returns string representation of the point

    Point.prototype.toString = function (opt) {
    			if (typeof opt === 'undefined') { opt = false; }
    			var p = opt ? this.toArray() : this.normalize().slice(0, -1);

    			return '(' + p.reduce(function (old, cur) {
    				return old + ', ' + MathLib.toString(cur);
    			}) + ')';
    		};
    		Point.I = new Point([new MathLib.Complex(0, -1), 0, 1]);

    		Point.J = new Point([new MathLib.Complex(0, 1), 0, 1]);
    		return Point;
    	})(MathLib.Vector);
    	MathLib.Point = Point;
    })(MathLib || (MathLib = {}));