124 lines
6.1 KiB
C++
124 lines
6.1 KiB
C++
/// Josh's 3D Math Library
|
|
/// A C++20 Library for 3D Math, Computer Graphics, and Scientific Computing.
|
|
/// Developed and Maintained by Josh O'Leary @ Redacted Software.
|
|
/// Special Thanks to William Tomasine II and Maxine Hayes.
|
|
/// (c) 2024 Redacted Software
|
|
/// This work is dedicated to the public domain.
|
|
|
|
/// @file Sphere.hpp
|
|
/// @desc The Sphere geometry object.
|
|
/// @edit 2024-07-06
|
|
|
|
#pragma once
|
|
|
|
#include <J3ML/Geometry/Shape.hpp>
|
|
#include <J3ML/Geometry/Forward.hpp>
|
|
#include <J3ML/LinearAlgebra.hpp>
|
|
|
|
|
|
namespace J3ML::Geometry
|
|
{
|
|
|
|
// A mathematical representation of a 3-dimensional sphere
|
|
class Sphere : public Shape
|
|
{
|
|
public: // Properties
|
|
Vector3 Position; // The center point of this sphere.
|
|
float Radius; /// The radius of this sphere.
|
|
public: // Constructors
|
|
|
|
/// The default constructor does not initialize any members of this class.
|
|
/** This means that the values of the members pos and r are undefined after creating a new Sphere using this
|
|
default constructor. Remember to assign to them before use.
|
|
@see pos, r. */
|
|
Sphere() {}
|
|
/// Constructs a sphere with a given position and radius.
|
|
/** @param radius A value > 0 constructs a sphere with positive volume. A value of <= 0 is valid, and constructs a degenerate sphere.
|
|
@see pos, r, IsFinite(), IsDegenerate() */
|
|
Sphere(const Vector3& pos, float radius) : Position(pos), Radius(radius) {}
|
|
|
|
/// Constructs a sphere that passes through the given two points.
|
|
/** The constructed sphere will be the minimal sphere that encloses the given two points. The center point of this
|
|
sphere will lie midway between pointA and pointB, and the radius will be half the distance between pointA and
|
|
pointB. Both input points are assumed to be finite. */
|
|
Sphere(const Vector3 &pointA, const Vector3 &pointB);
|
|
|
|
/// Constructs a sphere that passes through the given three points.
|
|
/** @note The resulting sphere may not be the minimal enclosing sphere for the three points! */
|
|
Sphere(const Vector3 &pointA, const Vector3 &pointB, const Vector3 &pointC);
|
|
|
|
/// Constructs a sphere that passes through the given four points.
|
|
/** @note The resulting sphere may not be the minimal enclosing sphere for the four points! */
|
|
Sphere(const Vector3 &pointA, const Vector3 &pointB, const Vector3 &pointC, const Vector3 &pointD);
|
|
|
|
public:
|
|
/// Generates a random point on the surface of this sphere
|
|
/** The points are distributed uniformly.
|
|
This function uses the rejection method to generate a uniform distribution of points on the surface.
|
|
Therefore, it is assumed that this sphere is not degenerate, i.e. it has a positive radius.
|
|
A fixed number of 1000 tries is performed, after which a fixed point on the surface is returned as a fallback.
|
|
@param rng A pre-seeded random number generator object that is to be used by this function to generate random vlaues.
|
|
@see class RNG, RandomPointInside(), IsDegenerate()
|
|
@todo Add Sphere::PointOnSurface(polarYaw, polarPitch). */
|
|
Vector3 RandomPointOnSurface(RNG& rng) const;
|
|
static Vector3 RandomPointOnSurface(RNG& rng, const Vector3& center, float radius);
|
|
|
|
/// Generates a random point inside this sphere.
|
|
/** The points are distributed uniformly.
|
|
This function uses the rejection method to generate a uniform distribution of points inside a sphere.
|
|
Therefore, it is assumed that this sphere is not degenerate, i.e. it has a positive radius.
|
|
A fixed number of 1000 tries is performed, after which the sphere center position is returned as a fallback.
|
|
@param rng A pre-seeded random number generator object that is to be used by this function to generate random values.
|
|
@see class RNG, RandomPointOnSurface(), IsDegenerate().
|
|
@todo Add Sphere::Point(polarYaw, polarPitch, radius). */
|
|
Vector3 RandomPointInside(RNG& rng);
|
|
static Vector3 RandomPointInside(RNG& rng, const Vector3& center, float radius);
|
|
public:
|
|
/// Quickly returns an arbitrary point inside this Sphere. Used in GJK intersection test.
|
|
[[nodiscard]] Vector3 AnyPointFast() const { return Position; }
|
|
/// Computes the extreme point of this Sphere in the given direction.
|
|
/** An extreme point is a farthest point of this Sphere in the given direction. For
|
|
a Sphere, this point is unique.
|
|
@param direction The direction vector of the direction to find the extreme point. This vector may
|
|
be unnormalized, but may not be null.
|
|
@return The extreme point of this Sphere in the given direction. */
|
|
[[nodiscard]] Vector3 ExtremePoint(const Vector3 &direction) const;
|
|
Vector3 ExtremePoint(const Vector3 &direction, float &projectionDistance) const;
|
|
|
|
|
|
Vector3 Centroid() const { return Position; }
|
|
Vector3 CenterPos() const { return Centroid(); }
|
|
|
|
/// Translates this Sphere in world space.
|
|
/** @param offset The amount of displacement to apply to this Sphere, in world space coordinates.
|
|
@see Transform(). */
|
|
void Translate(const Vector3& offset);
|
|
|
|
|
|
void Transform(const Matrix3x3& transform);
|
|
|
|
void Transform(const Matrix4x4& transform);
|
|
|
|
static inline float Cube(float inp);
|
|
|
|
[[nodiscard]] float Volume() const;
|
|
|
|
[[nodiscard]] float SurfaceArea() const;
|
|
|
|
[[nodiscard]] bool IsFinite() const;
|
|
|
|
[[nodiscard]] bool IsDegenerate() const;
|
|
|
|
[[nodiscard]] bool Contains(const Vector3& point) const;
|
|
|
|
[[nodiscard]] bool Contains(const Vector3& point, float epsilon) const;
|
|
|
|
[[nodiscard]] bool Contains(const LineSegment& lineseg) const;
|
|
TriangleMesh GenerateUVSphere(int subdivisions = 10.f) const;
|
|
TriangleMesh GenerateIcososphere() const;
|
|
TriangleMesh GenerateCubesphere() const;
|
|
|
|
|
|
void ProjectToAxis(const Vector3 &direction, float &outMin, float &outMax) const;
|
|
};
|
|
} |