/**
 * Represents a 2D Line between two points.
 */
export class Line2D {
    p1;
    p2;
    /**
     * Line constructor
     * @param pt1 Start of line.
     * @param pt2 End of line.
     */
    constructor(p1, p2) {
        this.p1 = p1;
        this.p2 = p2;
    }
    /**
     * Checks if `this` intersects `line`.
     * @param line Line.
     * @returns `true` if there is an intersection, `false` otherwise.
     */
    intersects(line) {
        return Line2D.intersects(this, line);
    }
    //https://stackoverflow.com/a/38977789
    /**
     * Checks if two lines intersects.
     * @param line1 First line
     * @param line2 Second line
     * @param dst If an intersection is found this will contain the point where the two lines intersect,
     * otherwise it will contain the nearest point between the two lines.
     * @returns `true` if there is a intersection, `false` otherwise.
     */
    static intersects(line1, line2, dst) {
        const denom = (line2.p2.y - line2.p1.y) * (line1.p2.x - line1.p1.x) -
            (line2.p2.x - line2.p1.x) * (line1.p2.y - line1.p1.y);
        const ua = ((line2.p2.x - line2.p1.x) * (line1.p1.y - line2.p1.y) -
            (line2.p2.y - line2.p1.y) * (line1.p1.x - line2.p1.x)) /
            denom;
        const ub = ((line1.p2.x - line1.p1.x) * (line1.p1.y - line2.p1.y) -
            (line1.p2.y - line1.p1.y) * (line1.p1.x - line2.p1.x)) /
            denom;
        if (denom === 0) {
            return false;
        }
        if (dst) {
            dst.x = line1.p1.x + ua * (line1.p2.x - line1.p1.x);
            dst.y = line1.p1.y + ua * (line1.p2.y - line1.p1.y);
        }
        return ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1;
    }
    // NOTE: Not used yet so we dont expose it.
    // /**
    //  * This function checks if the two lines intersects. This line and the incomming line.
    //  * @param ln Line.
    //  * @param asSegmentsQ
    //  * @param dst contains intersection position.
    //  * @returns true if there is an intersection, false otherwise.
    //  */
    // public tryGetIntersectionToRef(ln: Line2D<T>, asSegmentsQ: boolean, dst: T): boolean {
    //     const A = this.p1;
    //     const B = this.p2;
    //     const E = ln.p1;
    //     const F = ln.p2;
    //     const a1 = B.y - A.y;
    //     const b1 = A.x - B.x;
    //     const c1 = B.x * A.y - A.x * B.y;
    //     const a2 = F.y - E.y;
    //     const b2 = E.x - F.x;
    //     const c2 = F.x * E.y - E.x * F.y;
    //     const denom = a1 * b2 - a2 * b1;
    //     if (denom == 0) {
    //         return false;
    //     }
    //     const ip = { x: 0, y: 0 };
    //     ip.x = (b1 * c2 - b2 * c1) / denom;
    //     ip.y = (a2 * c1 - a1 * c2) / denom;
    //     if (asSegmentsQ) {
    //         if (Math.pow(ip.x - B.x, 2) + Math.pow(ip.y - B.y, 2) > Math.pow(A.x - B.x, 2) + Math.pow(A.y - B.y, 2)) {
    //             return false;
    //         }
    //         if (Math.pow(ip.x - A.x, 2) + Math.pow(ip.y - A.y, 2) > Math.pow(A.x - B.x, 2) + Math.pow(A.y - B.y, 2)) {
    //             return false;
    //         }
    //         if (Math.pow(ip.x - F.x, 2) + Math.pow(ip.y - F.y, 2) > Math.pow(E.x - F.x, 2) + Math.pow(E.y - F.y, 2)) {
    //             return false;
    //         }
    //         if (Math.pow(ip.x - E.x, 2) + Math.pow(ip.y - E.y, 2) > Math.pow(E.x - F.x, 2) + Math.pow(E.y - F.y, 2)) {
    //             return false;
    //         }
    //     }
    //     dst.x = ip.x;
    //     dst.y = ip.y;
    //     return true;
    // }
    /**
     * Takes three Point inputs a, b, and c and returns +1 if a->b->c is a counterclockwise angle,
     * -1 if a->b->c is a clockwise angle, and 0 if a->b->c are collinear.
     * @param a Vertex 2 point.
     * @param b Vertex 2 point.
     * @param c Vertex 2 point.
     * @returns +1 if ccw, -1 if cw, 0 if collinear.
     */
    static ccw(a, b, c) {
        return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
    }
}
//# sourceMappingURL=Line2D.js.map