Implement Polyhedron::Contains Intersects ContainsConvex ClosestPoint IsNull

This commit is contained in:
2024-07-10 14:19:04 -04:00
parent b07e926cd9
commit 2f9cb5dd87
2 changed files with 156 additions and 57 deletions

View File

@@ -11,7 +11,7 @@ namespace J3ML::Geometry
using namespace J3ML::LinearAlgebra;
// Represents a three-dimensional closed geometric solid defined by flat polygonal faces.
class Polyhedron : public Shape
class Polyhedron
{
public:
// Stores a list of indices of a single face of a Polygon
@@ -33,78 +33,101 @@ namespace J3ML::Geometry
// Specifies the vertices of this polyhedron.
std::vector<Vector3> v;
std::vector<Face> f;
public:
/// The default constructor creates a null polyhedron.
/** The null polyhedron has 0 vertices and 0 faces.
@see IsNull(). */
Polyhedron() = default;
int NumVertices() const {return (int)v.size();}
int NumFaces() const { return (int)f.size();}
AABB MinimalEnclosingAABB() const;
[[nodiscard]] int NumVertices() const {return (int)v.size();}
[[nodiscard]] int NumFaces() const { return (int)f.size();}
[[nodiscard]] AABB MinimalEnclosingAABB() const;
Vector3 Vertex(int vertexIndex) const;
[[nodiscard]] Vector3 Vertex(int vertexIndex) const;
[[nodiscard]] bool Contains(const Vector3&) const;
[[nodiscard]] bool Contains(const LineSegment&) const;
[[nodiscard]] bool Contains(const Triangle&) const;
[[nodiscard]] bool Contains(const Polygon&) const;
[[nodiscard]] bool Contains(const AABB&) const;
[[nodiscard]] bool Contains(const OBB&) const;
[[nodiscard]] bool Contains(const Frustum&) const;
[[nodiscard]] bool Contains(const Polyhedron&) const;
[[nodiscard]] bool ContainsConvex(const Vector3&, float epsilon = 1e-4f) const;
[[nodiscard]] bool ContainsConvex(const LineSegment&) const;
[[nodiscard]] bool ContainsConvex(const Triangle&) const;
/// Tests whether this polyhedron and the given object intersect.
/** Both objects are treated as "solid", meaning that if one of the objects is fully contained inside
another, this function still returns true. (e.g. in case a line segment is contained inside this polyhedron,
or this polyhedron is contained inside a sphere, etc.)
@return True if an intersection occurs or one of the objects is contained inside the other, false otherwise.
@note This function assumes that this polyhedron is closed and the edges are not self-intersecting.
@see Contains(), ContainsConvex(), ClosestPoint(), ClosestPointConvex(), Distance(), IntersectsConvex().
@todo Add Intersects(Circle/Disc). */
[[nodiscard]] bool Intersects(const Line&) const;
[[nodiscard]] bool Intersects(const LineSegment&) const;
[[nodiscard]] bool Intersects(const Ray&) const;
[[nodiscard]] bool Intersects(const Plane&) const;
[[nodiscard]] bool Intersects(const Polyhedron&) const;
[[nodiscard]] bool Intersects(const AABB& aabb) const;
[[nodiscard]] bool Intersects(const OBB&) const;
[[nodiscard]] bool Intersects(const Triangle&) const;
[[nodiscard]] bool Intersects(const Polygon&) const;
[[nodiscard]] bool Intersects(const Frustum&) const;
[[nodiscard]] bool Intersects(const Sphere&) const;
[[nodiscard]] bool Intersects(const Capsule& capsule) const;
[[nodiscard]] bool IsClosed() const;
[[nodiscard]] Plane FacePlane(int faceIndex) const;
[[nodiscard]] std::vector<Polygon> Faces() const;
[[nodiscard]] int NumEdges() const;
[[nodiscard]] LineSegment Edge(int edgeIndex) const;
[[nodiscard]] std::vector<std::pair<int, int>> EdgeIndices() const;
[[nodiscard]] std::vector<LineSegment> Edges() const;
[[nodiscard]] Polygon FacePolygon(int faceIndex) const;
[[nodiscard]] Vector3 FaceNormal(int faceIndex) const;
[[nodiscard]] bool IsConvex() const;
/// Returns true if the Euler formula (V + F - E == 2) holds for this Polyhedron.
/** The running time is O(E) ~ O(V).
@see NumVertices(), NumEdges(), NumFaces(). */
[[nodiscard]] bool EulerFormulaHolds() const;
bool Contains(const Vector3&) const;
bool Contains(const LineSegment&) const;
bool Contains(const Triangle&) const;
bool Contains(const Polygon&) const;
bool Contains(const AABB&) const;
bool Contains(const OBB&) const;
bool Contains(const Frustum&) const;
bool Contains(const Polyhedron&) const;
[[nodiscard]] Vector3 ApproximateConvexCentroid() const;
bool ContainsConvex(const Vector3&, float epsilon = 1e-4f) const;
bool ContainsConvex(const LineSegment&) const;
bool ContainsConvex(const Triangle&) const;
[[nodiscard]] int ExtremeVertex(const Vector3 &direction) const;
bool Intersects(const Line&) const;
bool Intersects(const LineSegment&) const;
bool Intersects(const Ray&) const;
bool Intersects(const Plane&) const;
bool Intersects(const Polyhedron&) const;
bool Intersects(const AABB&) const;
bool Intersects(const OBB&) const;
bool Intersects(const Triangle&) const;
bool Intersects(const Polygon&) const;
bool Intersects(const Frustum&) const;
bool Intersects(const Sphere&) const;
bool Intersects(const Capsule& capsule) const;
bool IsClosed() const;
Plane FacePlane(int faceIndex) const;
std::vector<Polygon> Faces() const;
int NumEdges() const;
LineSegment Edge(int edgeIndex) const;
std::vector<std::pair<int, int>> EdgeIndices() const;
std::vector<LineSegment> Edges() const;
Polygon FacePolygon(int faceIndex) const;
Vector3 FaceNormal(int faceIndex) const;
bool IsConvex() const;
Vector3 ApproximateConvexCentroid() const;
int ExtremeVertex(const Vector3 &direction) const;
Vector3 ExtremePoint(const Vector3 &direction) const;
[[nodiscard]] Vector3 ExtremePoint(const Vector3 &direction) const;
/// Tests if the given face of this Polyhedron contains the given point.
bool FaceContains(int faceIndex, const Vector3 &worldSpacePoint, float polygonThickness = 1e-3f) const;
[[nodiscard]] bool FaceContains(int faceIndex, const Vector3 &worldSpacePoint, float polygonThickness = 1e-3f) const;
/// A helper for Contains() and FaceContains() tests: Returns a positive value if the given point is contained in the given face,
/// and a negative value if the given point is outside the face. The magnitude of the return value reports a pseudo-distance
/// from the point to the nearest edge of the face polygon. This is used as a robustness/stability criterion to estimate how
/// numerically believable the result is.
float FaceContainmentDistance2D(int faceIndex, const Vector3 &worldSpacePoint, float polygonThickness = 1e-5f) const;
[[nodiscard]] float FaceContainmentDistance2D(int faceIndex, const Vector3 &worldSpacePoint, float polygonThickness = 1e-5f) const;
void ProjectToAxis(const Vector3 &direction, float &outMin, float &outMax) const;
Vector3 ClosestPoint(const LineSegment& lineSegment, Vector3 *lineSegmentPt) const;
[[nodiscard]] Vector3 ClosestPoint(const Vector3& point) const;
/// Returns true if this polyhedron has 0 vertices and 0 faces.
bool IsNull() const { return v.empty() && f.empty(); }
protected:
private:
};