import '../../assert/js/assert.js';
import '../../globals.js';
// Copyright 2014-2024, University of Colorado Boulder
/**
 * A mathematical plane in 3 dimensions determined by a normal vector to the plane and the distance to the closest
 * point on the plane to the origin
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import dot from './dot.js';
import Ray3 from './Ray3.js';
import Vector3 from './Vector3.js';
class Plane3 {
    /**
     * @param normal - A normal vector (perpendicular) to the plane
     * @param distance - The signed distance to the plane from the origin, so that normal.times( distance )
     *                            will be a point on the plane.
     */
    constructor(normal, distance) {
        this.normal = normal;
        this.distance = distance;
        assert && assert(Math.abs(normal.magnitude - 1) < 0.01, 'the normal vector must be a unit vector');
    }
    intersectWithRay(ray) {
        return ray.pointAtDistance(ray.distanceToPlane(this));
    }
    /**
     * Returns a new plane that passes through three points $(\vec{a},\vec{b},\vec{c})$
     * The normal of the plane points along $\vec{c-a} \times \vec{b-a}$
     * Passing three collinear points will return null
     *
     * @param a - first point
     * @param b - second point
     * @param c - third point
     */
    static fromTriangle(a, b, c) {
        const normal = (c.minus(a)).cross(b.minus(a));
        if (normal.magnitude === 0) {
            return null;
        }
        normal.normalize();
        return new Plane3(normal, normal.dot(a));
    }
    getIntersection(plane) {
        // see https://en.wikipedia.org/wiki/Plane%E2%80%93plane_intersection
        const dot = this.normal.dot(plane.normal);
        const det = 1 - dot * dot;
        // parallel planes
        if (det === 0) {
            return null;
        }
        const c1 = (this.distance - plane.distance * dot) / det;
        const c2 = (plane.distance - this.distance * dot) / det;
        return new Ray3(this.normal.timesScalar(c1).plus(plane.normal.timesScalar(c2)), this.normal.cross(plane.normal).normalized());
    }
}
Plane3.XY = new Plane3(new Vector3(0, 0, 1), 0);
Plane3.XZ = new Plane3(new Vector3(0, 1, 0), 0);
Plane3.YZ = new Plane3(new Vector3(1, 0, 0), 0);
export default Plane3;
dot.register('Plane3', Plane3);
//# sourceMappingURL=Plane3.js.map