// David Eberly, Geometric Tools, Redmond WA 98052 // Copyright (c) 1998-2020 // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt // Version: 4.0.2019.08.13 #pragma once #include #include // The plane is represented as Dot(U,X) = c where U is a unit-length normal // vector, c is the plane constant, and X is any point on the plane. The user // must ensure that the normal vector is unit length. namespace WwiseGTE { template class Hyperplane { public: // Construction and destruction. The default constructor sets the // normal to (0,...,0,1) and the constant to zero (plane z = 0). Hyperplane() : constant((Real)0) { normal.MakeUnit(N - 1); } // Specify U and c directly. Hyperplane(Vector const& inNormal, Real inConstant) : normal(inNormal), constant(inConstant) { } // U is specified, c = Dot(U,p) where p is a point on the hyperplane. Hyperplane(Vector const& inNormal, Vector const& p) : normal(inNormal), constant(Dot(inNormal, p)) { } // U is a unit-length vector in the orthogonal complement of the set // {p[1]-p[0],...,p[n-1]-p[0]} and c = Dot(U,p[0]), where the p[i] are // pointson the hyperplane. Hyperplane(std::array, N> const& p) { Matrix edge; for (int i = 0; i < N - 1; ++i) { edge.SetCol(i, p[i + 1] - p[0]); } // Compute the 1-dimensional orthogonal complement of the edges of // the simplex formed by the points p[]. SingularValueDecomposition svd(N, N - 1, 32); svd.Solve(&edge[0], -1); svd.GetUColumn(N - 1, &normal[0]); constant = Dot(normal, p[0]); } // Public member access. Vector normal; Real constant; public: // Comparisons to support sorted containers. bool operator==(Hyperplane const& hyperplane) const { return normal == hyperplane.normal && constant == hyperplane.constant; } bool operator!=(Hyperplane const& hyperplane) const { return !operator==(hyperplane); } bool operator< (Hyperplane const& hyperplane) const { if (normal < hyperplane.normal) { return true; } if (normal > hyperplane.normal) { return false; } return constant < hyperplane.constant; } bool operator<=(Hyperplane const& hyperplane) const { return !hyperplane.operator<(*this); } bool operator> (Hyperplane const& hyperplane) const { return hyperplane.operator<(*this); } bool operator>=(Hyperplane const& hyperplane) const { return !operator<(hyperplane); } }; // Template alias for convenience. template using Plane3 = Hyperplane<3, Real>; }