165 lines
9.5 KiB
C++
165 lines
9.5 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 Circle.hpp
|
|
/// @desc The Circle geometry object.
|
|
/// @edit 2024-08-01
|
|
|
|
#pragma once
|
|
|
|
#include <J3ML/Geometry/Shape.hpp>
|
|
#include <J3ML/Geometry/Forward.hpp>
|
|
#include <J3ML/LinearAlgebra.hpp>
|
|
|
|
namespace J3ML
|
|
{
|
|
|
|
/// A two-dimensional circle in 3D space.
|
|
/// This class represents both a hollow circle (only edge) and a solid circle (disc).
|
|
class Circle : public Shape
|
|
{
|
|
public:
|
|
/// The center position of this circle.
|
|
Vector3 Position;
|
|
/// The normal direction of this circle.
|
|
/** A circle is a two-dimensional object in 3D space. This normal vector (together with the Position)
|
|
specifies the plane in which this circle lies in.
|
|
This vector is always normalized. If you assign to this member directly, be sure to only assign normalized vectors. */
|
|
Vector3 Normal;
|
|
/// The radius of the circle.
|
|
/** This parameter must be strictly positive to specify a non-degenerate circle. If zero is specified, this circle
|
|
is considered to be degenerate. */
|
|
float Radius;
|
|
/// The default constructor does not initialize any members of this class.
|
|
/** This means that the values of members Position, Normal, and Radius are all undefined after creating
|
|
a new circle using this default constructor. Remember to assign them before use.
|
|
@see Position, Normal, Radius. */
|
|
Circle() {}
|
|
/// Constructs a new circle by explicitly specifying the member variables.
|
|
/** @param center The center point of the circle.
|
|
@param normal The direction vector that specifies the orientation of this circle.
|
|
This vector must be normalized, the constructor will not normalize the vector for you (for performance reasons).
|
|
@param radius The radius of the circle.
|
|
@see Position, Normal, Radius. */
|
|
Circle(const Vector3& center, const Vector3& normal, float radius);
|
|
|
|
/// Returns a normalized direction vector to the 'U direction' of the circle.
|
|
/** This vector lies on the plane of this circle.
|
|
The U direction specifies the first basis vector of a local space of this circle. */
|
|
Vector3 BasisU() const;
|
|
/// Returns a normalized direction vector to the 'V direction' of the circle.
|
|
/** This vector lies on the plane of this circle.
|
|
The V direction specifies the second basis vector of a local space of this circle. */
|
|
Vector3 BasisV() const;
|
|
/// Returns a point at the edge of this circle.
|
|
/** @param angleRadians The direction of the point to get. A full circle is generated by the range [0, 2*pi],
|
|
but it is ok to pass in values outside this range.
|
|
@note This function is equivalent to calling GetPoint(float angleRadians, float d) with a value of d == 1.
|
|
@return A point in world space at the edge of this circle. */
|
|
Vector3 GetPoint(float angleRadians) const;
|
|
/// Returns a point inside this circle.
|
|
/** @param angleRadians The direction of the point to get. A full circle is generated by the range [0, 2*pi],
|
|
but it is ok to pass in values outside this range.
|
|
@param d A value in the range [0, 1] that specifies the normalized distance of the point from the center of the circle.
|
|
A value of 0 returns the center point of this circle. A value of 1 returns a point at the edge of this circle.
|
|
The range of d is not restricted, so it is ok to pass in values larger than 1 to generate a point lying completely
|
|
outside the circle. */
|
|
Vector3 GetPoint(float angleRadians, float d) const;
|
|
|
|
/// Returns the center point of this circle.
|
|
/** This point is also the center of mass for this circle. The functions CenterPoint() and Centroid() are equivalent.
|
|
@see Position. */
|
|
Vector3 CenterPoint() const { return Position; }
|
|
Vector3 Centroid() const { return Position;}
|
|
|
|
/// Computes an extreme point of this Circle/Disc in the given direction.
|
|
/** An extreme point is a farthest point of this Circle/Disc in the given direction. Given a direction,
|
|
this point is not necessarily 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 An extreme point of this Circle/Disc in the given direction. The returned point is always at
|
|
the edge of this Circle. */
|
|
Vector3 ExtremePoint(const Vector3& direction) const;
|
|
|
|
/// Computes the plane this circle is contained in.
|
|
/** All of the points of this circle lie inside this plane.
|
|
@see class Plane. */
|
|
Plane ContainingPlane() const;
|
|
|
|
/// Translates this Circle in world space.
|
|
/** @param offset The amount of displacement to apply to this circle, in world space coordinates.
|
|
@see Transform(). */
|
|
void Translate(const Vector3& offset);
|
|
|
|
/// Applies a transformation to this Circle.
|
|
/** @param transform The transformation to apply to this Circle. This transformation must be
|
|
affine, and must contain an orthogonal set of column vectors (may not contain shear or projection).
|
|
The transformation can only contain uniform scale, and may not contain mirroring.
|
|
@see Translate(), Scale(), classes Matrix3x3, Matrix4x4, Quaternion. */
|
|
void Transform(const Matrix3x3& transform);
|
|
void Transform(const Matrix4x4& transform);
|
|
void Transform(const Quaternion& transform);
|
|
|
|
/// Tests if the given point is contained at the edge of this circle.
|
|
/** @param point The target point to test.
|
|
@param maxDistance The epsilon threshold to test the distance against. This effectively turns the circle into a torus
|
|
for this test.
|
|
@see DistanceToEdge(), DistanceToDisc(), ClosestPointToEdge(), ClosestPointToDisc().
|
|
@todo Implement DiscContains(Vector3/LineSegment/Triangle). */
|
|
bool EdgeContains(const Vector3& point, float maxDistance = 1e-6f) const;
|
|
|
|
/// Computes the distance of the given object to the edge of this circle.
|
|
/** @todo Implement DistanceToEdge(Ray/LineSegment/Line).
|
|
@return The distance of the given point to the edge of this circle. If the point is contained on this circle,
|
|
the value 0 is returned.
|
|
@see DistanceToEdge(), DistanceToDisc(), ClosestPointToDisc().*/
|
|
float DistanceToEdge(const Vector3& point) const;
|
|
|
|
/// Computes the distance of the given object to this disc (filled circle).
|
|
/** If the point is contained inside this disc, the value 0 is returned.
|
|
@see DistanceToEdge(), ClosestPointToEdge(), ClosestPointToDisc().
|
|
@todo Implement DistanceToDisc(Ray/LineSegment/Line). */
|
|
float DistanceToDisc(const Vector3& point) const;
|
|
|
|
/// Computes the closest point on the edge of this circle to the given object.
|
|
/** @todo Implement ClosestPointToEdge(Ray/LineSegment/Line).
|
|
@see DistanceToEdge(), DistanceToDisc(), ClosestPointToDisc(). */
|
|
Vector3 ClosestPointToEdge(const Vector3& point) const;
|
|
|
|
/// Computes the closest point on the disc of this circle to the given object.
|
|
/** @todo Implement ClosestPointToDisc(Ray/LineSegment/Line).
|
|
@see DistanceToEdge(), DistanceToDisc(), ClosestPointToEdge(). */
|
|
Vector3 ClosestPointToDisc(const Vector3& point) const;
|
|
|
|
/// Tests this circle for an intersection against the given plane.
|
|
/** @note For Circle-Plane intersection, there is no need to differentiate between a hollow or filled circle(disc).
|
|
@return The number of intersection points found for this circle and the given plane.
|
|
@see IntersectsDisc(). */
|
|
int Intersects(const Plane& plane, Vector3* pt1, Vector3* pt2) const;
|
|
int Intersects(const Plane& plane) const;
|
|
|
|
/// Tests this disc for an intersection against the given object.
|
|
/** @see Intersects(). */
|
|
bool IntersectsDisc(const Line& line) const;
|
|
bool IntersectsDisc(const LineSegment& lineSegment) const;
|
|
bool IntersectsDisc(const Ray& ray) const;
|
|
|
|
/// Tests if this circle intersects the faces of the given OBB.
|
|
/** @param obb The bounding box to test against. This box is treated as "hollow", i.e. only the faces of the OBB are considered to be
|
|
a part of the OBB.
|
|
@return A vector that contains all the detected points of intersection for this circle and the given OBB. If the circle is fully
|
|
contained inside the OBB, or is fully outside the OBB, no intersection occurs, and the returned vector has zero elements.
|
|
@see Intersects(), IntersectsDisc(). */
|
|
std::vector<Vector3> IntersectsFaces(const OBB& obb) const;
|
|
std::vector<Vector3> IntersectsFaces(const AABB& aabb) const;
|
|
};
|
|
Circle operator *(const Matrix3x3& transform, const Circle& circle);
|
|
Circle operator *(const Matrix4x4& transform, const Circle& circle);
|
|
Circle operator *(const Quaternion& transform, const Circle& circle);
|
|
std::ostream& operator << (std::ostream& o, const Circle& circle);
|
|
}
|