# 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 = {}));