import { sort_by } from "./util/array";
import { Selection } from "../models/selections/selection";
export function point_in_poly(x, y, px, py) {
    let inside = false;
    let x1 = px[px.length - 1];
    let y1 = py[py.length - 1];
    for (let i = 0; i < px.length; i++) {
        const x2 = px[i];
        const y2 = py[i];
        if ((y1 < y) != (y2 < y)) {
            if ((x1 + (y - y1) / (y2 - y1) * (x2 - x1)) < x)
                inside = !inside;
        }
        x1 = x2;
        y1 = y2;
    }
    return inside;
}
export function point_in_ellipse(x, y, angle, b, a, x0, y0) {
    const A = ((Math.cos(angle) / a) ** 2 + (Math.sin(angle) / b) ** 2);
    const B = 2 * Math.cos(angle) * Math.sin(angle) * ((1 / a) ** 2 - (1 / b) ** 2);
    const C = ((Math.cos(angle) / b) ** 2 + (Math.sin(angle) / a) ** 2);
    const eqn = A * (x - x0) ** 2 + B * (x - x0) * (y - y0) + C * (y - y0) ** 2;
    const inside = eqn <= 1;
    return inside;
}
export function create_empty_hit_test_result() {
    return new Selection();
}
export function create_hit_test_result_from_hits(hits) {
    const result = new Selection();
    result.indices = sort_by(hits, ([_i, dist]) => dist).map(([i, _dist]) => i);
    return result;
}
function sqr(x) {
    return x * x;
}
export function dist_2_pts(p0, p1) {
    return sqr(p0.x - p1.x) + sqr(p0.y - p1.y);
}
export function dist_to_segment_squared(p, v, w) {
    const l2 = dist_2_pts(v, w);
    if (l2 == 0)
        return dist_2_pts(p, v);
    const t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
    if (t < 0)
        return dist_2_pts(p, v);
    if (t > 1)
        return dist_2_pts(p, w);
    const q = { x: v.x + t * (w.x - v.x), y: v.y + t * (w.y - v.y) };
    return dist_2_pts(p, q);
}
export function dist_to_segment(p, v, w) {
    return Math.sqrt(dist_to_segment_squared(p, v, w));
}
export function check_2_segments_intersect(l0_x0, l0_y0, l0_x1, l0_y1, l1_x0, l1_y0, l1_x1, l1_y1) {
    /*
     *  Check if 2 segments (l0 and l1) intersect. Returns a structure with
     *  the following attributes:
     *   * hit (boolean): whether the 2 segments intersect
     *   * x (float): x coordinate of the intersection point
     *   * y (float): y coordinate of the intersection point
     */
    const den = ((l1_y1 - l1_y0) * (l0_x1 - l0_x0)) - ((l1_x1 - l1_x0) * (l0_y1 - l0_y0));
    if (den == 0) {
        return { hit: false, x: null, y: null };
    }
    else {
        let a = l0_y0 - l1_y0;
        let b = l0_x0 - l1_x0;
        const num1 = ((l1_x1 - l1_x0) * a) - ((l1_y1 - l1_y0) * b);
        const num2 = ((l0_x1 - l0_x0) * a) - ((l0_y1 - l0_y0) * b);
        a = num1 / den;
        b = num2 / den;
        const x = l0_x0 + (a * (l0_x1 - l0_x0));
        const y = l0_y0 + (a * (l0_y1 - l0_y0));
        return { hit: (a > 0 && a < 1) && (b > 0 && b < 1), x, y };
    }
}
//# sourceMappingURL=hittest.js.map