diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index d3d6daf81..65203c4b0 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -46,6 +46,7 @@ namespace Nz bool IsValid() const; + Sphere& MakeUnit(); Sphere& MakeZero(); Sphere& Set(T X, T Y, T Z, T Radius); @@ -71,6 +72,7 @@ namespace Nz bool operator!=(const Sphere& sphere) const; static Sphere Lerp(const Sphere& from, const Sphere& to, T interpolation); + static Sphere Unit(); static Sphere Zero(); T x, y, z, radius; diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index fb7297d7a..062a7b271 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -13,6 +13,20 @@ namespace Nz { + /*! + * \class Nz::Sphere + * \brief Math class that represents a sphere "S2" in a three dimensional euclidean space + */ + + /*! + * \brief Constructs a Sphere object from its center position and radius + * + * \param X X position + * \param Y Y position + * \param Z Z position + * \param Radius half of the diameter + */ + template Sphere::Sphere(T X, T Y, T Z, T Radius) { @@ -25,18 +39,38 @@ namespace Nz Set(rect); } */ + + /*! + * \brief Constructs a Sphere object from its position and radius + * + * \param center Center of the sphere + * \param Radius Half of the diameter + */ + template Sphere::Sphere(const Vector3& center, T Radius) { Set(center, Radius); } + /*! + * \brief Constructs a Sphere object from an array of four elements + * + * \param sphere[4] sphere[0] is X component, sphere[1] is Y component, sphere[2] is Z component and sphere[3] is radius + */ + template Sphere::Sphere(const T sphere[4]) { Set(sphere); } + /*! + * \brief Constructs a Sphere object from another type of Sphere + * + * \param sphere Sphere of type U to convert to type T + */ + template template Sphere::Sphere(const Sphere& sphere) @@ -44,12 +78,32 @@ namespace Nz Set(sphere); } + /*! + * \brief Tests whether the sphere contains the provided point inclusive of the edge of the sphere + * \return true if inclusive + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \see Contains + */ + template bool Sphere::Contains(T X, T Y, T Z) const { - return SquaredDistance(X, Y, Z) <= radius*radius; + return SquaredDistance(X, Y, Z) <= radius * radius; } + /*! + * \brief Tests whether the sphere contains the provided box inclusive of the edge of the sphere + * \return true if all inclusive + * + * \param box Three dimensional box + * + * \see Contains + */ + template bool Sphere::Contains(const Box& box) const { @@ -61,12 +115,31 @@ namespace Nz return false; } + + /*! + * \brief Tests whether the sphere contains the provided point inclusive of the edge of the sphere + * \return true if inclusive + * + * \param point Position of the point + */ + template bool Sphere::Contains(const Vector3& point) const { return Contains(point.x, point.y, point.z); } + /*! + * \brief Returns the distance from the center of the sphere to the point + * \return Distance to the point + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \see SquaredDistance + */ + template T Sphere::Distance(T X, T Y, T Z) const { @@ -74,12 +147,32 @@ namespace Nz return distance.GetLength(); } + /*! + * \brief Returns the distance from the center of the sphere to the point + * \return Distance to the point + * + * \param point Position of the point + * + * \see SquaredDistance + */ + template T Sphere::Distance(const Vector3& point) const { return Distance(point.x, point.y, point.z); } + /*! + * \brief Extends the sphere to contain the point in the boundary + * \return A reference to this sphere extended + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \see ExtendTo + */ + template Sphere& Sphere::ExtendTo(T X, T Y, T Z) { @@ -90,12 +183,30 @@ namespace Nz return *this; } + /*! + * \brief Extends the sphere to contain the point in the boundary + * \return A reference to this sphere extended + * + * \param point Position of the point + * + * \see ExtendTo + */ + template Sphere& Sphere::ExtendTo(const Vector3& point) { return ExtendTo(point.x, point.y, point.z); } + /*! + * \brief Computes the negative vertex of one direction + * \return The position of the vertex on the sphere in the opposite way of the normal while considering the center + * + * \param normal Vector normalized indicating a direction + * + * \see GetPositiveVertex + */ + template Vector3 Sphere::GetNegativeVertex(const Vector3& normal) const { @@ -105,12 +216,26 @@ namespace Nz return neg; } + /*! + * \brief Gets a Vector3 of the position + * \return The position of the center of the sphere + */ + template Vector3 Sphere::GetPosition() const { return Vector3(x, y, z); } + /*! + * \brief Computes the positive vertex of one direction + * \return The position of the vertex on the sphere in the same way of the normal while considering the center + * + * \param normal Vector normalized indicating a direction + * + * \see GetNegativeVertex + */ + template Vector3 Sphere::GetPositiveVertex(const Vector3& normal) const { @@ -120,6 +245,13 @@ namespace Nz return pos; } + /*! + * \brief Checks whether or not this sphere intersects a box + * \return true if the box intersects + * + * \param box Box to check + */ + template bool Sphere::Intersect(const Box& box) const { @@ -128,51 +260,88 @@ namespace Nz if (x < box.x) { T diff = x - box.x; - squaredDistance += diff*diff; + squaredDistance += diff * diff; } else if (x > box.x + box.width) { T diff = x - (box.x + box.width); - squaredDistance += diff*diff; + squaredDistance += diff * diff; } if (y < box.y) { T diff = y - box.y; - squaredDistance += diff*diff; + squaredDistance += diff * diff; } else if (y > box.y + box.height) { T diff = y - (box.y + box.height); - squaredDistance += diff*diff; + squaredDistance += diff * diff; } if (z < box.z) { T diff = z - box.z; - squaredDistance += diff*diff; + squaredDistance += diff * diff; } else if (z > box.z + box.depth) { T diff = z - (box.z + box.depth); - squaredDistance += diff*diff; + squaredDistance += diff * diff; } return squaredDistance <= radius * radius; } + /*! + * \brief Checks whether or not this sphere intersects another sphere + * \return true if the spheres intersect or if one is in the other + * + * \param sphere Sphere to check + */ + template bool Sphere::Intersect(const Sphere& sphere) const { - return SquaredDistance(sphere.x, sphere.y, sphere.z) - radius*radius <= sphere.radius*sphere.radius; + return SquaredDistance(sphere.x, sphere.y, sphere.z) - radius * radius <= sphere.radius * sphere.radius; } + /*! + * \brief Checks whether this sphere is valid + * \return true if the sphere has a strictly positive radius + */ + template bool Sphere::IsValid() const { return radius > F(0.0); } + /*! + * \brief Makes the sphere position (0, 0, 0) and radius 1 + * \return A reference to this vector with position (0, 0, 0) and radius 1 + * + * \see Unit + */ + + template + Sphere& Sphere::MakeUnit() + { + x = F(0.0); + y = F(0.0); + z = F(0.0); + radius = F(1.0); + + return *this; + } + + /*! + * \brief Makes the sphere position (0, 0, 0) and radius 0 + * \return A reference to this vector with position (0, 0, 0) and radius 0 + * + * \see Zero + */ + template Sphere& Sphere::MakeZero() { @@ -184,6 +353,16 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the sphere with center and radius + * \return A reference to this sphere + * + * \param X X position + * \param Y Y position + * \param Z Z position + * \param Radius half of the diameter + */ + template Sphere& Sphere::Set(T X, T Y, T Z, T Radius) { @@ -195,6 +374,14 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the sphere with center and radius + * \return A reference to this sphere + * + * \param center Center of the sphere + * \param Radius Half of the diameter + */ + template Sphere& Sphere::Set(const Vector3& center, T Radius) { @@ -217,6 +404,14 @@ namespace Nz return *this; } */ + + /*! + * \brief Sets the components of the sphere with center and radius from another + * \return A reference to this sphere + * + * \param sphere The other sphere + */ + template Sphere& Sphere::Set(const Sphere& sphere) { @@ -225,6 +420,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the sphere from an array of four elements + * \return A reference to this sphere + * + * \param sphere[4] sphere[0] is X position, sphere[1] is Y position, sphere[2] is Z position and sphere[3] is radius + */ + template Sphere& Sphere::Set(const T sphere[4]) { @@ -236,6 +438,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the sphere from another type of Sphere + * \return A reference to this sphere + * + * \param sphere Sphere of type U to convert its components + */ + template template Sphere& Sphere::Set(const Sphere& sphere) @@ -248,19 +457,44 @@ namespace Nz return *this; } + /*! + * \brief Returns the squared distance from the center of the sphere to the point + * \return Squared distance to the point + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \see Distance + */ + template T Sphere::SquaredDistance(T X, T Y, T Z) const { - Vector3 distance(X-x, Y-y, Z-z); + Vector3 distance(X - x, Y - y, Z - z); return distance.GetSquaredLength(); } + /*! + * \brief Returns the squared distance from the center of the sphere to the point + * \return Squared distance to the point + * + * \param point Position of the point + * + * \see Distance + */ + template T Sphere::SquaredDistance(const Vector3& point) const { return SquaredDistance(point.x, point.y, point.z); } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Sphere(x, y, z; radius)" + */ + template String Sphere::ToString() const { @@ -269,6 +503,15 @@ namespace Nz return ss << "Sphere(" << x << ", " << y << ", " << z << "; " << radius << ')'; } + /*! + * \brief Returns the ith element of the sphere + * \return A reference to the ith element of the sphere + * + * \remark Access to index greather than 4 is undefined behavior + * \remark Produce a NazaraError if you try to acces to index greather than 4 with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of you try to acces to index greather than 4 + */ + template T& Sphere::operator[](unsigned int i) { @@ -286,6 +529,15 @@ namespace Nz return *(&x+i); } + /*! + * \brief Returns the ith element of the sphere + * \return A value to the ith element of the sphere + * + * \remark Access to index greather than 4 is undefined behavior + * \remark Produce a NazaraError if you try to acces to index greather than 4 with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of you try to acces to index greather than 4 + */ + template T Sphere::operator[](unsigned int i) const { @@ -303,31 +555,89 @@ namespace Nz return *(&x+i); } + /*! + * \brief Multiplies the radius of the sphere with a scalar + * \return A sphere where the center is the same and radius is the product of this radius and the scalar + * + * \param scale The scalar to multiply radius with + */ + template Sphere Sphere::operator*(T scalar) const { - return Sphere(x, y, z, radius*scalar); + return Sphere(x, y, z, radius * scalar); } + /*! + * \brief Multiplies the radius of other sphere with a scalar + * \return A reference to this sphere where the center is the same and radius is the product of this radius and the scalar + * + * \param scale The scalar to multiply radius with + */ + template Sphere& Sphere::operator*=(T scalar) { radius *= scalar; } + /*! + * \brief Compares the sphere to other one + * \return true if the spheres are the same + * + * \param sphere Other sphere to compare with + */ + template bool Sphere::operator==(const Sphere& sphere) const { return NumberEquals(x, sphere.x) && NumberEquals(y, sphere.y) && NumberEquals(z, sphere.z) && - NumberEquals(radius, sphere.radius); + NumberEquals(radius, sphere.radius); } + /*! + * \brief Compares the sphere to other one + * \return false if the spheres are the same + * + * \param sphere Other sphere to compare with + */ + template bool Sphere::operator!=(const Sphere& sphere) const { return !operator==(sphere); } + /*! + * \brief Shorthand for the sphere (0, 0, 0, 1) + * \return A sphere with center (0, 0, 0) and radius 1 + * + * \see MakeUnit + */ + + template + Sphere Sphere::Unit() + { + Sphere sphere; + sphere.MakeUnit(); + + return sphere; + } + + /*! + * \brief Interpolates the sphere to other one with a factor of interpolation + * \return A new sphere which is the interpolation of two spheres + * + * \param from Initial sphere + * \param to Target sphere + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * \remark With NAZARA_DEBUG, a NazaraError is thrown and Zero() is returned + * + * \see Lerp + */ + template Sphere Sphere::Lerp(const Sphere& from, const Sphere& to, T interpolation) { @@ -340,14 +650,21 @@ namespace Nz #endif Sphere sphere; - sphere.x = Lerp(from.x, to.x, interpolation); - sphere.y = Lerp(from.y, to.y, interpolation); - sphere.z = Lerp(from.z, to.z, interpolation); - sphere.radius = Lerp(from.radius, to.radius, interpolation); + sphere.x = Nz::Lerp(from.x, to.x, interpolation); + sphere.y = Nz::Lerp(from.y, to.y, interpolation); + sphere.z = Nz::Lerp(from.z, to.z, interpolation); + sphere.radius = Nz::Lerp(from.radius, to.radius, interpolation); return sphere; } + /*! + * \brief Shorthand for the sphere (0, 0, 0, 0) + * \return A sphere with center (0, 0, 0) and radius 0 + * + * \see MakeZero + */ + template Sphere Sphere::Zero() { @@ -358,6 +675,14 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param sphere The sphere to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Sphere& sphere) {