/**
 * Sutherland-Hodgman clip of `points_in` against the axis-aligned
 * half-plane `coord_idx ≤ bound` (or `coord_idx ≥ bound` when
 * `keep_below` is false). 2D stride 2; result to `points_out`.
 * Returns surviving vertex count.
 *
 * @param {Float64Array} points_in
 * @param {number} point_count
 * @param {Float64Array} points_out
 * @param {number} coord_idx 0 = u, 1 = v
 * @param {number} bound
 * @param {boolean} keep_below true to keep points with coord ≤ bound
 * @returns {number} surviving vertex count
 */
export function clip_against_axis_uv(points_in, point_count, points_out, coord_idx, bound, keep_below) {
    let out_count = 0;

    for (let i = 0; i < point_count; i++) {
        const j = (i + 1) % point_count;

        const ax = points_in[i * 2], ay = points_in[i * 2 + 1];
        const bx = points_in[j * 2], by = points_in[j * 2 + 1];

        const av = coord_idx === 0 ? ax : ay;
        const bv = coord_idx === 0 ? bx : by;

        const a_inside = keep_below ? (av <= bound) : (av >= bound);
        const b_inside = keep_below ? (bv <= bound) : (bv >= bound);

        if (a_inside) {
            points_out[out_count * 2] = ax;
            points_out[out_count * 2 + 1] = ay;
            out_count++;
        }

        if (a_inside !== b_inside) {

            // a_inside !== b_inside ⇒ av and bv are on opposite sides of `bound`,
            // so av !== bv and the denominator is non-zero (the `:0` fallback was
            // unreachable here).
            const denom = bv - av;
            const t = (bound - av) / denom;

            points_out[out_count * 2] = ax + (bx - ax) * t;
            points_out[out_count * 2 + 1] = ay + (by - ay) * t;

            out_count++;
        }
    }

    return out_count;
}