Browse Source

Math: completed documentation review.

pull/54/merge
Vladimír Vondruš 12 years ago
parent
commit
81039fc2c9
  1. 9
      src/Magnum/Math/Algorithms/GaussJordan.h
  2. 10
      src/Magnum/Math/Algorithms/GramSchmidt.h
  3. 2
      src/Magnum/Math/Algorithms/Svd.h
  4. 20
      src/Magnum/Math/Angle.h
  5. 12
      src/Magnum/Math/BoolVector.h
  6. 58
      src/Magnum/Math/Complex.h
  7. 6
      src/Magnum/Math/Constants.h
  8. 6
      src/Magnum/Math/Dual.h
  9. 47
      src/Magnum/Math/DualComplex.h
  10. 81
      src/Magnum/Math/DualQuaternion.h
  11. 14
      src/Magnum/Math/Functions.h
  12. 29
      src/Magnum/Math/Geometry/Distance.h
  13. 6
      src/Magnum/Math/Geometry/Intersection.h
  14. 2
      src/Magnum/Math/Math.h
  15. 24
      src/Magnum/Math/Matrix.h
  16. 87
      src/Magnum/Math/Matrix3.h
  17. 123
      src/Magnum/Math/Matrix4.h
  18. 91
      src/Magnum/Math/Quaternion.h
  19. 6
      src/Magnum/Math/Range.h
  20. 60
      src/Magnum/Math/RectangularMatrix.h
  21. 2
      src/Magnum/Math/Swizzle.h
  22. 6
      src/Magnum/Math/TypeTraits.h
  23. 4
      src/Magnum/Math/Unit.h
  24. 88
      src/Magnum/Math/Vector.h
  25. 28
      src/Magnum/Math/Vector2.h
  26. 9
      src/Magnum/Math/Vector3.h
  27. 3
      src/Magnum/Math/Vector4.h

9
src/Magnum/Math/Algorithms/GaussJordan.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Function Magnum::Math::Algorithms::gaussJordanInPlaceTransposed(), Magnum::Math::Algorithms::gaussJordanInPlace() * @brief Function @ref Magnum::Math::Algorithms::gaussJordanInPlaceTransposed(), @ref Magnum::Math::Algorithms::gaussJordanInPlace()
*/ */
#include "Magnum/Math/RectangularMatrix.h" #include "Magnum/Math/RectangularMatrix.h"
@ -42,7 +42,8 @@ namespace Magnum { namespace Math { namespace Algorithms {
As Gauss-Jordan elimination works on rows and matrices in OpenGL are As Gauss-Jordan elimination works on rows and matrices in OpenGL are
column-major, it is more efficient to operate on transposed matrices and treat column-major, it is more efficient to operate on transposed matrices and treat
columns as rows. See also gaussJordanInPlace() which works with non-transposed matrices. columns as rows. See also @ref gaussJordanInPlace() which works with
non-transposed matrices.
The function eliminates matrix @p a and solves @p t in place. For efficiency The function eliminates matrix @p a and solves @p t in place. For efficiency
reasons, only pure Gaussian elimination is done on @p a and the final reasons, only pure Gaussian elimination is done on @p a and the final
@ -94,8 +95,8 @@ template<std::size_t size, std::size_t rows, class T> bool gaussJordanInPlaceTra
/** /**
@brief In-place Gauss-Jordan elimination @brief In-place Gauss-Jordan elimination
Transposes the matrices, calls gaussJordanInPlaceTransposed() on them and then Transposes the matrices, calls @ref gaussJordanInPlaceTransposed() on them and
transposes them back. then transposes them back.
*/ */
template<std::size_t size, std::size_t cols, class T> bool gaussJordanInPlace(RectangularMatrix<size, size, T>& a, RectangularMatrix<cols, size, T>& t) { template<std::size_t size, std::size_t cols, class T> bool gaussJordanInPlace(RectangularMatrix<size, size, T>& a, RectangularMatrix<cols, size, T>& t) {
a = a.transposed(); a = a.transposed();

10
src/Magnum/Math/Algorithms/GramSchmidt.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Function Magnum::Math::Algorithms::gramSchmidtOrthogonalizeInPlace(), Magnum::Math::Algorithms::gramSchmidtOrthogonalize(), Magnum::Math::Algorithms::gramSchmidtOrthonormalizeInPlace(), Magnum::Math::Algorithms::gramSchmidtOrthonormalize() * @brief Function @ref Magnum::Math::Algorithms::gramSchmidtOrthogonalizeInPlace(), @ref Magnum::Math::Algorithms::gramSchmidtOrthogonalize(), @ref Magnum::Math::Algorithms::gramSchmidtOrthonormalizeInPlace(), @ref Magnum::Math::Algorithms::gramSchmidtOrthonormalize()
*/ */
#include "Magnum/Math/RectangularMatrix.h" #include "Magnum/Math/RectangularMatrix.h"
@ -48,8 +48,8 @@ template<std::size_t cols, std::size_t rows, class T> void gramSchmidtOrthogonal
/** /**
@brief Gram-Schmidt matrix orthogonalization @brief Gram-Schmidt matrix orthogonalization
Unlike gramSchmidtOrthogonalizeInPlace() returns the modified matrix instead Unlike @ref gramSchmidtOrthogonalizeInPlace() returns the modified matrix
of performing the orthogonalization in-place. instead of performing the orthogonalization in-place.
*/ */
template<std::size_t cols, std::size_t rows, class T> RectangularMatrix<cols, rows, T> gramSchmidtOrthogonalize(RectangularMatrix<cols, rows, T> matrix) { template<std::size_t cols, std::size_t rows, class T> RectangularMatrix<cols, rows, T> gramSchmidtOrthogonalize(RectangularMatrix<cols, rows, T> matrix) {
gramSchmidtOrthogonalizeInPlace(matrix); gramSchmidtOrthogonalizeInPlace(matrix);
@ -72,8 +72,8 @@ template<std::size_t cols, std::size_t rows, class T> void gramSchmidtOrthonorma
/** /**
@brief Gram-Schmidt matrix orthonormalization @brief Gram-Schmidt matrix orthonormalization
Unlike gramSchmidtOrthonormalizeInPlace() returns the modified matrix instead Unlike @ref gramSchmidtOrthonormalizeInPlace() returns the modified matrix
of performing the orthonormalization in-place. instead of performing the orthonormalization in-place.
*/ */
template<std::size_t cols, std::size_t rows, class T> RectangularMatrix<cols, rows, T> gramSchmidtOrthonormalize(RectangularMatrix<cols, rows, T> matrix) { template<std::size_t cols, std::size_t rows, class T> RectangularMatrix<cols, rows, T> gramSchmidtOrthonormalize(RectangularMatrix<cols, rows, T> matrix) {
gramSchmidtOrthonormalizeInPlace(matrix); gramSchmidtOrthonormalizeInPlace(matrix);

2
src/Magnum/Math/Algorithms/Svd.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Function Magnum::Math::Algorithms::svd() * @brief Function @ref Magnum::Math::Algorithms::svd()
*/ */
#include <tuple> #include <tuple>

20
src/Magnum/Math/Angle.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Deg, Magnum::Math::Rad and related operators. * @brief Class @ref Magnum::Math::Deg, @ref Magnum::Math::Rad and related operators.
*/ */
#include <Corrade/configure.h> #include <Corrade/configure.h>
@ -119,7 +119,7 @@ std::sin(Float(Rad<Float>(b)); // required explicit conversion hints to user
// (i.e., conversion to radians) // (i.e., conversion to radians)
@endcode @endcode
@see Magnum::Deg, Magnum::Degd @see @ref Magnum::Deg, @ref Magnum::Degd
*/ */
template<class T> class Deg: public Unit<Deg, T> { template<class T> class Deg: public Unit<Deg, T> {
public: public:
@ -157,7 +157,8 @@ Double cosine = Math::cos(60.0_deg); // cosine = 0.5
Double cosine = Math::cos(1.047_rad); // cosine = 0.5 Double cosine = Math::cos(1.047_rad); // cosine = 0.5
@endcode @endcode
@see Magnum::operator""_deg(), operator""_degf(), operator""_rad() @see Magnum::operator""_deg(), operator""_degf(), operator""_rad()
@note Not available on GCC < 4.7. Use Deg::Deg(T) instead. @todoc Make references explicit when Doxygen can link to operator""
@note Not available on GCC < 4.7. Use @ref Deg::Deg(T) instead.
@requires_gl Only single-precision types are available in OpenGL ES. @requires_gl Only single-precision types are available in OpenGL ES.
*/ */
constexpr Deg<Double> operator "" _deg(long double value) { return Deg<Double>(value); } constexpr Deg<Double> operator "" _deg(long double value) { return Deg<Double>(value); }
@ -172,7 +173,8 @@ Float tangent = Math::tan(60.0_degf); // tangent = 1.732f
Float tangent = Math::tan(1.047_radf); // tangent = 1.732f Float tangent = Math::tan(1.047_radf); // tangent = 1.732f
@endcode @endcode
@see Magnum::operator""_degf(), operator""_deg(), operator""_radf() @see Magnum::operator""_degf(), operator""_deg(), operator""_radf()
@note Not available on GCC < 4.7. Use Deg::Deg(T) instead. @todoc Make references explicit when Doxygen can link to operator""
@note Not available on GCC < 4.7. Use @ref Deg::Deg(T) instead.
@requires_gl Only single-precision types are available in OpenGL ES. @requires_gl Only single-precision types are available in OpenGL ES.
*/ */
constexpr Deg<Float> operator "" _degf(long double value) { return Deg<Float>(value); } constexpr Deg<Float> operator "" _degf(long double value) { return Deg<Float>(value); }
@ -181,8 +183,8 @@ constexpr Deg<Float> operator "" _degf(long double value) { return Deg<Float>(va
/** /**
@brief Angle in radians @brief Angle in radians
See Deg for more information. See @ref Deg for more information.
@see Magnum::Rad, Magnum::Radd @see @ref Magnum::Rad, @ref Magnum::Radd
*/ */
template<class T> class Rad: public Unit<Rad, T> { template<class T> class Rad: public Unit<Rad, T> {
public: public:
@ -216,7 +218,8 @@ template<class T> class Rad: public Unit<Rad, T> {
See operator""_rad() for more information. See operator""_rad() for more information.
@see Magnum::operator""_rad(), operator""_radf(), operator""_deg() @see Magnum::operator""_rad(), operator""_radf(), operator""_deg()
@note Not available on GCC < 4.7. Use Rad::Rad(T) instead. @todoc Make references explicit when Doxygen can link to operator""
@note Not available on GCC < 4.7. Use @ref Rad::Rad(T) instead.
*/ */
constexpr Rad<Double> operator "" _rad(long double value) { return Rad<Double>(value); } constexpr Rad<Double> operator "" _rad(long double value) { return Rad<Double>(value); }
#endif #endif
@ -226,7 +229,8 @@ constexpr Rad<Double> operator "" _rad(long double value) { return Rad<Double>(v
See operator""_degf() for more information. See operator""_degf() for more information.
@see Magnum::operator""_radf(), operator""_rad(), operator""_degf() @see Magnum::operator""_radf(), operator""_rad(), operator""_degf()
@note Not available on GCC < 4.7. Use Rad::Rad(T) instead. @todoc Make references explicit when Doxygen can link to operator""
@note Not available on GCC < 4.7. Use @ref Rad::Rad(T) instead.
*/ */
constexpr Rad<Float> operator "" _radf(long double value) { return Rad<Float>(value); } constexpr Rad<Float> operator "" _radf(long double value) { return Rad<Float>(value); }
#endif #endif

12
src/Magnum/Math/BoolVector.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::BoolVector * @brief Class @ref Magnum::Math::BoolVector
*/ */
#include <Corrade/configure.h> #include <Corrade/configure.h>
@ -59,8 +59,8 @@ namespace Implementation {
Result of component-wise comparison from Vector. The boolean values are stored Result of component-wise comparison from Vector. The boolean values are stored
as bits in array of unsigned bytes, unused bits have undefined value which as bits in array of unsigned bytes, unused bits have undefined value which
doesn't affect comparison or all() / none() / any() functions. See also doesn't affect comparison or @ref all() / @ref none() / @ref any() functions.
@ref matrix-vector for brief introduction. See also @ref matrix-vector for brief introduction.
*/ */
template<std::size_t size> class BoolVector { template<std::size_t size> class BoolVector {
static_assert(size != 0, "BoolVector cannot have zero elements"); static_assert(size != 0, "BoolVector cannot have zero elements");
@ -106,7 +106,8 @@ template<std::size_t size> class BoolVector {
* @brief Raw data * @brief Raw data
* @return %Array of DataSize length * @return %Array of DataSize length
* *
* @see operator[](), set() * @todoc Make reference explicit when Doxygen can link to operator[]
* @see operator[](), @ref set()
*/ */
UnsignedByte* data() { return _data; } UnsignedByte* data() { return _data; }
constexpr const UnsignedByte* data() const { return _data; } /**< @overload */ constexpr const UnsignedByte* data() const { return _data; } /**< @overload */
@ -158,6 +159,7 @@ template<std::size_t size> class BoolVector {
* @brief Bitwise AND * @brief Bitwise AND
* *
* @see operator&=() * @see operator&=()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
BoolVector<size> operator&(const BoolVector<size>& other) const { BoolVector<size> operator&(const BoolVector<size>& other) const {
return BoolVector<size>(*this) &= other; return BoolVector<size>(*this) &= other;
@ -179,6 +181,7 @@ template<std::size_t size> class BoolVector {
* @brief Bitwise OR * @brief Bitwise OR
* *
* @see operator|=() * @see operator|=()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
BoolVector<size> operator|(const BoolVector<size>& other) const { BoolVector<size> operator|(const BoolVector<size>& other) const {
return BoolVector<size>(*this) |= other; return BoolVector<size>(*this) |= other;
@ -200,6 +203,7 @@ template<std::size_t size> class BoolVector {
* @brief Bitwise XOR * @brief Bitwise XOR
* *
* @see operator^=() * @see operator^=()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
BoolVector<size> operator^(const BoolVector<size>& other) const { BoolVector<size> operator^(const BoolVector<size>& other) const {
return BoolVector<size>(*this) ^= other; return BoolVector<size>(*this) ^= other;

58
src/Magnum/Math/Complex.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Complex * @brief Class @ref Magnum::Math::Complex
*/ */
#include <limits> #include <limits>
@ -51,11 +51,11 @@ namespace Implementation {
@tparam T Data type @tparam T Data type
Represents 2D rotation. See @ref transformations for brief introduction. Represents 2D rotation. See @ref transformations for brief introduction.
@see Magnum::Complex, Magnum::Complexd, Matrix3 @see @ref Magnum::Complex, @ref Magnum::Complexd, @ref Matrix3
*/ */
template<class T> class Complex { template<class T> class Complex {
public: public:
typedef T Type; /**< @brief Underlying data type */ typedef T Type; /**< @brief Underlying data type */
/** /**
* @brief Dot product * @brief Dot product
@ -64,6 +64,7 @@ template<class T> class Complex {
* c_0 \cdot c_1 = a_0 a_1 + b_0 b_1 * c_0 \cdot c_1 = a_0 a_1 + b_0 b_1
* @f] * @f]
* @see dot() const * @see dot() const
* @todoc Explicit reference when Doxygen can handle const
*/ */
static T dot(const Complex<T>& a, const Complex<T>& b) { static T dot(const Complex<T>& a, const Complex<T>& b) {
return a._real*b._real + a._imaginary*b._imaginary; return a._real*b._real + a._imaginary*b._imaginary;
@ -75,7 +76,8 @@ template<class T> class Complex {
* Expects that both complex numbers are normalized. @f[ * Expects that both complex numbers are normalized. @f[
* \theta = acos \left( \frac{Re(c_0 \cdot c_1))}{|c_0| |c_1|} \right) = acos (a_0 a_1 + b_0 b_1) * \theta = acos \left( \frac{Re(c_0 \cdot c_1))}{|c_0| |c_1|} \right) = acos (a_0 a_1 + b_0 b_1)
* @f] * @f]
* @see isNormalized(), Quaternion::angle(), Vector::angle() * @see @ref isNormalized(), @ref Quaternion::angle(),
* @ref Vector::angle()
*/ */
static Rad<T> angle(const Complex<T>& normalizedA, const Complex<T>& normalizedB) { static Rad<T> angle(const Complex<T>& normalizedA, const Complex<T>& normalizedB) {
CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(),
@ -90,7 +92,8 @@ template<class T> class Complex {
* @f[ * @f[
* c = cos \theta + i sin \theta * c = cos \theta + i sin \theta
* @f] * @f]
* @see angle(), Matrix3::rotation(), Quaternion::rotation() * @see @ref angle(), @ref Matrix3::rotation(),
* @ref Quaternion::rotation()
*/ */
static Complex<T> rotation(Rad<T> angle) { static Complex<T> rotation(Rad<T> angle) {
return {std::cos(T(angle)), std::sin(T(angle))}; return {std::cos(T(angle)), std::sin(T(angle))};
@ -100,7 +103,8 @@ template<class T> class Complex {
* @brief Create complex number from rotation matrix * @brief Create complex number from rotation matrix
* *
* Expects that the matrix is orthogonal (i.e. pure rotation). * Expects that the matrix is orthogonal (i.e. pure rotation).
* @see toMatrix(), DualComplex::fromMatrix(), Matrix::isOrthogonal() * @see @ref toMatrix(), @ref DualComplex::fromMatrix(),
* @ref Matrix::isOrthogonal()
*/ */
static Complex<T> fromMatrix(const Matrix<2, T>& matrix) { static Complex<T> fromMatrix(const Matrix<2, T>& matrix) {
CORRADE_ASSERT(matrix.isOrthogonal(), CORRADE_ASSERT(matrix.isOrthogonal(),
@ -132,7 +136,8 @@ template<class T> class Complex {
* To be used in transformations later. @f[ * To be used in transformations later. @f[
* c = v_x + iv_y * c = v_x + iv_y
* @f] * @f]
* @see operator Vector2(), transformVector() * @see operator Vector2(), @ref transformVector()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
constexpr explicit Complex(const Vector2<T>& vector): _real(vector.x()), _imaginary(vector.y()) {} constexpr explicit Complex(const Vector2<T>& vector): _real(vector.x()), _imaginary(vector.y()) {}
@ -153,7 +158,7 @@ template<class T> class Complex {
* Complex number is normalized if it has unit length: @f[ * Complex number is normalized if it has unit length: @f[
* |c \cdot c - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon * |c \cdot c - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon
* @f] * @f]
* @see dot(), normalized() * @see @ref dot(), @ref normalized()
*/ */
bool isNormalized() const { bool isNormalized() const {
return Implementation::isNormalizedSquared(dot()); return Implementation::isNormalizedSquared(dot());
@ -182,7 +187,7 @@ template<class T> class Complex {
* @f[ * @f[
* \theta = atan2(b, a) * \theta = atan2(b, a)
* @f] * @f]
* @see rotation() * @see @ref rotation()
*/ */
Rad<T> angle() const { Rad<T> angle() const {
return Rad<T>(std::atan2(_imaginary, _real)); return Rad<T>(std::atan2(_imaginary, _real));
@ -197,8 +202,8 @@ template<class T> class Complex {
* b & a * b & a
* \end{pmatrix} * \end{pmatrix}
* @f] * @f]
* @see fromMatrix(), DualComplex::toMatrix(), * @see @ref fromMatrix(), @ref DualComplex::toMatrix(),
* Matrix3::from(const Matrix<2, T>&, const Vector2<T>&) * @ref Matrix3::from(const Matrix<2, T>&, const Vector2<T>&)
*/ */
Matrix<2, T> toMatrix() const { Matrix<2, T> toMatrix() const {
return {Vector<2, T>(_real, _imaginary), return {Vector<2, T>(_real, _imaginary),
@ -222,6 +227,7 @@ template<class T> class Complex {
* @brief Add complex number * @brief Add complex number
* *
* @see operator+=() * @see operator+=()
* @todoc Explicit reference when Doxygen can handle operators
*/ */
Complex<T> operator+(const Complex<T>& other) const { Complex<T> operator+(const Complex<T>& other) const {
return Complex<T>(*this) += other; return Complex<T>(*this) += other;
@ -255,6 +261,7 @@ template<class T> class Complex {
* @brief Subtract complex number * @brief Subtract complex number
* *
* @see operator-=() * @see operator-=()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Complex<T> operator-(const Complex<T>& other) const { Complex<T> operator-(const Complex<T>& other) const {
return Complex<T>(*this) -= other; return Complex<T>(*this) -= other;
@ -277,6 +284,7 @@ template<class T> class Complex {
* @brief Multiply with scalar * @brief Multiply with scalar
* *
* @see operator*=(T) * @see operator*=(T)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Complex<T> operator*(T scalar) const { Complex<T> operator*(T scalar) const {
return Complex<T>(*this) *= scalar; return Complex<T>(*this) *= scalar;
@ -299,6 +307,7 @@ template<class T> class Complex {
* @brief Divide with scalar * @brief Divide with scalar
* *
* @see operator/=(T) * @see operator/=(T)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Complex<T> operator/(T scalar) const { Complex<T> operator/(T scalar) const {
return Complex<T>(*this) /= scalar; return Complex<T>(*this) /= scalar;
@ -319,11 +328,12 @@ template<class T> class Complex {
/** /**
* @brief Dot product of the complex number * @brief Dot product of the complex number
* *
* Should be used instead of length() for comparing complex number length * Should be used instead of @ref length() for comparing complex number
* with other values, because it doesn't compute the square root. @f[ * length with other values, because it doesn't compute the square
* root. @f[
* c \cdot c = a^2 + b^2 * c \cdot c = a^2 + b^2
* @f] * @f]
* @see dot(const Complex&, const Complex&), isNormalized() * @see @ref dot(const Complex&, const Complex&), @ref isNormalized()
*/ */
T dot() const { T dot() const {
return dot(*this, *this); return dot(*this, *this);
@ -332,11 +342,11 @@ template<class T> class Complex {
/** /**
* @brief %Complex number length * @brief %Complex number length
* *
* See also dot() const which is faster for comparing length with other * See also @ref dot() const which is faster for comparing length with
* values. @f[ * other values. @f[
* |c| = \sqrt{c \cdot c} * |c| = \sqrt{c \cdot c}
* @f] * @f]
* @see isNormalized() * @see @ref isNormalized()
*/ */
T length() const { T length() const {
/** @todo Remove when newlib has this fixed */ /** @todo Remove when newlib has this fixed */
@ -350,7 +360,7 @@ template<class T> class Complex {
/** /**
* @brief Normalized complex number (of unit length) * @brief Normalized complex number (of unit length)
* *
* @see isNormalized() * @see @ref isNormalized()
*/ */
Complex<T> normalized() const { Complex<T> normalized() const {
return (*this)/length(); return (*this)/length();
@ -370,7 +380,7 @@ template<class T> class Complex {
/** /**
* @brief Inverted complex number * @brief Inverted complex number
* *
* See invertedNormalized() which is faster for normalized * See @ref invertedNormalized() which is faster for normalized
* complex numbers. @f[ * complex numbers. @f[
* c^{-1} = \frac{c^*}{|c|^2} = \frac{c^*}{c \cdot c} * c^{-1} = \frac{c^*}{|c|^2} = \frac{c^*}{c \cdot c}
* @f] * @f]
@ -382,11 +392,11 @@ template<class T> class Complex {
/** /**
* @brief Inverted normalized complex number * @brief Inverted normalized complex number
* *
* Equivalent to conjugated(). Expects that the complex number is * Equivalent to @ref conjugated(). Expects that the complex number is
* normalized. @f[ * normalized. @f[
* c^{-1} = \frac{c^*}{c \cdot c} = c^* * c^{-1} = \frac{c^*}{c \cdot c} = c^*
* @f] * @f]
* @see isNormalized(), inverted() * @see @ref isNormalized(), @ref inverted()
*/ */
Complex<T> invertedNormalized() const { Complex<T> invertedNormalized() const {
CORRADE_ASSERT(isNormalized(), CORRADE_ASSERT(isNormalized(),
@ -401,7 +411,9 @@ template<class T> class Complex {
* @f[ * @f[
* v' = c v = c (v_x + iv_y) * v' = c v = c (v_x + iv_y)
* @f] * @f]
* @see Complex(const Vector2&), operator Vector2(), Matrix3::transformVector() * @see @ref Complex(const Vector2<T>&), operator Vector2(),
* @ref Matrix3::transformVector()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector2<T> transformVector(const Vector2<T>& vector) const { Vector2<T> transformVector(const Vector2<T>& vector) const {
return Vector2<T>((*this)*Complex<T>(vector)); return Vector2<T>((*this)*Complex<T>(vector));
@ -415,6 +427,7 @@ template<class T> class Complex {
@brief Multiply scalar with complex @brief Multiply scalar with complex
Same as Complex::operator*(T) const. Same as Complex::operator*(T) const.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<class T> inline Complex<T> operator*(T scalar, const Complex<T>& complex) { template<class T> inline Complex<T> operator*(T scalar, const Complex<T>& complex) {
return complex*scalar; return complex*scalar;
@ -427,6 +440,7 @@ template<class T> inline Complex<T> operator*(T scalar, const Complex<T>& comple
\frac t c = \frac t a + i \frac t b \frac t c = \frac t a + i \frac t b
@f] @f]
@see Complex::operator/() @see Complex::operator/()
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<class T> inline Complex<T> operator/(T scalar, const Complex<T>& complex) { template<class T> inline Complex<T> operator/(T scalar, const Complex<T>& complex) {
return {scalar/complex.real(), scalar/complex.imaginary()}; return {scalar/complex.real(), scalar/complex.imaginary()};

6
src/Magnum/Math/Constants.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Constants * @brief Class @ref Magnum::Math::Constants
*/ */
#include "Magnum/Types.h" #include "Magnum/Types.h"
@ -36,7 +36,7 @@ namespace Magnum { namespace Math {
/** /**
@brief Numeric constants @brief Numeric constants
@see Magnum::Constants, Magnum::Constantsd @see @ref Magnum::Constants, @ref Magnum::Constantsd
*/ */
template<class T> struct Constants { template<class T> struct Constants {
Constants() = delete; Constants() = delete;
@ -46,7 +46,7 @@ template<class T> struct Constants {
/** /**
* @brief Pi * @brief Pi
* *
* @see Deg, Rad * @see @ref Deg, @ref Rad
*/ */
static constexpr T pi(); static constexpr T pi();

6
src/Magnum/Math/Dual.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Dual * @brief Class @ref Magnum::Math::Dual
*/ */
#include <cmath> #include <cmath>
@ -96,6 +96,7 @@ template<class T> class Dual {
* @brief Add dual number * @brief Add dual number
* *
* @see operator+=() * @see operator+=()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Dual<T> operator+(const Dual<T>& other) const { Dual<T> operator+(const Dual<T>& other) const {
return Dual<T>(*this)+=other; return Dual<T>(*this)+=other;
@ -129,6 +130,7 @@ template<class T> class Dual {
* @brief Subtract dual number * @brief Subtract dual number
* *
* @see operator-=() * @see operator-=()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Dual<T> operator-(const Dual<T>& other) const { Dual<T> operator-(const Dual<T>& other) const {
return Dual<T>(*this)-=other; return Dual<T>(*this)-=other;
@ -213,7 +215,7 @@ template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug deb
@f[ @f[
\sqrt{\hat a} = \sqrt{a_0} + \epsilon \frac{a_\epsilon}{2 \sqrt{a_0}} \sqrt{\hat a} = \sqrt{a_0} + \epsilon \frac{a_\epsilon}{2 \sqrt{a_0}}
@f] @f]
@see Math::sqrt(const T&) @see @ref Math::sqrt(const T&)
*/ */
template<class T> Dual<T> sqrt(const Dual<T>& dual) { template<class T> Dual<T> sqrt(const Dual<T>& dual) {
T sqrt0 = std::sqrt(dual.real()); T sqrt0 = std::sqrt(dual.real());

47
src/Magnum/Math/DualComplex.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::DualComplex * @brief Class @ref Magnum::Math::DualComplex
*/ */
#include "Magnum/Math/Complex.h" #include "Magnum/Math/Complex.h"
@ -41,7 +41,8 @@ namespace Magnum { namespace Math {
Represents 2D rotation and translation. See @ref transformations for brief Represents 2D rotation and translation. See @ref transformations for brief
introduction. introduction.
@see Magnum::DualComplex, Magnum::DualComplexd, Dual, Complex, Matrix3 @see @ref Magnum::DualComplex, @ref Magnum::DualComplexd, @ref Dual,
@ref Complex, @ref Matrix3
@todo Can this be done similarly as in dual quaternions? It sort of works, but @todo Can this be done similarly as in dual quaternions? It sort of works, but
the math beneath is weird. the math beneath is weird.
*/ */
@ -56,8 +57,8 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[ * @f[
* \hat c = (cos \theta + i sin \theta) + \epsilon (0 + i0) * \hat c = (cos \theta + i sin \theta) + \epsilon (0 + i0)
* @f] * @f]
* @see angle(), Complex::rotation(), Matrix3::rotation(), * @see @ref Complex::rotation(), @ref Matrix3::rotation(),
* DualQuaternion::rotation() * @ref DualQuaternion::rotation()
*/ */
static DualComplex<T> rotation(Rad<T> angle) { static DualComplex<T> rotation(Rad<T> angle) {
return {Complex<T>::rotation(angle), {{}, {}}}; return {Complex<T>::rotation(angle), {{}, {}}};
@ -70,8 +71,11 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[ * @f[
* \hat c = (0 + i1) + \epsilon (v_x + iv_y) * \hat c = (0 + i1) + \epsilon (v_x + iv_y)
* @f] * @f]
* @see translation() const, Matrix3::translation(const Vector2&), * @see translation() const,
* DualQuaternion::translation(), Vector2::xAxis(), Vector2::yAxis() * @ref Matrix3::translation(const Vector2<T>&),
* @ref DualQuaternion::translation(), @ref Vector2::xAxis(),
* @ref Vector2::yAxis()
* @todoc Explicit reference when Doxygen can handle const
*/ */
static DualComplex<T> translation(const Vector2<T>& vector) { static DualComplex<T> translation(const Vector2<T>& vector) {
return {{}, {vector.x(), vector.y()}}; return {{}, {vector.x(), vector.y()}};
@ -81,8 +85,8 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @brief Create dual complex number from rotation matrix * @brief Create dual complex number from rotation matrix
* *
* Expects that the matrix represents rigid transformation. * Expects that the matrix represents rigid transformation.
* @see toMatrix(), Complex::fromMatrix(), * @see @ref toMatrix(), @ref Complex::fromMatrix(),
* Matrix3::isRigidTransformation() * @ref Matrix3::isRigidTransformation()
*/ */
static DualComplex<T> fromMatrix(const Matrix3<T>& matrix) { static DualComplex<T> fromMatrix(const Matrix3<T>& matrix) {
CORRADE_ASSERT(matrix.isRigidTransformation(), CORRADE_ASSERT(matrix.isRigidTransformation(),
@ -136,7 +140,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* Dual complex number is normalized if its real part has unit length: @f[ * Dual complex number is normalized if its real part has unit length: @f[
* |c_0|^2 = |c_0| = 1 * |c_0|^2 = |c_0| = 1
* @f] * @f]
* @see Complex::dot(), normalized() * @see @ref Complex::dot(), @ref normalized()
* @todoc Improve the equation as in Complex::isNormalized() * @todoc Improve the equation as in Complex::isNormalized()
*/ */
bool isNormalized() const { bool isNormalized() const {
@ -146,7 +150,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
/** /**
* @brief Rotation part of dual complex number * @brief Rotation part of dual complex number
* *
* @see Complex::angle() * @see @ref Complex::angle()
*/ */
constexpr Complex<T> rotation() const { constexpr Complex<T> rotation() const {
return Dual<Complex<T>>::real(); return Dual<Complex<T>>::real();
@ -158,7 +162,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[ * @f[
* \boldsymbol a = (c_\epsilon c_0^*) * \boldsymbol a = (c_\epsilon c_0^*)
* @f] * @f]
* @see translation(const Vector2&) * @see @ref translation(const Vector2<T>&)
*/ */
Vector2<T> translation() const { Vector2<T> translation() const {
return Vector2<T>(Dual<Complex<T>>::dual()); return Vector2<T>(Dual<Complex<T>>::dual());
@ -167,7 +171,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
/** /**
* @brief Convert dual complex number to transformation matrix * @brief Convert dual complex number to transformation matrix
* *
* @see fromMatrix(), Complex::toMatrix() * @see @ref fromMatrix(), @ref Complex::toMatrix()
*/ */
Matrix3<T> toMatrix() const { Matrix3<T> toMatrix() const {
return Matrix3<T>::from(Dual<Complex<T>>::real().toMatrix(), translation()); return Matrix3<T>::from(Dual<Complex<T>>::real().toMatrix(), translation());
@ -191,7 +195,8 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[ * @f[
* \hat c^* = c^*_0 + c^*_\epsilon * \hat c^* = c^*_0 + c^*_\epsilon
* @f] * @f]
* @see dualConjugated(), conjugated(), Complex::conjugated() * @see @ref dualConjugated(), @ref conjugated(),
* @ref Complex::conjugated()
*/ */
DualComplex<T> complexConjugated() const { DualComplex<T> complexConjugated() const {
return {Dual<Complex<T>>::real().conjugated(), Dual<Complex<T>>::dual().conjugated()}; return {Dual<Complex<T>>::real().conjugated(), Dual<Complex<T>>::dual().conjugated()};
@ -203,7 +208,8 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[ * @f[
* \overline{\hat c} = c_0 - \epsilon c_\epsilon * \overline{\hat c} = c_0 - \epsilon c_\epsilon
* @f] * @f]
* @see complexConjugated(), conjugated(), Dual::conjugated() * @see @ref complexConjugated(), @ref conjugated(),
* @ref Dual::conjugated()
*/ */
DualComplex<T> dualConjugated() const { DualComplex<T> dualConjugated() const {
return Dual<Complex<T>>::conjugated(); return Dual<Complex<T>>::conjugated();
@ -215,8 +221,8 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* Both complex and dual conjugation. @f[ * Both complex and dual conjugation. @f[
* \overline{\hat c^*} = c^*_0 - \epsilon c^*_\epsilon = c^*_0 + \epsilon(-a_\epsilon + ib_\epsilon) * \overline{\hat c^*} = c^*_0 - \epsilon c^*_\epsilon = c^*_0 + \epsilon(-a_\epsilon + ib_\epsilon)
* @f] * @f]
* @see complexConjugated(), dualConjugated(), Complex::conjugated(), * @see @ref complexConjugated(), @ref dualConjugated(),
* Dual::conjugated() * @ref Complex::conjugated(), @ref Dual::conjugated()
*/ */
DualComplex<T> conjugated() const { DualComplex<T> conjugated() const {
return {Dual<Complex<T>>::real().conjugated(), {-Dual<Complex<T>>::dual().real(), Dual<Complex<T>>::dual().imaginary()}}; return {Dual<Complex<T>>::real().conjugated(), {-Dual<Complex<T>>::dual().real(), Dual<Complex<T>>::dual().imaginary()}};
@ -254,7 +260,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[ * @f[
* c' = \frac{c_0}{|c_0|} * c' = \frac{c_0}{|c_0|}
* @f] * @f]
* @see isNormalized() * @see @ref isNormalized()
* @todo can this be done similarly to dual quaternions? * @todo can this be done similarly to dual quaternions?
*/ */
DualComplex<T> normalized() const { DualComplex<T> normalized() const {
@ -280,7 +286,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* Expects that the complex number is normalized. @f[ * Expects that the complex number is normalized. @f[
* \hat c^{-1} = c_0^{-1} - \epsilon c_\epsilon = c_0^* - \epsilon c_\epsilon * \hat c^{-1} = c_0^{-1} - \epsilon c_\epsilon = c_0^* - \epsilon c_\epsilon
* @f] * @f]
* @see isNormalized(), inverted() * @see @ref isNormalized(), @ref inverted()
* @todo can this be done similarly to dual quaternions? * @todo can this be done similarly to dual quaternions?
*/ */
DualComplex<T> invertedNormalized() const { DualComplex<T> invertedNormalized() const {
@ -294,8 +300,9 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* complex number. @f[ * complex number. @f[
* v' = \hat c v = \hat c ((0 + i) + \epsilon(v_x + iv_y)) * v' = \hat c v = \hat c ((0 + i) + \epsilon(v_x + iv_y))
* @f] * @f]
* @see DualComplex(const Vector2&), dual(), Matrix3::transformPoint(), * @see @ref DualComplex(const Vector2<T>&), @ref dual(),
* Complex::transformVector(), DualQuaternion::transformPoint() * @ref Matrix3::transformPoint(), @ref Complex::transformVector(),
* @ref DualQuaternion::transformPoint()
*/ */
Vector2<T> transformPoint(const Vector2<T>& vector) const { Vector2<T> transformPoint(const Vector2<T>& vector) const {
return Vector2<T>(((*this)*DualComplex<T>(vector)).dual()); return Vector2<T>(((*this)*DualComplex<T>(vector)).dual());

81
src/Magnum/Math/DualQuaternion.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::DualQuaternion * @brief Class @ref Magnum::Math::DualQuaternion
*/ */
#include "Magnum/Math/Dual.h" #include "Magnum/Math/Dual.h"
@ -41,7 +41,8 @@ namespace Magnum { namespace Math {
Represents 3D rotation and translation. See @ref transformations for brief Represents 3D rotation and translation. See @ref transformations for brief
introduction. introduction.
@see Magnum::DualQuaternion, Magnum::DualQuaterniond, Dual, Quaternion, Matrix4 @see @ref Magnum::DualQuaternion, @ref Magnum::DualQuaterniond, @ref Dual,
@ref Quaternion, @ref Matrix4
*/ */
template<class T> class DualQuaternion: public Dual<Quaternion<T>> { template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
public: public:
@ -55,9 +56,11 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* Expects that the rotation axis is normalized. @f[ * Expects that the rotation axis is normalized. @f[
* \hat q = [\boldsymbol a \cdot sin \frac \theta 2, cos \frac \theta 2] + \epsilon [\boldsymbol 0, 0] * \hat q = [\boldsymbol a \cdot sin \frac \theta 2, cos \frac \theta 2] + \epsilon [\boldsymbol 0, 0]
* @f] * @f]
* @see rotation() const, Quaternion::rotation(), Matrix4::rotation(), * @see rotation() const, @ref Quaternion::rotation(),
* DualComplex::rotation(), Vector3::xAxis(), Vector3::yAxis(), * @ref Matrix4::rotation(), @ref DualComplex::rotation(),
* Vector3::zAxis(), Vector::isNormalized() * @ref Vector3::xAxis(), @ref Vector3::yAxis(),
* @ref Vector3::zAxis(), @ref Vector::isNormalized()
* @todoc Explicit reference when Doxygen can handle const
*/ */
static DualQuaternion<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) { static DualQuaternion<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) {
return {Quaternion<T>::rotation(angle, normalizedAxis), {{}, T(0)}}; return {Quaternion<T>::rotation(angle, normalizedAxis), {{}, T(0)}};
@ -72,9 +75,11 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f[ * @f[
* \hat q = [\boldsymbol 0, 1] + \epsilon [\frac{\boldsymbol v}{2}, 0] * \hat q = [\boldsymbol 0, 1] + \epsilon [\frac{\boldsymbol v}{2}, 0]
* @f] * @f]
* @see translation() const, Matrix4::translation(const Vector3&), * @see translation() const,
* DualComplex::translation(), Vector3::xAxis(), Vector3::yAxis(), * @ref Matrix4::translation(const Vector3<T>&),
* Vector3::zAxis() * @ref DualComplex::translation(), @ref Vector3::xAxis(),
* @ref Vector3::yAxis(), @ref Vector3::zAxis()
* @todoc Explicit reference when Doxygen can handle const
*/ */
static DualQuaternion<T> translation(const Vector3<T>& vector) { static DualQuaternion<T> translation(const Vector3<T>& vector) {
return {{}, {vector/T(2), T(0)}}; return {{}, {vector/T(2), T(0)}};
@ -84,8 +89,8 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @brief Create dual quaternion from transformation matrix * @brief Create dual quaternion from transformation matrix
* *
* Expects that the matrix represents rigid transformation. * Expects that the matrix represents rigid transformation.
* @see toMatrix(), Quaternion::fromMatrix(), * @see @ref toMatrix(), @ref Quaternion::fromMatrix(),
* Matrix4::isRigidTransformation() * @ref Matrix4::isRigidTransformation()
*/ */
static DualQuaternion<T> fromMatrix(const Matrix4<T>& matrix) { static DualQuaternion<T> fromMatrix(const Matrix4<T>& matrix) {
CORRADE_ASSERT(matrix.isRigidTransformation(), CORRADE_ASSERT(matrix.isRigidTransformation(),
@ -124,7 +129,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* To be used in transformations later. @f[ * To be used in transformations later. @f[
* \hat q = [\boldsymbol 0, 1] + \epsilon [\boldsymbol v, 0] * \hat q = [\boldsymbol 0, 1] + \epsilon [\boldsymbol v, 0]
* @f] * @f]
* @see transformPointNormalized() * @see @ref transformPointNormalized()
* @todoc Remove workaround when Doxygen is predictable * @todoc Remove workaround when Doxygen is predictable
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -142,7 +147,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* Dual quaternion is normalized if it has unit length: @f[ * Dual quaternion is normalized if it has unit length: @f[
* |\hat q|^2 = |\hat q| = 1 + \epsilon 0 * |\hat q|^2 = |\hat q| = 1 + \epsilon 0
* @f] * @f]
* @see lengthSquared(), normalized() * @see @ref lengthSquared(), @ref normalized()
* @todoc Improve the equation as in Quaternion::isNormalized() * @todoc Improve the equation as in Quaternion::isNormalized()
*/ */
bool isNormalized() const { bool isNormalized() const {
@ -156,7 +161,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/** /**
* @brief Rotation part of unit dual quaternion * @brief Rotation part of unit dual quaternion
* *
* @see Quaternion::angle(), Quaternion::axis() * @see @ref Quaternion::angle(), @ref Quaternion::axis()
*/ */
constexpr Quaternion<T> rotation() const { constexpr Quaternion<T> rotation() const {
return Dual<Quaternion<T>>::real(); return Dual<Quaternion<T>>::real();
@ -168,7 +173,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f[ * @f[
* \boldsymbol a = 2 (q_\epsilon q_0^*)_V * \boldsymbol a = 2 (q_\epsilon q_0^*)_V
* @f] * @f]
* @see translation(const Vector3&) * @see @ref translation(const Vector3<T>&)
*/ */
Vector3<T> translation() const { Vector3<T> translation() const {
return (Dual<Quaternion<T>>::dual()*Dual<Quaternion<T>>::real().conjugated()).vector()*T(2); return (Dual<Quaternion<T>>::dual()*Dual<Quaternion<T>>::real().conjugated()).vector()*T(2);
@ -177,7 +182,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/** /**
* @brief Convert dual quaternion to transformation matrix * @brief Convert dual quaternion to transformation matrix
* *
* @see fromMatrix(), Quaternion::toMatrix() * @see @ref fromMatrix(), @ref Quaternion::toMatrix()
*/ */
Matrix4<T> toMatrix() const { Matrix4<T> toMatrix() const {
return Matrix4<T>::from(Dual<Quaternion<T>>::real().toMatrix(), translation()); return Matrix4<T>::from(Dual<Quaternion<T>>::real().toMatrix(), translation());
@ -189,7 +194,8 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f[ * @f[
* \hat q^* = q_0^* + q_\epsilon^* * \hat q^* = q_0^* + q_\epsilon^*
* @f] * @f]
* @see dualConjugated(), conjugated(), Quaternion::conjugated() * @see @ref dualConjugated(), @ref conjugated(),
* @ref Quaternion::conjugated()
*/ */
DualQuaternion<T> quaternionConjugated() const { DualQuaternion<T> quaternionConjugated() const {
return {Dual<Quaternion<T>>::real().conjugated(), Dual<Quaternion<T>>::dual().conjugated()}; return {Dual<Quaternion<T>>::real().conjugated(), Dual<Quaternion<T>>::dual().conjugated()};
@ -201,7 +207,8 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f[ * @f[
* \overline{\hat q} = q_0 - \epsilon q_\epsilon * \overline{\hat q} = q_0 - \epsilon q_\epsilon
* @f] * @f]
* @see quaternionConjugated(), conjugated(), Dual::conjugated() * @see @ref quaternionConjugated(), @ref conjugated(),
* @ref Dual::conjugated()
*/ */
DualQuaternion<T> dualConjugated() const { DualQuaternion<T> dualConjugated() const {
return Dual<Quaternion<T>>::conjugated(); return Dual<Quaternion<T>>::conjugated();
@ -213,8 +220,8 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* Both quaternion and dual conjugation. @f[ * Both quaternion and dual conjugation. @f[
* \overline{\hat q^*} = q_0^* - \epsilon q_\epsilon^* = q_0^* + \epsilon [\boldsymbol q_{V \epsilon}, -q_{S \epsilon}] * \overline{\hat q^*} = q_0^* - \epsilon q_\epsilon^* = q_0^* + \epsilon [\boldsymbol q_{V \epsilon}, -q_{S \epsilon}]
* @f] * @f]
* @see quaternionConjugated(), dualConjugated(), Quaternion::conjugated(), * @see @ref quaternionConjugated(), @ref dualConjugated(),
* Dual::conjugated() * @ref Quaternion::conjugated(), @ref Dual::conjugated()
*/ */
DualQuaternion<T> conjugated() const { DualQuaternion<T> conjugated() const {
return {Dual<Quaternion<T>>::real().conjugated(), {Dual<Quaternion<T>>::dual().vector(), -Dual<Quaternion<T>>::dual().scalar()}}; return {Dual<Quaternion<T>>::real().conjugated(), {Dual<Quaternion<T>>::dual().vector(), -Dual<Quaternion<T>>::dual().scalar()}};
@ -223,8 +230,9 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/** /**
* @brief %Dual quaternion length squared * @brief %Dual quaternion length squared
* *
* Should be used instead of length() for comparing dual quaternion * Should be used instead of @ref length() for comparing dual
* length with other values, because it doesn't compute the square root. @f[ * quaternion length with other values, because it doesn't compute the
* square root. @f[
* |\hat q|^2 = \sqrt{\hat q^* \hat q}^2 = q_0 \cdot q_0 + \epsilon 2 (q_0 \cdot q_\epsilon) * |\hat q|^2 = \sqrt{\hat q^* \hat q}^2 = q_0 \cdot q_0 + \epsilon 2 (q_0 \cdot q_\epsilon)
* @f] * @f]
*/ */
@ -235,7 +243,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/** /**
* @brief %Dual quaternion length * @brief %Dual quaternion length
* *
* See lengthSquared() which is faster for comparing length with other * See @ref lengthSquared() which is faster for comparing length with other
* values. @f[ * values. @f[
* |\hat q| = \sqrt{\hat q^* \hat q} = |q_0| + \epsilon \frac{q_0 \cdot q_\epsilon}{|q_0|} * |\hat q| = \sqrt{\hat q^* \hat q} = |q_0| + \epsilon \frac{q_0 \cdot q_\epsilon}{|q_0|}
* @f] * @f]
@ -247,7 +255,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/** /**
* @brief Normalized dual quaternion (of unit length) * @brief Normalized dual quaternion (of unit length)
* *
* @see isNormalized() * @see @ref isNormalized()
*/ */
DualQuaternion<T> normalized() const { DualQuaternion<T> normalized() const {
return (*this)/length(); return (*this)/length();
@ -256,7 +264,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/** /**
* @brief Inverted dual quaternion * @brief Inverted dual quaternion
* *
* See invertedNormalized() which is faster for normalized dual * See @ref invertedNormalized() which is faster for normalized dual
* quaternions. @f[ * quaternions. @f[
* \hat q^{-1} = \frac{\hat q^*}{|\hat q|^2} * \hat q^{-1} = \frac{\hat q^*}{|\hat q|^2}
* @f] * @f]
@ -268,11 +276,11 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/** /**
* @brief Inverted normalized dual quaternion * @brief Inverted normalized dual quaternion
* *
* Equivalent to quaternionConjugated(). Expects that the quaternion is * Equivalent to @ref quaternionConjugated(). Expects that the
* normalized. @f[ * quaternion is normalized. @f[
* \hat q^{-1} = \frac{\hat q^*}{|\hat q|^2} = \hat q^* * \hat q^{-1} = \frac{\hat q^*}{|\hat q|^2} = \hat q^*
* @f] * @f]
* @see isNormalized(), inverted() * @see @ref isNormalized(), @ref inverted()
*/ */
DualQuaternion<T> invertedNormalized() const { DualQuaternion<T> invertedNormalized() const {
CORRADE_ASSERT(isNormalized(), CORRADE_ASSERT(isNormalized(),
@ -283,12 +291,14 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/** /**
* @brief Rotate and translate point with dual quaternion * @brief Rotate and translate point with dual quaternion
* *
* See transformPointNormalized(), which is faster for normalized dual * See @ref transformPointNormalized(), which is faster for normalized
* quaternions. @f[ * dual quaternions. @f[
* v' = \hat q v \overline{\hat q^{-1}} = \hat q ([\boldsymbol 0, 1] + \epsilon [\boldsymbol v, 0]) \overline{\hat q^{-1}} * v' = \hat q v \overline{\hat q^{-1}} = \hat q ([\boldsymbol 0, 1] + \epsilon [\boldsymbol v, 0]) \overline{\hat q^{-1}}
* @f] * @f]
* @see DualQuaternion(const Vector3&), dual(), Matrix4::transformPoint(), * @see @ref DualQuaternion(const Vector3<T>&), @ref dual(),
* Quaternion::transformVector(), DualComplex::transformPoint() * @ref Matrix4::transformPoint(),
* @ref Quaternion::transformVector(),
* @ref DualComplex::transformPoint()
*/ */
Vector3<T> transformPoint(const Vector3<T>& vector) const { Vector3<T> transformPoint(const Vector3<T>& vector) const {
return ((*this)*DualQuaternion<T>(vector)*inverted().dualConjugated()).dual().vector(); return ((*this)*DualQuaternion<T>(vector)*inverted().dualConjugated()).dual().vector();
@ -297,13 +307,14 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/** /**
* @brief Rotate and translate point with normalized dual quaternion * @brief Rotate and translate point with normalized dual quaternion
* *
* Faster alternative to transformPoint(), expects that the dual * Faster alternative to @ref transformPoint(), expects that the dual
* quaternion is normalized. @f[ * quaternion is normalized. @f[
* v' = \hat q v \overline{\hat q^{-1}} = \hat q v \overline{\hat q^*} = \hat q ([\boldsymbol 0, 1] + \epsilon [\boldsymbol v, 0]) \overline{\hat q^*} * v' = \hat q v \overline{\hat q^{-1}} = \hat q v \overline{\hat q^*} = \hat q ([\boldsymbol 0, 1] + \epsilon [\boldsymbol v, 0]) \overline{\hat q^*}
* @f] * @f]
* @see isNormalized(), DualQuaternion(const Vector3&), dual(), * @see @ref isNormalized(), @ref DualQuaternion(const Vector3<T>&),
* Matrix4::transformPoint(), Quaternion::transformVectorNormalized(), * @ref dual(), @ref Matrix4::transformPoint(),
* DualComplex::transformPointNormalized() * @ref Quaternion::transformVectorNormalized(),
* @ref DualComplex::transformPoint()
*/ */
Vector3<T> transformPointNormalized(const Vector3<T>& vector) const { Vector3<T> transformPointNormalized(const Vector3<T>& vector) const {
CORRADE_ASSERT(isNormalized(), CORRADE_ASSERT(isNormalized(),

14
src/Magnum/Math/Functions.h

@ -67,7 +67,7 @@ template<UnsignedInt exponent, class T> constexpr T pow(T base) {
* @brief Base-2 integral logarithm * @brief Base-2 integral logarithm
* *
* Returns integral logarithm of given number with base `2`. * Returns integral logarithm of given number with base `2`.
* @see log() * @see @ref log()
*/ */
UnsignedInt MAGNUM_EXPORT log2(UnsignedInt number); UnsignedInt MAGNUM_EXPORT log2(UnsignedInt number);
@ -75,7 +75,7 @@ UnsignedInt MAGNUM_EXPORT log2(UnsignedInt number);
* @brief Integral logarithm * @brief Integral logarithm
* *
* Returns integral logarithm of given number with given base. * Returns integral logarithm of given number with given base.
* @see log2() * @see @ref log2()
*/ */
UnsignedInt MAGNUM_EXPORT log(UnsignedInt base, UnsignedInt number); UnsignedInt MAGNUM_EXPORT log(UnsignedInt base, UnsignedInt number);
@ -289,7 +289,7 @@ template<std::size_t size, class T> Vector<size, T> ceil(const Vector<size, T>&
/** /**
@brief Square root @brief Square root
@see sqrtInverted(), Vector::length() @see @ref sqrtInverted(), @ref Vector::length()
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T sqrt(const T& a); template<class T> inline T sqrt(const T& a);
@ -308,7 +308,7 @@ template<std::size_t size, class T> Vector<size, T> sqrt(const Vector<size, T>&
/** /**
@brief Inverse square root @brief Inverse square root
@see sqrt(), Vector::lengthInverted() @see @ref sqrt(), @ref Vector::lengthInverted()
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T sqrtInverted(const T& a); template<class T> inline T sqrtInverted(const T& a);
@ -326,7 +326,7 @@ template<std::size_t size, class T> Vector<size, T> sqrtInverted(const Vector<si
Values smaller than @p min are set to @p min, values larger than @p max are Values smaller than @p min are set to @p min, values larger than @p max are
set to @p max. set to @p max.
@see min(), max() @see @ref min(), @ref max()
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class T, class U> inline T clamp(const T& value, U min, U max); template<class T, class U> inline T clamp(const T& value, U min, U max);
@ -351,7 +351,7 @@ template<std::size_t size, class T> Vector<size, T> clamp(const Vector<size, T>&
The interpolation for vectors is done as in following, similarly for scalars: @f[ The interpolation for vectors is done as in following, similarly for scalars: @f[
\boldsymbol v_{LERP} = (1 - t) \boldsymbol v_A + t \boldsymbol v_B \boldsymbol v_{LERP} = (1 - t) \boldsymbol v_A + t \boldsymbol v_B
@f] @f]
@see lerpInverted(), Quaternion::lerp() @see @ref lerpInverted(), @ref Quaternion::lerp()
@todo http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ @todo http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
(when SIMD is in place) (when SIMD is in place)
*/ */
@ -375,7 +375,7 @@ template<std::size_t size, class T, class U> inline Vector<size, T> lerp(const V
Returns interpolation phase *t*: @f[ Returns interpolation phase *t*: @f[
t = \frac{\boldsymbol v_{LERP} - \boldsymbol v_A}{\boldsymbol v_B - \boldsymbol v_A} t = \frac{\boldsymbol v_{LERP} - \boldsymbol v_A}{\boldsymbol v_B - \boldsymbol v_A}
@f] @f]
@see lerp() @see @ref lerp()
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T lerpInverted(const T& a, const T& b, const T& lerp); template<class T> inline T lerpInverted(const T& a, const T& b, const T& lerp);

29
src/Magnum/Math/Geometry/Distance.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Geometry::Distance * @brief Class @ref Magnum::Math::Geometry::Distance
*/ */
#include "Magnum/Math/Functions.h" #include "Magnum/Math/Functions.h"
@ -50,7 +50,7 @@ class Distance {
* d = \frac{|(\boldsymbol b - \boldsymbol a)_\bot \cdot (\boldsymbol a - \boldsymbol p)|} {|\boldsymbol b - \boldsymbol a|} * d = \frac{|(\boldsymbol b - \boldsymbol a)_\bot \cdot (\boldsymbol a - \boldsymbol p)|} {|\boldsymbol b - \boldsymbol a|}
* @f] * @f]
* Source: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html * Source: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
* @see linePointSquared(const Vector2&, const Vector2&, const Vector2&) * @see @ref linePointSquared(const Vector2<T>&, const Vector2<T>&, const Vector2<T>&)
*/ */
template<class T> static T linePoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) { template<class T> static T linePoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
const Vector2<T> bMinusA = b - a; const Vector2<T> bMinusA = b - a;
@ -63,7 +63,8 @@ class Distance {
* @param b Second point of the line * @param b Second point of the line
* @param point Point * @param point Point
* *
* More efficient than linePoint(const Vector2&, const Vector2&, const Vector2&) * More efficient than
* @ref linePoint(const Vector2<T>&, const Vector2<T>&, const Vector2<T>&)
* for comparing distance with other values, because it doesn't * for comparing distance with other values, because it doesn't
* compute the square root. * compute the square root.
*/ */
@ -84,7 +85,7 @@ class Distance {
* {|\boldsymbol b - \boldsymbol a|} * {|\boldsymbol b - \boldsymbol a|}
* @f] * @f]
* Source: http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html * Source: http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
* @see linePointSquared(const Vector3&, const Vector3&, const Vector3&) * @see @ref linePointSquared(const Vector3<T>&, const Vector3<T>&, const Vector3<T>&)
*/ */
template<class T> static T linePoint(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) { template<class T> static T linePoint(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
return std::sqrt(linePointSquared(a, b, point)); return std::sqrt(linePointSquared(a, b, point));
@ -93,7 +94,7 @@ class Distance {
/** /**
* @brief %Distance of line and point in 3D, squared * @brief %Distance of line and point in 3D, squared
* *
* More efficient than linePoint(const Vector3&, const Vector3&, const Vector3&) * More efficient than @ref linePoint(const Vector3<T>&, const Vector3<T>&, const Vector3<T>&)
* for comparing distance with other values, because it doesn't * for comparing distance with other values, because it doesn't
* compute the square root. * compute the square root.
*/ */
@ -121,19 +122,19 @@ class Distance {
* @f] * @f]
* The last alternative is when the following equation applies. The * The last alternative is when the following equation applies. The
* point then lies between **a** and **b** and the distance is * point then lies between **a** and **b** and the distance is
* computed the same way as in linePoint(). @f[ * computed the same way as in @ref linePoint(). @f[
* |\boldsymbol b - \boldsymbol a|^2 > |\boldsymbol p - \boldsymbol a|^2 + |\boldsymbol p - \boldsymbol b|^2 * |\boldsymbol b - \boldsymbol a|^2 > |\boldsymbol p - \boldsymbol a|^2 + |\boldsymbol p - \boldsymbol b|^2
* @f] * @f]
* *
* @see lineSegmentPointSquared() * @see @ref lineSegmentPointSquared()
*/ */
template<class T> static T lineSegmentPoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point); template<class T> static T lineSegmentPoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point);
/** /**
* @brief %Distance of point from line segment in 2D, squared * @brief %Distance of point from line segment in 2D, squared
* *
* More efficient than lineSegmentPoint() for comparing distance with * More efficient than @ref lineSegmentPoint() for comparing distance
* other values, because it doesn't compute the square root. * with other values, because it doesn't compute the square root.
*/ */
template<class T> static T lineSegmentPointSquared(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point); template<class T> static T lineSegmentPointSquared(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point);
@ -144,9 +145,9 @@ class Distance {
* @param point Point * @param point Point
* *
* Similar to 2D implementation * Similar to 2D implementation
* lineSegmentPoint(const Vector2&, const Vector2&, const Vector2&). * @ref lineSegmentPoint(const Vector2<T>&, const Vector2<T>&, const Vector2<T>&).
* *
* @see lineSegmentPointSquared(const Vector3&, const Vector3&, const Vector3&) * @see @ref lineSegmentPointSquared(const Vector3<T>&, const Vector3<T>&, const Vector3<T>&)
*/ */
template<class T> static T lineSegmentPoint(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) { template<class T> static T lineSegmentPoint(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
return std::sqrt(lineSegmentPointSquared(a, b, point)); return std::sqrt(lineSegmentPointSquared(a, b, point));
@ -155,8 +156,10 @@ class Distance {
/** /**
* @brief %Distance of point from line segment in 3D, squared * @brief %Distance of point from line segment in 3D, squared
* *
* More efficient than lineSegmentPoint(const Vector3&, const Vector3&, const Vector3&) for comparing distance with * More efficient than
* other values, because it doesn't compute the square root. * @ref lineSegmentPoint(const Vector3<T>&, const Vector3<T>&, const Vector3<T>&)
* for comparing distance with other values, because it doesn't compute
* the square root.
*/ */
template<class T> static T lineSegmentPointSquared(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point); template<class T> static T lineSegmentPointSquared(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point);
}; };

6
src/Magnum/Math/Geometry/Intersection.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Geometry::Intersection * @brief Class @ref Magnum::Math::Geometry::Intersection
*/ */
#include "Magnum/Math/Vector3.h" #include "Magnum/Math/Vector3.h"
@ -66,7 +66,7 @@ class Intersection {
* \end{array} * \end{array}
* @f] * @f]
* *
* See also lineSegmentLine() which computes only **t**, which is * See also @ref lineSegmentLine() which computes only **t**, which is
* useful if you don't need to test that the intersection lies inside * useful if you don't need to test that the intersection lies inside
* line segment defined by `q` and `q + s`. * line segment defined by `q` and `q + s`.
*/ */
@ -89,7 +89,7 @@ class Intersection {
* value is in range @f$ [ 0 ; 1 ] @f$, the intersection is inside * value is in range @f$ [ 0 ; 1 ] @f$, the intersection is inside
* the line segment defined by `p` and `p + r`. * the line segment defined by `p` and `p + r`.
* *
* Unlike lineSegmentLineSegment() computes only **t**. * Unlike @ref lineSegmentLineSegment() computes only **t**.
*/ */
template<class T> static T lineSegmentLine(const Vector2<T>& p, const Vector2<T>& r, const Vector2<T>& q, const Vector2<T>& s) { template<class T> static T lineSegmentLine(const Vector2<T>& p, const Vector2<T>& r, const Vector2<T>& q, const Vector2<T>& s) {
return Vector2<T>::cross(q - p, s)/Vector2<T>::cross(r, s); return Vector2<T>::cross(q - p, s)/Vector2<T>::cross(r, s);

2
src/Magnum/Math/Math.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Forward declarations for Magnum::Math namespace * @brief Forward declarations for @ref Magnum::Math namespace
*/ */
#include <cstddef> #include <cstddef>

24
src/Magnum/Math/Matrix.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Matrix * @brief Class @ref Magnum::Math::Matrix, typedef @ref Magnum::Math::Matrix2x2, @ref Magnum::Math::Matrix3x3, @ref Magnum::Math::Matrix4x4
*/ */
#include "Magnum/Math/RectangularMatrix.h" #include "Magnum/Math/RectangularMatrix.h"
@ -57,7 +57,7 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
/** /**
* @brief Zero-filled matrix constructor * @brief Zero-filled matrix constructor
* *
* Use this constructor by calling `Matrix m(Matrix::Zero);`. * Use this constructor by calling `%Matrix m(Matrix::Zero);`.
*/ */
constexpr explicit Matrix(ZeroType) {} constexpr explicit Matrix(ZeroType) {}
@ -68,7 +68,7 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
* @brief Default constructor * @brief Default constructor
* *
* You can also explicitly call this constructor with * You can also explicitly call this constructor with
* `Matrix m(Matrix::Identity);`. Optional parameter @p value allows * `%Matrix m(Matrix::Identity);`. Optional parameter @p value allows
* you to specify value on diagonal. * you to specify value on diagonal.
*/ */
constexpr /*implicit*/ Matrix(IdentityType = Identity, T value = T(1)): RectangularMatrix<size, size, T>(typename Implementation::GenerateSequence<size>::Type(), constexpr /*implicit*/ Matrix(IdentityType = Identity, T value = T(1)): RectangularMatrix<size, size, T>(typename Implementation::GenerateSequence<size>::Type(),
@ -113,8 +113,9 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
* The matrix is orthogonal if its transpose is equal to its inverse: @f[ * The matrix is orthogonal if its transpose is equal to its inverse: @f[
* Q^T = Q^{-1} * Q^T = Q^{-1}
* @f] * @f]
* @see transposed(), inverted(), Matrix3::isRigidTransformation(), * @see @ref transposed(), @ref inverted(),
* Matrix4::isRigidTransformation() * @ref Matrix3::isRigidTransformation(),
* @ref Matrix4::isRigidTransformation()
*/ */
bool isOrthogonal() const; bool isOrthogonal() const;
@ -149,19 +150,22 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
* Computed using Cramer's rule: @f[ * Computed using Cramer's rule: @f[
* A^{-1} = \frac{1}{\det(A)} Adj(A) * A^{-1} = \frac{1}{\det(A)} Adj(A)
* @f] * @f]
* See invertedOrthogonal(), Matrix3::invertedRigid() and Matrix4::invertedRigid() * See @ref invertedOrthogonal(), @ref Matrix3::invertedRigid() and
* which are faster alternatives for particular matrix types. * @ref Matrix4::invertedRigid() which are faster alternatives for
* particular matrix types.
*/ */
Matrix<size, T> inverted() const; Matrix<size, T> inverted() const;
/** /**
* @brief Inverted orthogonal matrix * @brief Inverted orthogonal matrix
* *
* Equivalent to transposed(), expects that the matrix is orthogonal. @f[ * Equivalent to @ref transposed(), expects that the matrix is
* orthogonal. @f[
* A^{-1} = A^T * A^{-1} = A^T
* @f] * @f]
* @see inverted(), isOrthogonal(), Matrix3::invertedRigid(), * @see @ref inverted(), @ref isOrthogonal(),
* Matrix4::invertedRigid() * @ref Matrix3::invertedRigid(),
* @ref Matrix4::invertedRigid()
*/ */
Matrix<size, T> invertedOrthogonal() const { Matrix<size, T> invertedOrthogonal() const {
CORRADE_ASSERT(isOrthogonal(), CORRADE_ASSERT(isOrthogonal(),

87
src/Magnum/Math/Matrix3.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Matrix3 * @brief Class @ref Magnum::Math::Matrix3
*/ */
#include "Magnum/Math/Matrix.h" #include "Magnum/Math/Matrix.h"
@ -40,8 +40,8 @@ namespace Magnum { namespace Math {
Represents 2D transformation. See @ref matrix-vector and @ref transformations Represents 2D transformation. See @ref matrix-vector and @ref transformations
for brief introduction. for brief introduction.
@see Magnum::Matrix3, Magnum::Matrix3d, DualComplex, @see @ref Magnum::Matrix3, @ref Magnum::Matrix3d, @ref DualComplex,
SceneGraph::MatrixTransformation2D @ref SceneGraph::MatrixTransformation2D
@configurationvalueref{Magnum::Math::Matrix3} @configurationvalueref{Magnum::Math::Matrix3}
*/ */
template<class T> class Matrix3: public Matrix<3, T> { template<class T> class Matrix3: public Matrix<3, T> {
@ -50,9 +50,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D translation matrix * @brief 2D translation matrix
* @param vector Translation vector * @param vector Translation vector
* *
* @see translation(), DualComplex::translation(), * @see translation() const, @ref DualComplex::translation(),
* Matrix4::translation(const Vector3&), Vector2::xAxis(), * @ref Matrix4::translation(const Vector3<T>&),
* Vector2::yAxis() * @ref Vector2::xAxis(), @ref Vector2::yAxis()
* @todoc Explicit reference when Doxygen can handle const
*/ */
constexpr static Matrix3<T> translation(const Vector2<T>& vector) { constexpr static Matrix3<T> translation(const Vector2<T>& vector) {
return {{ T(1), T(0), T(0)}, return {{ T(1), T(0), T(0)},
@ -64,8 +65,9 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D scaling matrix * @brief 2D scaling matrix
* @param vector Scaling vector * @param vector Scaling vector
* *
* @see rotationScaling() const, Matrix4::scaling(const Vector3&), * @see @ref rotationScaling(),
* Vector2::xScale(), Vector2::yScale() * @ref Matrix4::scaling(const Vector3<T>&),
* @ref Vector2::xScale(), @ref Vector2::yScale()
*/ */
constexpr static Matrix3<T> scaling(const Vector2<T>& vector) { constexpr static Matrix3<T> scaling(const Vector2<T>& vector) {
return {{vector.x(), T(0), T(0)}, return {{vector.x(), T(0), T(0)},
@ -77,8 +79,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D rotation matrix * @brief 2D rotation matrix
* @param angle Rotation angle (counterclockwise) * @param angle Rotation angle (counterclockwise)
* *
* @see rotation() const, Complex::rotation(), DualComplex::rotation(), * @see rotation() const, @ref Complex::rotation(),
* Matrix4::rotation(Rad, const Vector3&) * @ref DualComplex::rotation(),
* @ref Matrix4::rotation(Rad, const Vector3<T>&)
* @todoc Explicit reference when Doxygen can handle const
*/ */
static Matrix3<T> rotation(Rad<T> angle); static Matrix3<T> rotation(Rad<T> angle);
@ -87,7 +91,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @param normal Normal of the line through which to reflect * @param normal Normal of the line through which to reflect
* *
* Expects that the normal is normalized. * Expects that the normal is normalized.
* @see Matrix4::reflection(), Vector::isNormalized() * @see @ref Matrix4::reflection(), @ref Vector::isNormalized()
*/ */
static Matrix3<T> reflection(const Vector2<T>& normal) { static Matrix3<T> reflection(const Vector2<T>& normal) {
CORRADE_ASSERT(normal.isNormalized(), CORRADE_ASSERT(normal.isNormalized(),
@ -99,7 +103,8 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D projection matrix * @brief 2D projection matrix
* @param size Size of the view * @param size Size of the view
* *
* @see Matrix4::orthographicProjection(), Matrix4::perspectiveProjection() * @see @ref Matrix4::orthographicProjection(),
* @ref Matrix4::perspectiveProjection()
*/ */
static Matrix3<T> projection(const Vector2<T>& size) { static Matrix3<T> projection(const Vector2<T>& size) {
return scaling(2.0f/size); return scaling(2.0f/size);
@ -112,7 +117,8 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @param translation Translation part (first two elements of * @param translation Translation part (first two elements of
* third column) * third column)
* *
* @see rotationScaling() const, translation() const * @see @ref rotationScaling(), translation() const
* @todoc Explicit reference when Doxygen can handle const
*/ */
constexpr static Matrix3<T> from(const Matrix<2, T>& rotationScaling, const Vector2<T>& translation) { constexpr static Matrix3<T> from(const Matrix<2, T>& rotationScaling, const Vector2<T>& translation) {
return {{rotationScaling[0], T(0)}, return {{rotationScaling[0], T(0)},
@ -127,8 +133,8 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief Default constructor * @brief Default constructor
* *
* Creates identity matrix. You can also explicitly call this * Creates identity matrix. You can also explicitly call this
* constructor with `Matrix3 m(Matrix3::Identity);`. Optional parameter * constructor with `%Matrix3 m(Matrix3::Identity);`. Optional
* @p value allows you to specify value on diagonal. * parameter @p value allows you to specify value on diagonal.
*/ */
constexpr /*implicit*/ Matrix3(typename Matrix<3, T>::IdentityType = (Matrix<3, T>::Identity), T value = T(1)): Matrix<3, T>(Matrix<3, T>::Identity, value) {} constexpr /*implicit*/ Matrix3(typename Matrix<3, T>::IdentityType = (Matrix<3, T>::Identity), T value = T(1)): Matrix<3, T>(Matrix<3, T>::Identity, value) {}
@ -149,7 +155,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* *
* Rigid transformation consists only of rotation and translation (i.e. * Rigid transformation consists only of rotation and translation (i.e.
* no scaling or projection). * no scaling or projection).
* @see isOrthogonal() * @see @ref isOrthogonal()
*/ */
bool isRigidTransformation() const { bool isRigidTransformation() const {
return rotationScaling().isOrthogonal() && row(2) == Vector3<T>(T(0), T(0), T(1)); return rotationScaling().isOrthogonal() && row(2) == Vector3<T>(T(0), T(0), T(1));
@ -159,9 +165,11 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D rotation and scaling part of the matrix * @brief 2D rotation and scaling part of the matrix
* *
* Upper-left 2x2 part of the matrix. * Upper-left 2x2 part of the matrix.
* @see from(const Matrix<2, T>&, const Vector2&), rotation() const * @see @ref from(const Matrix<2, T>&, const Vector2<T>&),
* rotationNormalized(), @ref uniformScaling(), rotation(T), * rotation() const, @ref rotationNormalized(),
* Matrix4::rotationScaling() const * @ref uniformScaling(), @ref rotation(Rad<T>),
* @ref Matrix4::rotationScaling()
* @todoc Explicit reference when Doxygen can handle const
*/ */
constexpr Matrix<2, T> rotationScaling() const { constexpr Matrix<2, T> rotationScaling() const {
return {(*this)[0].xy(), return {(*this)[0].xy(),
@ -176,6 +184,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @see rotation() const, @ref uniformScaling(), * @see rotation() const, @ref uniformScaling(),
* @ref Matrix4::rotationNormalized() * @ref Matrix4::rotationNormalized()
* @todo assert also orthogonality or this is good enough? * @todo assert also orthogonality or this is good enough?
* @todoc Explicit reference when Doxygen can handle const
*/ */
Matrix<2, T> rotationNormalized() const { Matrix<2, T> rotationNormalized() const {
CORRADE_ASSERT((*this)[0].xy().isNormalized() && (*this)[1].xy().isNormalized(), CORRADE_ASSERT((*this)[0].xy().isNormalized() && (*this)[1].xy().isNormalized(),
@ -189,8 +198,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
* *
* Normalized upper-left 2x2 part of the matrix. Expects uniform * Normalized upper-left 2x2 part of the matrix. Expects uniform
* scaling. * scaling.
* @see rotationNormalized(), rotationScaling(), @ref uniformScaling(), * @see @ref rotationNormalized(), @ref rotationScaling(),
* rotation(T), Matrix4::rotation() const * @ref uniformScaling(), @ref rotation(Rad<T>),
* Matrix4::rotation() const
* @todoc Explicit reference when Doxygen can handle const
*/ */
Matrix<2, T> rotation() const { Matrix<2, T> rotation() const {
CORRADE_ASSERT(TypeTraits<T>::equals((*this)[0].xy().dot(), (*this)[1].xy().dot()), CORRADE_ASSERT(TypeTraits<T>::equals((*this)[0].xy().dot(), (*this)[1].xy().dot()),
@ -206,9 +217,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
* Expects that the scaling is the same in all axes. Faster alternative * Expects that the scaling is the same in all axes. Faster alternative
* to @ref uniformScaling(), because it doesn't compute the square * to @ref uniformScaling(), because it doesn't compute the square
* root. * root.
* @see @ref rotationScaling(), @ref rotation(), * @see @ref rotationScaling(), rotation() const,
* @ref rotationNormalized(), @ref scaling(const Vector2<T>&), * @ref rotationNormalized(), @ref scaling(const Vector2<T>&),
* @ref Matrix4::uniformScaling() * @ref Matrix4::uniformScaling()
* @todoc Explicit reference when Doxygen can handle const
*/ */
T uniformScalingSquared() const { T uniformScalingSquared() const {
const T scalingSquared = (*this)[0].xy().dot(); const T scalingSquared = (*this)[0].xy().dot();
@ -223,9 +235,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
* Length of vectors in upper-left 2x2 part of the matrix. Expects that * Length of vectors in upper-left 2x2 part of the matrix. Expects that
* the scaling is the same in all axes. Use faster alternative * the scaling is the same in all axes. Use faster alternative
* @ref uniformScalingSquared() where possible. * @ref uniformScalingSquared() where possible.
* @see @ref rotationScaling(), @ref rotation(), * @see @ref rotationScaling(), rotation() const,
* @ref rotationNormalized(), @ref scaling(const Vector2<T>&), * @ref rotationNormalized(), @ref scaling(const Vector2<T>&),
* @ref Matrix4::uniformScaling() * @ref Matrix4::uniformScaling()
* @todoc Explicit reference when Doxygen can handle const
*/ */
T uniformScaling() const { return std::sqrt(uniformScalingSquared()); } T uniformScaling() const { return std::sqrt(uniformScalingSquared()); }
@ -233,7 +246,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief Right-pointing 2D vector * @brief Right-pointing 2D vector
* *
* First two elements of first column. * First two elements of first column.
* @see up(), Vector2::xAxis(), Matrix4::right() * @see @ref up(), @ref Vector2::xAxis(), @ref Matrix4::right()
*/ */
Vector2<T>& right() { return (*this)[0].xy(); } Vector2<T>& right() { return (*this)[0].xy(); }
constexpr Vector2<T> right() const { return (*this)[0].xy(); } /**< @overload */ constexpr Vector2<T> right() const { return (*this)[0].xy(); } /**< @overload */
@ -242,7 +255,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief Up-pointing 2D vector * @brief Up-pointing 2D vector
* *
* First two elements of second column. * First two elements of second column.
* @see right(), Vector2::yAxis(), Matrix4::up() * @see @ref right(), @ref Vector2::yAxis(), @ref Matrix4::up()
*/ */
Vector2<T>& up() { return (*this)[1].xy(); } Vector2<T>& up() { return (*this)[1].xy(); }
constexpr Vector2<T> up() const { return (*this)[1].xy(); } /**< @overload */ constexpr Vector2<T> up() const { return (*this)[1].xy(); } /**< @overload */
@ -251,8 +264,9 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D translation part of the matrix * @brief 2D translation part of the matrix
* *
* First two elements of third column. * First two elements of third column.
* @see from(const Matrix<2, T>&, const Vector2&), * @see @ref from(const Matrix<2, T>&, const Vector2<T>&),
* translation(const Vector2&), Matrix4::translation() * @ref translation(const Vector2<T>&),
* @ref Matrix4::translation()
*/ */
Vector2<T>& translation() { return (*this)[2].xy(); } Vector2<T>& translation() { return (*this)[2].xy(); }
constexpr Vector2<T> translation() const { return (*this)[2].xy(); } /**< @overload */ constexpr Vector2<T> translation() const { return (*this)[2].xy(); } /**< @overload */
@ -261,20 +275,22 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief Inverted rigid transformation matrix * @brief Inverted rigid transformation matrix
* *
* Expects that the matrix represents rigid transformation. * Expects that the matrix represents rigid transformation.
* Significantly faster than the general algorithm in inverted(). * Significantly faster than the general algorithm in @ref inverted().
* @see isRigidTransformation(), invertedOrthogonal(), * @see @ref isRigidTransformation(), @ref invertedOrthogonal(),
* rotationScaling() const, translation() const * @ref rotationScaling(), translation() const
* @todoc Explicit reference when Doxygen can handle const
*/ */
Matrix3<T> invertedRigid() const; Matrix3<T> invertedRigid() const;
/** /**
* @brief Transform 2D vector with the matrix * @brief Transform 2D vector with the matrix
* *
* Unlike in transformPoint(), translation is not involved in the * Unlike in @ref transformPoint(), translation is not involved in the
* transformation. @f[ * transformation. @f[
* \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ 0 \end{pmatrix} * \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ 0 \end{pmatrix}
* @f] * @f]
* @see Complex::transformVector(), Matrix4::transformVector() * @see @ref Complex::transformVector(),
* @ref Matrix4::transformVector()
* @todo extract 2x2 matrix and multiply directly? (benchmark that) * @todo extract 2x2 matrix and multiply directly? (benchmark that)
*/ */
Vector2<T> transformVector(const Vector2<T>& vector) const { Vector2<T> transformVector(const Vector2<T>& vector) const {
@ -284,11 +300,12 @@ template<class T> class Matrix3: public Matrix<3, T> {
/** /**
* @brief Transform 2D point with the matrix * @brief Transform 2D point with the matrix
* *
* Unlike in transformVector(), translation is also involved in the * Unlike in @ref transformVector(), translation is also involved in
* transformation. @f[ * the transformation. @f[
* \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ 1 \end{pmatrix} * \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ 1 \end{pmatrix}
* @f] * @f]
* @see DualComplex::transformPoint(), Matrix4::transformPoint() * @see @ref DualComplex::transformPoint(),
* @ref Matrix4::transformPoint()
*/ */
Vector2<T> transformPoint(const Vector2<T>& vector) const { Vector2<T> transformPoint(const Vector2<T>& vector) const {
return ((*this)*Vector3<T>(vector, T(1))).xy(); return ((*this)*Vector3<T>(vector, T(1))).xy();

123
src/Magnum/Math/Matrix4.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Matrix4 * @brief Class @ref Magnum::Math::Matrix4
*/ */
#include "Magnum/Math/Matrix.h" #include "Magnum/Math/Matrix.h"
@ -45,8 +45,8 @@ namespace Magnum { namespace Math {
Represents 3D transformation. See @ref matrix-vector and @ref transformations Represents 3D transformation. See @ref matrix-vector and @ref transformations
for brief introduction. for brief introduction.
@see Magnum::Matrix4, Magnum::Matrix4d, DualQuaternion, @see @ref Magnum::Matrix4, @ref Magnum::Matrix4d, @ref DualQuaternion,
SceneGraph::MatrixTransformation3D @ref SceneGraph::MatrixTransformation3D
@configurationvalueref{Magnum::Math::Matrix4} @configurationvalueref{Magnum::Math::Matrix4}
*/ */
template<class T> class Matrix4: public Matrix<4, T> { template<class T> class Matrix4: public Matrix<4, T> {
@ -55,9 +55,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D translation * @brief 3D translation
* @param vector Translation vector * @param vector Translation vector
* *
* @see translation(), DualQuaternion::translation(), * @see @ref translation(), @ref DualQuaternion::translation(),
* Matrix3::translation(const Vector2&), Vector3::xAxis(), * @ref Matrix3::translation(const Vector2<T>&),
* Vector3::yAxis(), Vector3::zAxis() * @ref Vector3::xAxis(), @ref Vector3::yAxis(),
* @ref Vector3::zAxis()
*/ */
constexpr static Matrix4<T> translation(const Vector3<T>& vector) { constexpr static Matrix4<T> translation(const Vector3<T>& vector) {
return {{ T(1), T(0), T(0), T(0)}, return {{ T(1), T(0), T(0), T(0)},
@ -70,8 +71,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D scaling * @brief 3D scaling
* @param vector Scaling vector * @param vector Scaling vector
* *
* @see rotationScaling() const, Matrix3::scaling(const Vector2&), * @see @ref rotationScaling(),
* Vector3::xScale(), Vector3::yScale(), Vector3::zScale() * @ref Matrix3::scaling(const Vector2<T>&),
* @ref Vector3::xScale(), @ref Vector3::yScale(),
* @ref Vector3::zScale()
*/ */
constexpr static Matrix4<T> scaling(const Vector3<T>& vector) { constexpr static Matrix4<T> scaling(const Vector3<T>& vector) {
return {{vector.x(), T(0), T(0), T(0)}, return {{vector.x(), T(0), T(0), T(0)},
@ -86,10 +89,13 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param normalizedAxis Normalized rotation axis * @param normalizedAxis Normalized rotation axis
* *
* Expects that the rotation axis is normalized. If possible, use * Expects that the rotation axis is normalized. If possible, use
* faster alternatives like rotationX(), rotationY() and rotationZ(). * faster alternatives like @ref rotationX(), @ref rotationY() and
* @see rotation() const, Quaternion::rotation(), DualQuaternion::rotation(), * @ref rotationZ().
* Matrix3::rotation(Rad), Vector3::xAxis(), Vector3::yAxis(), * @see rotation() const, @ref Quaternion::rotation(),
* Vector3::zAxis(), Vector::isNormalized() * @ref DualQuaternion::rotation(), @ref Matrix3::rotation(Rad),
* @ref Vector3::xAxis(), @ref Vector3::yAxis(),
* @ref Vector3::zAxis(), @ref Vector::isNormalized()
* @todoc Explicit reference when Doxygen can handle const
*/ */
static Matrix4<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis); static Matrix4<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis);
@ -97,9 +103,11 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D rotation around X axis * @brief 3D rotation around X axis
* @param angle Rotation angle (counterclockwise) * @param angle Rotation angle (counterclockwise)
* *
* Faster than calling `Matrix4::rotation(angle, Vector3::xAxis())`. * Faster than calling `%Matrix4::rotation(angle, %Vector3::xAxis())`.
* @see rotation(Rad, const Vector3&), rotationY(), rotationZ(), * @see @ref rotation(Rad, const Vector3<T>&), @ref rotationY(),
* rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad) * @ref rotationZ(), rotation() const,
* @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad)
* @todoc Explicit reference when Doxygen can handle const
*/ */
static Matrix4<T> rotationX(Rad<T> angle); static Matrix4<T> rotationX(Rad<T> angle);
@ -107,9 +115,11 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D rotation around Y axis * @brief 3D rotation around Y axis
* @param angle Rotation angle (counterclockwise) * @param angle Rotation angle (counterclockwise)
* *
* Faster than calling `Matrix4::rotation(angle, Vector3::yAxis())`. * Faster than calling `%Matrix4::rotation(angle, %Vector3::yAxis())`.
* @see rotation(Rad, const Vector3&), rotationX(), rotationZ(), * @see @ref rotation(Rad, const Vector3<T>&), @ref rotationX(),
* rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad) * @ref rotationZ(), rotation() const,
* @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad)
* @todoc Explicit reference when Doxygen can handle const
*/ */
static Matrix4<T> rotationY(Rad<T> angle); static Matrix4<T> rotationY(Rad<T> angle);
@ -117,9 +127,11 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D rotation matrix around Z axis * @brief 3D rotation matrix around Z axis
* @param angle Rotation angle (counterclockwise) * @param angle Rotation angle (counterclockwise)
* *
* Faster than calling `Matrix4::rotation(angle, Vector3::zAxis())`. * Faster than calling `%Matrix4::rotation(angle, %Vector3::zAxis())`.
* @see rotation(Rad, const Vector3&), rotationX(), rotationY(), * @see @ref rotation(Rad, const Vector3<T>&), @ref rotationX(),
* rotation() const, Quaternion::rotation(), Matrix3::rotation(Rad) * @ref rotationY(), rotation() const,
* @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad)
* @todoc Explicit reference when Doxygen can handle const
*/ */
static Matrix4<T> rotationZ(Rad<T> angle); static Matrix4<T> rotationZ(Rad<T> angle);
@ -128,7 +140,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param normal Normal of the plane through which to reflect * @param normal Normal of the plane through which to reflect
* *
* Expects that the normal is normalized. * Expects that the normal is normalized.
* @see Matrix3::reflection(), Vector::isNormalized() * @see @ref Matrix3::reflection(), @ref Vector::isNormalized()
*/ */
static Matrix4<T> reflection(const Vector3<T>& normal); static Matrix4<T> reflection(const Vector3<T>& normal);
@ -138,7 +150,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param near Near clipping plane * @param near Near clipping plane
* @param far Far clipping plane * @param far Far clipping plane
* *
* @see perspectiveProjection(), Matrix3::projection() * @see @ref perspectiveProjection(), @ref Matrix3::projection()
*/ */
static Matrix4<T> orthographicProjection(const Vector2<T>& size, T near, T far); static Matrix4<T> orthographicProjection(const Vector2<T>& size, T near, T far);
@ -148,7 +160,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param near Near clipping plane * @param near Near clipping plane
* @param far Far clipping plane * @param far Far clipping plane
* *
* @see orthographicProjection(), Matrix3::projection() * @see @ref orthographicProjection(), @ref Matrix3::projection()
*/ */
static Matrix4<T> perspectiveProjection(const Vector2<T>& size, T near, T far); static Matrix4<T> perspectiveProjection(const Vector2<T>& size, T near, T far);
@ -159,7 +171,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param near Near clipping plane * @param near Near clipping plane
* @param far Far clipping plane * @param far Far clipping plane
* *
* @see orthographicProjection(), Matrix3::projection() * @see @ref orthographicProjection(), @ref Matrix3::projection()
*/ */
static Matrix4<T> perspectiveProjection(Rad<T> fov, T aspectRatio, T near, T far) { static Matrix4<T> perspectiveProjection(Rad<T> fov, T aspectRatio, T near, T far) {
const T xyScale = 2*std::tan(T(fov)/2)*near; const T xyScale = 2*std::tan(T(fov)/2)*near;
@ -173,7 +185,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param translation Translation part (first three elements of * @param translation Translation part (first three elements of
* fourth column) * fourth column)
* *
* @see rotationScaling() const, translation() const * @see @ref rotationScaling(), translation() const
* @todoc Explicit reference when Doxygen can handle const
*/ */
constexpr static Matrix4<T> from(const Matrix<3, T>& rotationScaling, const Vector3<T>& translation) { constexpr static Matrix4<T> from(const Matrix<3, T>& rotationScaling, const Vector3<T>& translation) {
return {{rotationScaling[0], T(0)}, return {{rotationScaling[0], T(0)},
@ -189,8 +202,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief Default constructor * @brief Default constructor
* *
* Creates identity matrix. You can also explicitly call this * Creates identity matrix. You can also explicitly call this
* constructor with `Matrix4 m(Matrix4::Identity);`. Optional parameter * constructor with `%Matrix4 m(Matrix4::Identity);`. Optional
* @p value allows you to specify value on diagonal. * parameter @p value allows you to specify value on diagonal.
*/ */
constexpr /*implicit*/ Matrix4(typename Matrix<4, T>::IdentityType = (Matrix<4, T>::Identity), T value = T(1)): Matrix<4, T>(Matrix<4, T>::Identity, value) {} constexpr /*implicit*/ Matrix4(typename Matrix<4, T>::IdentityType = (Matrix<4, T>::Identity), T value = T(1)): Matrix<4, T>(Matrix<4, T>::Identity, value) {}
@ -211,7 +224,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* *
* Rigid transformation consists only of rotation and translation (i.e. * Rigid transformation consists only of rotation and translation (i.e.
* no scaling or projection). * no scaling or projection).
* @see isOrthogonal() * @see @ref isOrthogonal()
*/ */
bool isRigidTransformation() const { bool isRigidTransformation() const {
return rotationScaling().isOrthogonal() && row(3) == Vector4<T>(T(0), T(0), T(0), T(1)); return rotationScaling().isOrthogonal() && row(3) == Vector4<T>(T(0), T(0), T(0), T(1));
@ -221,9 +234,11 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D rotation and scaling part of the matrix * @brief 3D rotation and scaling part of the matrix
* *
* Upper-left 3x3 part of the matrix. * Upper-left 3x3 part of the matrix.
* @see from(const Matrix<3, T>&, const Vector3&), rotation() const, * @see @ref from(const Matrix<3, T>&, const Vector3<T>&),
* rotationNormalized(), @ref uniformScaling(), * rotation() const, @ref rotationNormalized(),
* rotation(T, const Vector3&), Matrix3::rotationScaling() const * @ref uniformScaling(), @ref rotation(Rad, const Vector3<T>&),
* Matrix3::rotationScaling() const
* @todoc Explicit reference when Doxygen can handle const
*/ */
/* Not Matrix3, because it is for affine 2D transformations */ /* Not Matrix3, because it is for affine 2D transformations */
constexpr Matrix<3, T> rotationScaling() const { constexpr Matrix<3, T> rotationScaling() const {
@ -240,6 +255,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @see rotation() const, @ref uniformScaling(), * @see rotation() const, @ref uniformScaling(),
* @ref Matrix3::rotationNormalized() * @ref Matrix3::rotationNormalized()
* @todo assert also orthogonality or this is good enough? * @todo assert also orthogonality or this is good enough?
* @todoc Explicit reference when Doxygen can handle const
*/ */
/* Not Matrix3, because it is for affine 2D transformations */ /* Not Matrix3, because it is for affine 2D transformations */
Matrix<3, T> rotationNormalized() const { Matrix<3, T> rotationNormalized() const {
@ -255,9 +271,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* *
* Normalized upper-left 3x3 part of the matrix. Expects uniform * Normalized upper-left 3x3 part of the matrix. Expects uniform
* scaling. * scaling.
* @see rotationNormalized(), rotationScaling() const, * @see @ref rotationNormalized(), @ref rotationScaling(),
* @ref uniformScaling(), rotation(T, const Vector3&), * @ref uniformScaling(), @ref rotation(Rad, const Vector3<T>&),
* Matrix3::rotation() const * Matrix3::rotation() const
* @todoc Explicit reference when Doxygen can handle const
*/ */
/* Not Matrix3, because it is for affine 2D transformations */ /* Not Matrix3, because it is for affine 2D transformations */
Matrix<3, T> rotation() const; Matrix<3, T> rotation() const;
@ -269,9 +286,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* Expects that the scaling is the same in all axes. Faster alternative * Expects that the scaling is the same in all axes. Faster alternative
* to @ref uniformScaling(), because it doesn't compute the square * to @ref uniformScaling(), because it doesn't compute the square
* root. * root.
* @see @ref rotationScaling(), @ref rotation(), * @see @ref rotationScaling(), rotation() const,
* @ref rotationNormalized(), @ref scaling(const Vector3<T>&), * @ref rotationNormalized(), @ref scaling(const Vector3<T>&),
* @ref Matrix3::uniformScaling() * @ref Matrix3::uniformScaling()
* @todoc Explicit reference when Doxygen can handle const
*/ */
T uniformScalingSquared() const; T uniformScalingSquared() const;
@ -281,9 +299,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* Length of vectors in upper-left 3x3 part of the matrix. Expects that * Length of vectors in upper-left 3x3 part of the matrix. Expects that
* the scaling is the same in all axes. Use faster alternative * the scaling is the same in all axes. Use faster alternative
* @ref uniformScalingSquared() where possible. * @ref uniformScalingSquared() where possible.
* @see @ref rotationScaling(), @ref rotation(), * @see @ref rotationScaling(), rotation() const,
* @ref rotationNormalized(), @ref scaling(const Vector3<T>&), * @ref rotationNormalized(), @ref scaling(const Vector3<T>&),
* @ref Matrix3::uniformScaling() * @ref Matrix3::uniformScaling()
* @todoc Explicit reference when Doxygen can handle const
*/ */
T uniformScaling() const { return std::sqrt(uniformScalingSquared()); } T uniformScaling() const { return std::sqrt(uniformScalingSquared()); }
@ -291,7 +310,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief Right-pointing 3D vector * @brief Right-pointing 3D vector
* *
* First three elements of first column. * First three elements of first column.
* @see up(), backward(), Vector3::xAxis(), Matrix3::right() * @see @ref up(), @ref backward(), @ref Vector3::xAxis(),
* @ref Matrix3::right()
*/ */
Vector3<T>& right() { return (*this)[0].xyz(); } Vector3<T>& right() { return (*this)[0].xyz(); }
constexpr Vector3<T> right() const { return (*this)[0].xyz(); } /**< @overload */ constexpr Vector3<T> right() const { return (*this)[0].xyz(); } /**< @overload */
@ -300,7 +320,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief Up-pointing 3D vector * @brief Up-pointing 3D vector
* *
* First three elements of second column. * First three elements of second column.
* @see right(), backward(), Vector3::yAxis(), Matrix3::up() * @see @ref right(), @ref backward(), @ref Vector3::yAxis(),
* @ref Matrix3::up()
*/ */
Vector3<T>& up() { return (*this)[1].xyz(); } Vector3<T>& up() { return (*this)[1].xyz(); }
constexpr Vector3<T> up() const { return (*this)[1].xyz(); } /**< @overload */ constexpr Vector3<T> up() const { return (*this)[1].xyz(); } /**< @overload */
@ -309,7 +330,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief Backward-pointing 3D vector * @brief Backward-pointing 3D vector
* *
* First three elements of third column. * First three elements of third column.
* @see right(), up(), Vector3::yAxis() * @see @ref right(), @ref up(), @ref Vector3::yAxis()
*/ */
Vector3<T>& backward() { return (*this)[2].xyz(); } Vector3<T>& backward() { return (*this)[2].xyz(); }
constexpr Vector3<T> backward() const { return (*this)[2].xyz(); } /**< @overload */ constexpr Vector3<T> backward() const { return (*this)[2].xyz(); } /**< @overload */
@ -318,8 +339,9 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief 3D translation part of the matrix * @brief 3D translation part of the matrix
* *
* First three elements of fourth column. * First three elements of fourth column.
* @see from(const Matrix<3, T>&, const Vector3&), * @see @ref from(const Matrix<3, T>&, const Vector3<T>&),
* translation(const Vector3&), Matrix3::translation() * @ref translation(const Vector3<T>&),
* @ref Matrix3::translation()
*/ */
Vector3<T>& translation() { return (*this)[3].xyz(); } Vector3<T>& translation() { return (*this)[3].xyz(); }
constexpr Vector3<T> translation() const { return (*this)[3].xyz(); } /**< @overload */ constexpr Vector3<T> translation() const { return (*this)[3].xyz(); } /**< @overload */
@ -328,20 +350,22 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @brief Inverted rigid transformation matrix * @brief Inverted rigid transformation matrix
* *
* Expects that the matrix represents rigid transformation. * Expects that the matrix represents rigid transformation.
* Significantly faster than the general algorithm in inverted(). * Significantly faster than the general algorithm in @ref inverted().
* @see isRigidTransformation(), invertedOrthogonal(), * @see @ref isRigidTransformation(), @ref invertedOrthogonal(),
* rotationScaling() const, translation() const * @ref rotationScaling(), translation() const
* @todoc Explicit reference when Doxygen can handle const
*/ */
Matrix4<T> invertedRigid() const; Matrix4<T> invertedRigid() const;
/** /**
* @brief Transform 3D vector with the matrix * @brief Transform 3D vector with the matrix
* *
* Unlike in transformVector(), translation is not involved in the * Unlike in @ref transformVector(), translation is not involved in the
* transformation. @f[ * transformation. @f[
* \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ v_z \\ 0 \end{pmatrix} * \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ v_z \\ 0 \end{pmatrix}
* @f] * @f]
* @see Quaternion::transformVector(), Matrix3::transformVector() * @see @ref Quaternion::transformVector(),
* @ref Matrix3::transformVector()
* @todo extract 3x3 matrix and multiply directly? (benchmark that) * @todo extract 3x3 matrix and multiply directly? (benchmark that)
*/ */
Vector3<T> transformVector(const Vector3<T>& vector) const { Vector3<T> transformVector(const Vector3<T>& vector) const {
@ -351,11 +375,12 @@ template<class T> class Matrix4: public Matrix<4, T> {
/** /**
* @brief Transform 3D point with the matrix * @brief Transform 3D point with the matrix
* *
* Unlike in transformVector(), translation is also involved in the * Unlike in @ref transformVector(), translation is also involved in
* transformation. @f[ * the transformation. @f[
* \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ v_z \\ 1 \end{pmatrix} * \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ v_z \\ 1 \end{pmatrix}
* @f] * @f]
* @see DualQuaternion::transformPoint(), Matrix3::transformPoint() * @see @ref DualQuaternion::transformPoint(),
* @ref Matrix3::transformPoint()
*/ */
Vector3<T> transformPoint(const Vector3<T>& vector) const { Vector3<T> transformPoint(const Vector3<T>& vector) const {
return ((*this)*Vector4<T>(vector, T(1))).xyz(); return ((*this)*Vector4<T>(vector, T(1))).xyz();

91
src/Magnum/Math/Quaternion.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Quaternion * @brief Class @ref Magnum::Math::Quaternion
*/ */
#include <cmath> #include <cmath>
@ -44,11 +44,12 @@ namespace Magnum { namespace Math {
@tparam T Underlying data type @tparam T Underlying data type
Represents 3D rotation. See @ref transformations for brief introduction. Represents 3D rotation. See @ref transformations for brief introduction.
@see Magnum::Quaternion, Magnum::Quaterniond, DualQuaternion, Matrix4 @see @ref Magnum::Quaternion, @ref Magnum::Quaterniond, @ref DualQuaternion,
@ref Matrix4
*/ */
template<class T> class Quaternion { template<class T> class Quaternion {
public: public:
typedef T Type; /**< @brief Underlying data type */ typedef T Type; /**< @brief Underlying data type */
/** /**
* @brief Dot product * @brief Dot product
@ -57,6 +58,7 @@ template<class T> class Quaternion {
* p \cdot q = \boldsymbol p_V \cdot \boldsymbol q_V + p_S q_S * p \cdot q = \boldsymbol p_V \cdot \boldsymbol q_V + p_S q_S
* @f] * @f]
* @see dot() const * @see dot() const
* @todoc Explicit reference when Doxygen can handle const
*/ */
static T dot(const Quaternion<T>& a, const Quaternion<T>& b) { static T dot(const Quaternion<T>& a, const Quaternion<T>& b) {
/** @todo Use four-component SIMD implementation when available */ /** @todo Use four-component SIMD implementation when available */
@ -69,7 +71,8 @@ template<class T> class Quaternion {
* Expects that both quaternions are normalized. @f[ * Expects that both quaternions are normalized. @f[
* \theta = acos \left( \frac{p \cdot q}{|p| |q|} \right) = acos(p \cdot q) * \theta = acos \left( \frac{p \cdot q}{|p| |q|} \right) = acos(p \cdot q)
* @f] * @f]
* @see isNormalized(), Complex::angle(), Vector::angle() * @see @ref isNormalized(), @ref Complex::angle(),
* @ref Vector::angle()
*/ */
static Rad<T> angle(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB); static Rad<T> angle(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB);
@ -82,7 +85,7 @@ template<class T> class Quaternion {
* Expects that both quaternions are normalized. @f[ * Expects that both quaternions are normalized. @f[
* q_{LERP} = \frac{(1 - t) q_A + t q_B}{|(1 - t) q_A + t q_B|} * q_{LERP} = \frac{(1 - t) q_A + t q_B}{|(1 - t) q_A + t q_B|}
* @f] * @f]
* @see isNormalized(), slerp(), Math::lerp() * @see @ref isNormalized(), @ref slerp(), @ref Math::lerp()
*/ */
static Quaternion<T> lerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t); static Quaternion<T> lerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t);
@ -97,7 +100,7 @@ template<class T> class Quaternion {
* ~~~~~~~~~~ * ~~~~~~~~~~
* \theta = acos \left( \frac{q_A \cdot q_B}{|q_A| \cdot |q_B|} \right) = acos(q_A \cdot q_B) * \theta = acos \left( \frac{q_A \cdot q_B}{|q_A| \cdot |q_B|} \right) = acos(q_A \cdot q_B)
* @f] * @f]
* @see isNormalized(), lerp() * @see @ref isNormalized(), @ref lerp()
*/ */
static Quaternion<T> slerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t); static Quaternion<T> slerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t);
@ -109,9 +112,10 @@ template<class T> class Quaternion {
* Expects that the rotation axis is normalized. @f[ * Expects that the rotation axis is normalized. @f[
* q = [\boldsymbol a \cdot sin \frac \theta 2, cos \frac \theta 2] * q = [\boldsymbol a \cdot sin \frac \theta 2, cos \frac \theta 2]
* @f] * @f]
* @see angle(), axis(), DualQuaternion::rotation(), * @see @ref angle(), @ref axis(), @ref DualQuaternion::rotation(),
* Matrix4::rotation(), Complex::rotation(), Vector3::xAxis(), * @ref Matrix4::rotation(), @ref Complex::rotation(),
* Vector3::yAxis(), Vector3::zAxis(), Vector::isNormalized() * @ref Vector3::xAxis(), @ref Vector3::yAxis(),
* @ref Vector3::zAxis(), @ref Vector::isNormalized()
*/ */
static Quaternion<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis); static Quaternion<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis);
@ -119,7 +123,8 @@ template<class T> class Quaternion {
* @brief Create quaternion from rotation matrix * @brief Create quaternion from rotation matrix
* *
* Expects that the matrix is orthogonal (i.e. pure rotation). * Expects that the matrix is orthogonal (i.e. pure rotation).
* @see toMatrix(), DualComplex::fromMatrix(), Matrix::isOrthogonal() * @see @ref toMatrix(), @ref DualComplex::fromMatrix(),
* @ref Matrix::isOrthogonal()
*/ */
static Quaternion<T> fromMatrix(const Matrix<3, T>& matrix); static Quaternion<T> fromMatrix(const Matrix<3, T>& matrix);
@ -147,7 +152,7 @@ template<class T> class Quaternion {
* To be used in transformations later. @f[ * To be used in transformations later. @f[
* q = [\boldsymbol v, 0] * q = [\boldsymbol v, 0]
* @f] * @f]
* @see transformVector(), transformVectorNormalized() * @see @ref transformVector(), @ref transformVectorNormalized()
*/ */
constexpr explicit Quaternion(const Vector3<T>& vector): _vector(vector), _scalar(T(0)) {} constexpr explicit Quaternion(const Vector3<T>& vector): _vector(vector), _scalar(T(0)) {}
@ -164,10 +169,10 @@ template<class T> class Quaternion {
/** /**
* @brief Whether the quaternion is normalized * @brief Whether the quaternion is normalized
* *
* Quaternion is normalized if it has unit length: @f[ * %Quaternion is normalized if it has unit length: @f[
* |q \cdot q - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon * |q \cdot q - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon
* @f] * @f]
* @see dot(), normalized() * @see @ref dot(), @ref normalized()
*/ */
bool isNormalized() const { bool isNormalized() const {
return Implementation::isNormalizedSquared(dot()); return Implementation::isNormalizedSquared(dot());
@ -185,7 +190,7 @@ template<class T> class Quaternion {
* Expects that the quaternion is normalized. @f[ * Expects that the quaternion is normalized. @f[
* \theta = 2 \cdot acos q_S * \theta = 2 \cdot acos q_S
* @f] * @f]
* @see isNormalized(), axis(), rotation() * @see @ref isNormalized(), @ref axis(), @ref rotation()
*/ */
Rad<T> angle() const; Rad<T> angle() const;
@ -197,15 +202,15 @@ template<class T> class Quaternion {
* default-constructed quaternion. @f[ * default-constructed quaternion. @f[
* \boldsymbol a = \frac{\boldsymbol q_V}{\sqrt{1 - q_S^2}} * \boldsymbol a = \frac{\boldsymbol q_V}{\sqrt{1 - q_S^2}}
* @f] * @f]
* @see isNormalized(), angle(), rotation() * @see @ref isNormalized(), @ref angle(), @ref rotation()
*/ */
Vector3<T> axis() const; Vector3<T> axis() const;
/** /**
* @brief Convert quaternion to rotation matrix * @brief Convert quaternion to rotation matrix
* *
* @see fromMatrix(), DualQuaternion::toMatrix(), * @see @ref fromMatrix(), @ref DualQuaternion::toMatrix(),
* Matrix4::from(const Matrix<3, T>&, const Vector3<T>&) * @ref Matrix4::from(const Matrix<3, T>&, const Vector3<T>&)
*/ */
Matrix<3, T> toMatrix() const; Matrix<3, T> toMatrix() const;
@ -226,6 +231,7 @@ template<class T> class Quaternion {
* @brief Add quaternion * @brief Add quaternion
* *
* @see operator+=() * @see operator+=()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Quaternion<T> operator+(const Quaternion<T>& other) const { Quaternion<T> operator+(const Quaternion<T>& other) const {
return Quaternion<T>(*this) += other; return Quaternion<T>(*this) += other;
@ -256,7 +262,7 @@ template<class T> class Quaternion {
/** /**
* @brief Subtract quaternion * @brief Subtract quaternion
* *
* @see operator-=() * @see @ref operator-=()
*/ */
Quaternion<T> operator-(const Quaternion<T>& other) const { Quaternion<T> operator-(const Quaternion<T>& other) const {
return Quaternion<T>(*this) -= other; return Quaternion<T>(*this) -= other;
@ -279,6 +285,7 @@ template<class T> class Quaternion {
* @brief Multiply with scalar * @brief Multiply with scalar
* *
* @see operator*=(T) * @see operator*=(T)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Quaternion<T> operator*(T scalar) const { Quaternion<T> operator*(T scalar) const {
return Quaternion<T>(*this) *= scalar; return Quaternion<T>(*this) *= scalar;
@ -301,6 +308,7 @@ template<class T> class Quaternion {
* @brief Divide with scalar * @brief Divide with scalar
* *
* @see operator/=(T) * @see operator/=(T)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Quaternion<T> operator/(T scalar) const { Quaternion<T> operator/(T scalar) const {
return Quaternion<T>(*this) /= scalar; return Quaternion<T>(*this) /= scalar;
@ -319,29 +327,32 @@ template<class T> class Quaternion {
/** /**
* @brief Dot product of the quaternion * @brief Dot product of the quaternion
* *
* Should be used instead of length() for comparing quaternion length * Should be used instead of @ref length() for comparing quaternion
* with other values, because it doesn't compute the square root. @f[ * length with other values, because it doesn't compute the square
* root. @f[
* q \cdot q = \boldsymbol q_V \cdot \boldsymbol q_V + q_S^2 * q \cdot q = \boldsymbol q_V \cdot \boldsymbol q_V + q_S^2
* @f] * @f]
* @see isNormalized(), dot(const Quaternion&, const Quaternion&) * @see @ref isNormalized(),
* @ref dot(const Quaternion<T>&, const Quaternion<T>&)
*/ */
T dot() const { return dot(*this, *this); } T dot() const { return dot(*this, *this); }
/** /**
* @brief %Quaternion length * @brief %Quaternion length
* *
* See also dot() const which is faster for comparing length with other * See also dot() const which is faster for comparing length with
* values. @f[ * other values. @f[
* |q| = \sqrt{q \cdot q} * |q| = \sqrt{q \cdot q}
* @f] * @f]
* @see isNormalized() * @see @ref isNormalized()
* @todoc Explicit reference when Doxygen can handle const
*/ */
T length() const { return std::sqrt(dot()); } T length() const { return std::sqrt(dot()); }
/** /**
* @brief Normalized quaternion (of unit length) * @brief Normalized quaternion (of unit length)
* *
* @see isNormalized() * @see @ref isNormalized()
*/ */
Quaternion<T> normalized() const { return (*this)/length(); } Quaternion<T> normalized() const { return (*this)/length(); }
@ -357,7 +368,7 @@ template<class T> class Quaternion {
/** /**
* @brief Inverted quaternion * @brief Inverted quaternion
* *
* See invertedNormalized() which is faster for normalized * See @ref invertedNormalized() which is faster for normalized
* quaternions. @f[ * quaternions. @f[
* q^{-1} = \frac{q^*}{|q|^2} = \frac{q^*}{q \cdot q} * q^{-1} = \frac{q^*}{|q|^2} = \frac{q^*}{q \cdot q}
* @f] * @f]
@ -367,23 +378,25 @@ template<class T> class Quaternion {
/** /**
* @brief Inverted normalized quaternion * @brief Inverted normalized quaternion
* *
* Equivalent to conjugated(). Expects that the quaternion is * Equivalent to @ref conjugated(). Expects that the quaternion is
* normalized. @f[ * normalized. @f[
* q^{-1} = \frac{q^*}{|q|^2} = q^* * q^{-1} = \frac{q^*}{|q|^2} = q^*
* @f] * @f]
* @see isNormalized(), inverted() * @see @ref isNormalized(), @ref inverted()
*/ */
Quaternion<T> invertedNormalized() const; Quaternion<T> invertedNormalized() const;
/** /**
* @brief Rotate vector with quaternion * @brief Rotate vector with quaternion
* *
* See transformVectorNormalized(), which is faster for normalized * See @ref transformVectorNormalized(), which is faster for normalized
* quaternions. @f[ * quaternions. @f[
* v' = qvq^{-1} = q [\boldsymbol v, 0] q^{-1} * v' = qvq^{-1} = q [\boldsymbol v, 0] q^{-1}
* @f] * @f]
* @see Quaternion(const Vector3&), vector(), Matrix4::transformVector(), * @see @ref Quaternion(const Vector3<T>&), @ref vector(),
* DualQuaternion::transformPoint(), Complex::transformVector() * @ref Matrix4::transformVector(),
* @ref DualQuaternion::transformPoint(),
* @ref Complex::transformVector()
*/ */
Vector3<T> transformVector(const Vector3<T>& vector) const { Vector3<T> transformVector(const Vector3<T>& vector) const {
return ((*this)*Quaternion<T>(vector)*inverted()).vector(); return ((*this)*Quaternion<T>(vector)*inverted()).vector();
@ -392,12 +405,14 @@ template<class T> class Quaternion {
/** /**
* @brief Rotate vector with normalized quaternion * @brief Rotate vector with normalized quaternion
* *
* Faster alternative to transformVector(), expects that the quaternion * Faster alternative to @ref transformVector(), expects that the
* is normalized. @f[ * quaternion is normalized. @f[
* v' = qvq^{-1} = qvq^* = q [\boldsymbol v, 0] q^* * v' = qvq^{-1} = qvq^* = q [\boldsymbol v, 0] q^*
* @f] * @f]
* @see isNormalized(), Quaternion(const Vector3&), vector(), Matrix4::transformVector(), * @see @ref isNormalized(), @ref Quaternion(const Vector3<T>&),
* DualQuaternion::transformPointNormalized(), Complex::transformVector() * @ref vector(), @ref Matrix4::transformVector(),
* @ref DualQuaternion::transformPointNormalized(),
* @ref Complex::transformVector()
*/ */
Vector3<T> transformVectorNormalized(const Vector3<T>& vector) const; Vector3<T> transformVectorNormalized(const Vector3<T>& vector) const;
@ -420,6 +435,7 @@ template<class T> class Quaternion {
@brief Multiply scalar with quaternion @brief Multiply scalar with quaternion
Same as Quaternion::operator*(T) const. Same as Quaternion::operator*(T) const.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<class T> inline Quaternion<T> operator*(T scalar, const Quaternion<T>& quaternion) { template<class T> inline Quaternion<T> operator*(T scalar, const Quaternion<T>& quaternion) {
return quaternion*scalar; return quaternion*scalar;
@ -432,6 +448,7 @@ template<class T> inline Quaternion<T> operator*(T scalar, const Quaternion<T>&
\frac a q = [\frac a {\boldsymbol q_V}, \frac a {q_S}] \frac a q = [\frac a {\boldsymbol q_V}, \frac a {q_S}]
@f] @f]
@see Quaternion::operator/() @see Quaternion::operator/()
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<class T> inline Quaternion<T> operator/(T scalar, const Quaternion<T>& quaternion) { template<class T> inline Quaternion<T> operator/(T scalar, const Quaternion<T>& quaternion) {
return {scalar/quaternion.vector(), scalar/quaternion.scalar()}; return {scalar/quaternion.vector(), scalar/quaternion.scalar()};
@ -446,12 +463,16 @@ template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug deb
return debug; return debug;
} }
/** @todoc Remove the workaround when Doxygen is really able to preprocessor */
/* Explicit instantiation for commonly used types */ /* Explicit instantiation for commonly used types */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/** @privatesection */
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Quaternion<Float>&); extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Quaternion<Float>&);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Quaternion<Double>&); extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Quaternion<Double>&);
#endif #endif
/** @endprivatesection */
#endif #endif
namespace Implementation { namespace Implementation {

6
src/Magnum/Math/Range.h

@ -62,7 +62,7 @@ template<UnsignedInt dimensions, class T> class Range {
/** /**
* Create range from minimal coordinates and size * Create range from minimal coordinates and size
* @param min Minimal coordinates * @param min Minimal coordinates
* @param size Range size * @param size %Range size
*/ */
static Range<dimensions, T> fromSize(const VectorType& min, const VectorType& size) { static Range<dimensions, T> fromSize(const VectorType& min, const VectorType& size) {
return {min, min+size}; return {min, min+size};
@ -122,7 +122,7 @@ template<UnsignedInt dimensions, class T> class Range {
constexpr const VectorType max() const { return _max; } /**< @overload */ constexpr const VectorType max() const { return _max; } /**< @overload */
/** /**
* @brief Range size * @brief %Range size
* *
* @see @ref min(), @ref max(), @ref Range2D::sizeX(), * @see @ref min(), @ref max(), @ref Range2D::sizeX(),
* @ref Range2D::sizeY(), @ref Range3D::sizeX(), * @ref Range2D::sizeY(), @ref Range3D::sizeX(),
@ -131,7 +131,7 @@ template<UnsignedInt dimensions, class T> class Range {
VectorType size() const { return _max - _min; } VectorType size() const { return _max - _min; }
/** /**
* @brief Range center * @brief %Range center
* *
* @see @ref Range2D::centerX(), @ref Range2D::centerY(), * @see @ref Range2D::centerX(), @ref Range2D::centerY(),
* @ref Range3D::centerX(), @ref Range3D::centerY(), * @ref Range3D::centerX(), @ref Range3D::centerY(),

60
src/Magnum/Math/RectangularMatrix.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::RectangularMatrix * @brief Class @ref Magnum::Math::RectangularMatrix, typedef @ref Magnum::Math::Matrix2x3, @ref Magnum::Math::Matrix3x2, @ref Magnum::Math::Matrix2x4, @ref Magnum::Math::Matrix4x2, @ref Magnum::Math::Matrix3x4, @ref Magnum::Math::Matrix4x3
*/ */
#include "Magnum/Math/Vector.h" #include "Magnum/Math/Vector.h"
@ -43,8 +43,8 @@ namespace Implementation {
@tparam rows Row count @tparam rows Row count
@tparam T Underlying data type @tparam T Underlying data type
See @ref matrix-vector for brief introduction. See also Matrix (square) and See @ref matrix-vector for brief introduction. See also @ref Matrix (square)
Vector. and @ref Vector.
The data are stored in column-major order, to reflect that, all indices in The data are stored in column-major order, to reflect that, all indices in
math formulas are in reverse order (i.e. @f$ \boldsymbol A_{ji} @f$ instead math formulas are in reverse order (i.e. @f$ \boldsymbol A_{ji} @f$ instead
@ -65,13 +65,13 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/** /**
* @brief Size of matrix diagonal * @brief Size of matrix diagonal
* *
* @see fromDiagonal(), diagonal() * @see @ref fromDiagonal(), @ref diagonal()
*/ */
const static std::size_t DiagonalSize = (cols < rows ? cols : rows); const static std::size_t DiagonalSize = (cols < rows ? cols : rows);
/** /**
* @brief %Matrix from array * @brief %Matrix from array
* @return Reference to the data as if it was Matrix, thus doesn't * @return Reference to the data as if it was matrix, thus doesn't
* perform any copying. * perform any copying.
* *
* @attention Use with caution, the function doesn't check whether the * @attention Use with caution, the function doesn't check whether the
@ -90,7 +90,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* *
* Rolls the vector into matrix, i.e. first `rows` elements of the * Rolls the vector into matrix, i.e. first `rows` elements of the
* vector will make first column of resulting matrix. * vector will make first column of resulting matrix.
* @see toVector() * @see @ref toVector()
*/ */
static RectangularMatrix<cols, rows, T> fromVector(const Vector<cols*rows, T>& vector) { static RectangularMatrix<cols, rows, T> fromVector(const Vector<cols*rows, T>& vector) {
return *reinterpret_cast<const RectangularMatrix<cols, rows, T>*>(vector.data()); return *reinterpret_cast<const RectangularMatrix<cols, rows, T>*>(vector.data());
@ -99,7 +99,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/** /**
* @brief Construct diagonal matrix * @brief Construct diagonal matrix
* *
* @see diagonal() * @see @ref diagonal()
*/ */
constexpr static RectangularMatrix<cols, rows, T> fromDiagonal(const Vector<DiagonalSize, T>& diagonal) { constexpr static RectangularMatrix<cols, rows, T> fromDiagonal(const Vector<DiagonalSize, T>& diagonal) {
return RectangularMatrix(typename Implementation::GenerateSequence<cols>::Type(), diagonal); return RectangularMatrix(typename Implementation::GenerateSequence<cols>::Type(), diagonal);
@ -164,7 +164,8 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* @return One-dimensional array of `cols*rows` length in column-major * @return One-dimensional array of `cols*rows` length in column-major
* order. * order.
* *
* @see operator[] * @see operator[]()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
T* data() { return _data[0].data(); } T* data() { return _data[0].data(); }
constexpr const T* data() const { return _data[0].data(); } /**< @overload */ constexpr const T* data() const { return _data[0].data(); } /**< @overload */
@ -172,13 +173,15 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/** /**
* @brief %Matrix column * @brief %Matrix column
* *
* Particular elements can be accessed using Vector::operator[], e.g.: * Particular elements can be accessed using Vector::operator[](),
* e.g.:
* @code * @code
* RectangularMatrix<4, 3, Float> m; * RectangularMatrix<4, 3, Float> m;
* Float a = m[2][1]; * Float a = m[2][1];
* @endcode * @endcode
* *
* @see row(), data() * @see @ref row(), @ref data()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<rows, T>& operator[](std::size_t col) { return _data[col]; } Vector<rows, T>& operator[](std::size_t col) { return _data[col]; }
constexpr const Vector<rows, T>& operator[](std::size_t col) const { return _data[col]; } /**< @overload */ constexpr const Vector<rows, T>& operator[](std::size_t col) const { return _data[col]; } /**< @overload */
@ -186,9 +189,11 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/** /**
* @brief %Matrix row * @brief %Matrix row
* *
* Consider using transposed() when accessing rows frequently, as this * Consider using @ref transposed() when accessing rows frequently, as
* is slower than accessing columns due to the way the matrix is stored. * this is slower than accessing columns due to the way the matrix is
* stored.
* @see operator[]() * @see operator[]()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<cols, T> row(std::size_t row) const; Vector<cols, T> row(std::size_t row) const;
@ -203,8 +208,9 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/** /**
* @brief Non-equality operator * @brief Non-equality operator
* *
* @see Vector::operator<(), Vector::operator<=(), Vector::operator>=(), * @see Vector::operator<(), Vector::operator<=(),
* Vector::operator>() * Vector::operator>=(), Vector::operator>()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
bool operator!=(const RectangularMatrix<cols, rows, T>& other) const { bool operator!=(const RectangularMatrix<cols, rows, T>& other) const {
return !operator==(other); return !operator==(other);
@ -237,6 +243,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* @brief Add matrix * @brief Add matrix
* *
* @see operator+=() * @see operator+=()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
RectangularMatrix<cols, rows, T> operator+(const RectangularMatrix<cols, rows, T>& other) const { RectangularMatrix<cols, rows, T> operator+(const RectangularMatrix<cols, rows, T>& other) const {
return RectangularMatrix<cols, rows, T>(*this)+=other; return RectangularMatrix<cols, rows, T>(*this)+=other;
@ -259,7 +266,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/** /**
* @brief Subtract matrix * @brief Subtract matrix
* *
* @see operator-=() * @see @ref operator-=()
*/ */
RectangularMatrix<cols, rows, T> operator-(const RectangularMatrix<cols, rows, T>& other) const { RectangularMatrix<cols, rows, T> operator-(const RectangularMatrix<cols, rows, T>& other) const {
return RectangularMatrix<cols, rows, T>(*this)-=other; return RectangularMatrix<cols, rows, T>(*this)-=other;
@ -283,6 +290,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* @brief Multiply matrix with number * @brief Multiply matrix with number
* *
* @see operator*=(T), operator*(T, const RectangularMatrix<cols, rows, T>&) * @see operator*=(T), operator*(T, const RectangularMatrix<cols, rows, T>&)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
RectangularMatrix<cols, rows, T> operator*(T number) const { RectangularMatrix<cols, rows, T> operator*(T number) const {
return RectangularMatrix<cols, rows, T>(*this) *= number; return RectangularMatrix<cols, rows, T>(*this) *= number;
@ -307,6 +315,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* *
* @see operator/=(T), * @see operator/=(T),
* operator/(T, const RectangularMatrix<cols, rows, T>&) * operator/(T, const RectangularMatrix<cols, rows, T>&)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
RectangularMatrix<cols, rows, T> operator/(T number) const { RectangularMatrix<cols, rows, T> operator/(T number) const {
return RectangularMatrix<cols, rows, T>(*this) /= number; return RectangularMatrix<cols, rows, T>(*this) /= number;
@ -336,14 +345,14 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/** /**
* @brief Transposed matrix * @brief Transposed matrix
* *
* @see row() * @see @ref row()
*/ */
RectangularMatrix<rows, cols, T> transposed() const; RectangularMatrix<rows, cols, T> transposed() const;
/** /**
* @brief Values on diagonal * @brief Values on diagonal
* *
* @see fromDiagonal() * @see @ref fromDiagonal()
*/ */
constexpr Vector<DiagonalSize, T> diagonal() const; constexpr Vector<DiagonalSize, T> diagonal() const;
@ -354,7 +363,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* of the matrix will make first `rows` elements of resulting vector. * of the matrix will make first `rows` elements of resulting vector.
* Useful for performing vector operations with the matrix (e.g. * Useful for performing vector operations with the matrix (e.g.
* summing the elements etc.). * summing the elements etc.).
* @see fromVector() * @see @ref fromVector()
*/ */
Vector<rows*cols, T> toVector() const { Vector<rows*cols, T> toVector() const {
return *reinterpret_cast<const Vector<rows*cols, T>*>(data()); return *reinterpret_cast<const Vector<rows*cols, T>*>(data());
@ -379,7 +388,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
#ifndef CORRADE_GCC46_COMPATIBILITY #ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Matrix with 2 columns and 3 rows @brief %Matrix with 2 columns and 3 rows
Convenience alternative to <tt>%RectangularMatrix<2, 3, T></tt>. See Convenience alternative to <tt>%RectangularMatrix<2, 3, T></tt>. See
@ref RectangularMatrix for more information. @ref RectangularMatrix for more information.
@ -390,7 +399,7 @@ Convenience alternative to <tt>%RectangularMatrix<2, 3, T></tt>. See
template<class T> using Matrix2x3 = RectangularMatrix<2, 3, T>; template<class T> using Matrix2x3 = RectangularMatrix<2, 3, T>;
/** /**
@brief Matrix with 3 columns and 2 rows @brief %Matrix with 3 columns and 2 rows
Convenience alternative to <tt>%RectangularMatrix<3, 2, T></tt>. See Convenience alternative to <tt>%RectangularMatrix<3, 2, T></tt>. See
@ref RectangularMatrix for more information. @ref RectangularMatrix for more information.
@ -401,7 +410,7 @@ Convenience alternative to <tt>%RectangularMatrix<3, 2, T></tt>. See
template<class T> using Matrix3x2 = RectangularMatrix<3, 2, T>; template<class T> using Matrix3x2 = RectangularMatrix<3, 2, T>;
/** /**
@brief Matrix with 2 columns and 4 rows @brief %Matrix with 2 columns and 4 rows
Convenience alternative to <tt>%RectangularMatrix<2, 4, T></tt>. See Convenience alternative to <tt>%RectangularMatrix<2, 4, T></tt>. See
@ref RectangularMatrix for more information. @ref RectangularMatrix for more information.
@ -412,7 +421,7 @@ Convenience alternative to <tt>%RectangularMatrix<2, 4, T></tt>. See
template<class T> using Matrix2x4 = RectangularMatrix<2, 4, T>; template<class T> using Matrix2x4 = RectangularMatrix<2, 4, T>;
/** /**
@brief Matrix with 4 columns and 2 rows @brief %Matrix with 4 columns and 2 rows
Convenience alternative to <tt>%RectangularMatrix<4, 2, T></tt>. See Convenience alternative to <tt>%RectangularMatrix<4, 2, T></tt>. See
@ref RectangularMatrix for more information. @ref RectangularMatrix for more information.
@ -423,7 +432,7 @@ Convenience alternative to <tt>%RectangularMatrix<4, 2, T></tt>. See
template<class T> using Matrix4x2 = RectangularMatrix<4, 2, T>; template<class T> using Matrix4x2 = RectangularMatrix<4, 2, T>;
/** /**
@brief Matrix with 3 columns and 4 rows @brief %Matrix with 3 columns and 4 rows
Convenience alternative to <tt>%RectangularMatrix<3, 4, T></tt>. See Convenience alternative to <tt>%RectangularMatrix<3, 4, T></tt>. See
@ref RectangularMatrix for more information. @ref RectangularMatrix for more information.
@ -434,7 +443,7 @@ Convenience alternative to <tt>%RectangularMatrix<3, 4, T></tt>. See
template<class T> using Matrix3x4 = RectangularMatrix<3, 4, T>; template<class T> using Matrix3x4 = RectangularMatrix<3, 4, T>;
/** /**
@brief Matrix with 4 columns and 3 rows @brief %Matrix with 4 columns and 3 rows
Convenience alternative to <tt>%RectangularMatrix<4, 3, T></tt>. See Convenience alternative to <tt>%RectangularMatrix<4, 3, T></tt>. See
@ref RectangularMatrix for more information. @ref RectangularMatrix for more information.
@ -449,6 +458,7 @@ template<class T> using Matrix4x3 = RectangularMatrix<4, 3, T>;
@brief Multiply number with matrix @brief Multiply number with matrix
Same as RectangularMatrix::operator*(T) const. Same as RectangularMatrix::operator*(T) const.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<cols, rows, T> operator*( template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<cols, rows, T> operator*(
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -468,6 +478,7 @@ The computation is done column-wise. @f[
\boldsymbol B_j = \frac a {\boldsymbol A_j} \boldsymbol B_j = \frac a {\boldsymbol A_j}
@f] @f]
@see RectangularMatrix::operator/(T) const @see RectangularMatrix::operator/(T) const
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<cols, rows, T> operator/( template<std::size_t cols, std::size_t rows, class T> inline RectangularMatrix<cols, rows, T> operator/(
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -492,6 +503,7 @@ Internally the same as multiplying one-column matrix with one-row matrix. @f[
(\boldsymbol {aA})_{ji} = \boldsymbol a_i \boldsymbol A_j (\boldsymbol {aA})_{ji} = \boldsymbol a_i \boldsymbol A_j
@f] @f]
@see RectangularMatrix::operator*(const RectangularMatrix<size, cols, T>&) const @see RectangularMatrix::operator*(const RectangularMatrix<size, cols, T>&) const
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, std::size_t cols, class T> inline RectangularMatrix<cols, size, T> operator*(const Vector<size, T>& vector, const RectangularMatrix<cols, 1, T>& matrix) { template<std::size_t size, std::size_t cols, class T> inline RectangularMatrix<cols, size, T> operator*(const Vector<size, T>& vector, const RectangularMatrix<cols, 1, T>& matrix) {
return RectangularMatrix<1, size, T>(vector)*matrix; return RectangularMatrix<1, size, T>(vector)*matrix;

2
src/Magnum/Math/Swizzle.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Function Magnum::Math::swizzle() * @brief Function @ref Magnum::Math::swizzle()
*/ */
#include "Magnum/Math/Vector.h" #include "Magnum/Math/Vector.h"

6
src/Magnum/Math/TypeTraits.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::TypeTraits * @brief Class @ref Magnum::Math::TypeTraits
*/ */
#include <cmath> #include <cmath>
@ -99,8 +99,8 @@ template<class T> struct TypeTraits: Implementation::TypeTraitsDefault<T> {
/** /**
* @brief Fuzzy compare * @brief Fuzzy compare
* *
* Uses fuzzy compare for floating-point types (using epsilon() value), * Uses fuzzy compare for floating-point types (using @ref epsilon()
* pure equality comparison everywhere else. * value), pure equality comparison everywhere else.
*/ */
static bool equals(T a, T b); static bool equals(T a, T b);
#endif #endif

4
src/Magnum/Math/Unit.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Unit * @brief Class @ref Magnum::Math::Unit
*/ */
#include "Magnum/Math/TypeTraits.h" #include "Magnum/Math/TypeTraits.h"
@ -37,7 +37,7 @@ namespace Magnum { namespace Math {
@brief Base class for units @brief Base class for units
@tparam T Underlying data type @tparam T Underlying data type
@see Deg, Rad @see @ref Deg, @ref Rad
*/ */
template<template<class> class Derived, class T> class Unit { template<template<class> class Derived, class T> class Unit {
template<template<class> class, class> friend class Unit; template<template<class> class, class> friend class Unit;

88
src/Magnum/Math/Vector.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Vector * @brief Class @ref Magnum::Math::Vector
*/ */
#include <cmath> #include <cmath>
@ -92,7 +92,9 @@ template<std::size_t size, class T> class Vector {
* antiparallel. @f[ * antiparallel. @f[
* \boldsymbol a \cdot \boldsymbol b = \sum_{i=0}^{n-1} \boldsymbol a_i \boldsymbol b_i * \boldsymbol a \cdot \boldsymbol b = \sum_{i=0}^{n-1} \boldsymbol a_i \boldsymbol b_i
* @f] * @f]
* @see dot() const, operator-(), Vector2::perpendicular() * @see dot() const, @ref operator-(),
* @ref Vector2::perpendicular()
* @todoc Explicit reference when Doxygen can handle const
*/ */
static T dot(const Vector<size, T>& a, const Vector<size, T>& b) { static T dot(const Vector<size, T>& a, const Vector<size, T>& b) {
return (a*b).sum(); return (a*b).sum();
@ -104,7 +106,8 @@ template<std::size_t size, class T> class Vector {
* Expects that both vectors are normalized. @f[ * Expects that both vectors are normalized. @f[
* \theta = acos \left( \frac{\boldsymbol a \cdot \boldsymbol b}{|\boldsymbol a| |\boldsymbol b|} \right) = acos (\boldsymbol a \cdot \boldsymbol b) * \theta = acos \left( \frac{\boldsymbol a \cdot \boldsymbol b}{|\boldsymbol a| |\boldsymbol b|} \right) = acos (\boldsymbol a \cdot \boldsymbol b)
* @f] * @f]
* @see isNormalized(), Quaternion::angle(), Complex::angle() * @see @ref isNormalized(), @ref Quaternion::angle(),
* @ref Complex::angle()
*/ */
static Rad<T> angle(const Vector<size, T>& normalizedA, const Vector<size, T>& normalizedB); static Rad<T> angle(const Vector<size, T>& normalizedA, const Vector<size, T>& normalizedB);
@ -188,6 +191,7 @@ template<std::size_t size, class T> class Vector {
* @return One-dimensional array of `size` length. * @return One-dimensional array of `size` length.
* *
* @see operator[]() * @see operator[]()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
T* data() { return _data; } T* data() { return _data; }
constexpr const T* data() const { return _data; } /**< @overload */ constexpr const T* data() const { return _data; } /**< @overload */
@ -195,7 +199,7 @@ template<std::size_t size, class T> class Vector {
/** /**
* @brief Value at given position * @brief Value at given position
* *
* @see data() * @see @ref data()
*/ */
T& operator[](std::size_t pos) { return _data[pos]; } T& operator[](std::size_t pos) { return _data[pos]; }
constexpr T operator[](std::size_t pos) const { return _data[pos]; } /**< @overload */ constexpr T operator[](std::size_t pos) const { return _data[pos]; } /**< @overload */
@ -231,7 +235,7 @@ template<std::size_t size, class T> class Vector {
* @f[ * @f[
* |\boldsymbol a \cdot \boldsymbol a - 0| < \epsilon^2 \cong \epsilon * |\boldsymbol a \cdot \boldsymbol a - 0| < \epsilon^2 \cong \epsilon
* @f] * @f]
* @see dot(), normalized() * @see @ref dot(), @ref normalized()
*/ */
bool isZero() const { bool isZero() const {
return Implementation::isZeroSquared(dot()); return Implementation::isZeroSquared(dot());
@ -243,7 +247,7 @@ template<std::size_t size, class T> class Vector {
* The vector is normalized if it has unit length: @f[ * The vector is normalized if it has unit length: @f[
* |\boldsymbol a \cdot \boldsymbol a - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon * |\boldsymbol a \cdot \boldsymbol a - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon
* @f] * @f]
* @see dot(), normalized() * @see @ref dot(), @ref normalized()
*/ */
bool isNormalized() const { bool isNormalized() const {
return Implementation::isNormalizedSquared(dot()); return Implementation::isNormalizedSquared(dot());
@ -255,7 +259,7 @@ template<std::size_t size, class T> class Vector {
* @f[ * @f[
* \boldsymbol b_i = -\boldsymbol a_i * \boldsymbol b_i = -\boldsymbol a_i
* @f] * @f]
* @see Vector2::perpendicular() * @see @ref Vector2::perpendicular()
*/ */
Vector<size, T> operator-() const; Vector<size, T> operator-() const;
@ -276,7 +280,8 @@ template<std::size_t size, class T> class Vector {
/** /**
* @brief Add vector * @brief Add vector
* *
* @see operator+=(), sum() * @see operator+=(), @ref sum()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<size, T> operator+(const Vector<size, T>& other) const { Vector<size, T> operator+(const Vector<size, T>& other) const {
return Vector<size, T>(*this) += other; return Vector<size, T>(*this) += other;
@ -299,7 +304,7 @@ template<std::size_t size, class T> class Vector {
/** /**
* @brief Subtract vector * @brief Subtract vector
* *
* @see operator-=() * @see @ref operator-=()
*/ */
Vector<size, T> operator-(const Vector<size, T>& other) const { Vector<size, T> operator-(const Vector<size, T>& other) const {
return Vector<size, T>(*this) -= other; return Vector<size, T>(*this) -= other;
@ -313,6 +318,7 @@ template<std::size_t size, class T> class Vector {
* @f] * @f]
* @see operator*=(const Vector<size, T>&), * @see operator*=(const Vector<size, T>&),
* operator*=(Vector<size, Integral>&, FloatingPoint) * operator*=(Vector<size, Integral>&, FloatingPoint)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<size, T>& operator*=(T number) { Vector<size, T>& operator*=(T number) {
for(std::size_t i = 0; i != size; ++i) for(std::size_t i = 0; i != size; ++i)
@ -327,6 +333,7 @@ template<std::size_t size, class T> class Vector {
* @see operator*(const Vector<size, T>&) const, * @see operator*(const Vector<size, T>&) const,
* operator*=(T), operator*(T, const Vector<size, T>&), * operator*=(T), operator*(T, const Vector<size, T>&),
* operator*(const Vector<size, Integral>&, FloatingPoint) * operator*(const Vector<size, Integral>&, FloatingPoint)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<size, T> operator*(T number) const { Vector<size, T> operator*(T number) const {
return Vector<size, T>(*this) *= number; return Vector<size, T>(*this) *= number;
@ -340,6 +347,7 @@ template<std::size_t size, class T> class Vector {
* @f] * @f]
* @see operator/=(const Vector<size, T>&), * @see operator/=(const Vector<size, T>&),
* operator/=(Vector<size, Integral>&, FloatingPoint) * operator/=(Vector<size, Integral>&, FloatingPoint)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<size, T>& operator/=(T number) { Vector<size, T>& operator/=(T number) {
for(std::size_t i = 0; i != size; ++i) for(std::size_t i = 0; i != size; ++i)
@ -354,6 +362,7 @@ template<std::size_t size, class T> class Vector {
* @see operator/(const Vector<size, T>&) const, * @see operator/(const Vector<size, T>&) const,
* operator/=(T), operator/(T, const Vector<size, T>&), * operator/=(T), operator/(T, const Vector<size, T>&),
* operator/(const Vector<size, Integral>&, FloatingPoint) * operator/(const Vector<size, Integral>&, FloatingPoint)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<size, T> operator/(T number) const { Vector<size, T> operator/(T number) const {
return Vector<size, T>(*this) /= number; return Vector<size, T>(*this) /= number;
@ -367,6 +376,7 @@ template<std::size_t size, class T> class Vector {
* @f] * @f]
* @see operator*=(T), * @see operator*=(T),
* operator*=(Vector<size, Integral>&, const Vector<size, FloatingPoint>&) * operator*=(Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<size, T>& operator*=(const Vector<size, T>& other) { Vector<size, T>& operator*=(const Vector<size, T>& other) {
for(std::size_t i = 0; i != size; ++i) for(std::size_t i = 0; i != size; ++i)
@ -381,6 +391,7 @@ template<std::size_t size, class T> class Vector {
* @see operator*(T) const, operator*=(const Vector<size, T>&), * @see operator*(T) const, operator*=(const Vector<size, T>&),
* operator*(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&), * operator*(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&),
* @ref product() * @ref product()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<size, T> operator*(const Vector<size, T>& other) const { Vector<size, T> operator*(const Vector<size, T>& other) const {
return Vector<size, T>(*this) *= other; return Vector<size, T>(*this) *= other;
@ -394,6 +405,7 @@ template<std::size_t size, class T> class Vector {
* @f] * @f]
* @see operator/=(T), * @see operator/=(T),
* operator/=(Vector<size, Integral>&, const Vector<size, FloatingPoint>&) * operator/=(Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<size, T>& operator/=(const Vector<size, T>& other) { Vector<size, T>& operator/=(const Vector<size, T>& other) {
for(std::size_t i = 0; i != size; ++i) for(std::size_t i = 0; i != size; ++i)
@ -407,6 +419,7 @@ template<std::size_t size, class T> class Vector {
* *
* @see operator/(T) const, operator/=(const Vector<size, T>&), * @see operator/(T) const, operator/=(const Vector<size, T>&),
* operator/(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&) * operator/(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&)
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
Vector<size, T> operator/(const Vector<size, T>& other) const { Vector<size, T> operator/(const Vector<size, T>& other) const {
return Vector<size, T>(*this) /= other; return Vector<size, T>(*this) /= other;
@ -415,22 +428,24 @@ template<std::size_t size, class T> class Vector {
/** /**
* @brief Dot product of the vector * @brief Dot product of the vector
* *
* Should be used instead of length() for comparing vector length with * Should be used instead of @ref length() for comparing vector length
* other values, because it doesn't compute the square root. @f[ * with other values, because it doesn't compute the square root. @f[
* \boldsymbol a \cdot \boldsymbol a = \sum_{i=0}^{n-1} \boldsymbol a_i^2 * \boldsymbol a \cdot \boldsymbol a = \sum_{i=0}^{n-1} \boldsymbol a_i^2
* @f] * @f]
* @see dot(const Vector<size, T>&, const Vector<size, T>&), isNormalized() * @see @ref dot(const Vector<size, T>&, const Vector<size, T>&),
* @ref isNormalized()
*/ */
T dot() const { return dot(*this, *this); } T dot() const { return dot(*this, *this); }
/** /**
* @brief %Vector length * @brief %Vector length
* *
* See also dot() const which is faster for comparing length with other * See also @ref dot() const which is faster for comparing length with
* values. @f[ * other values. @f[
* |\boldsymbol a| = \sqrt{\boldsymbol a \cdot \boldsymbol a} * |\boldsymbol a| = \sqrt{\boldsymbol a \cdot \boldsymbol a}
* @f] * @f]
* @see lengthInverted(), Math::sqrt(), normalized(), resized() * @see @ref lengthInverted(), @ref Math::sqrt(), @ref normalized(),
* @ref resized()
* @todo something like std::hypot() for possibly better precision? * @todo something like std::hypot() for possibly better precision?
*/ */
T length() const { return std::sqrt(dot()); } T length() const { return std::sqrt(dot()); }
@ -441,14 +456,15 @@ template<std::size_t size, class T> class Vector {
* @f[ * @f[
* \frac{1}{|\boldsymbol a|} = \frac{1}{\sqrt{\boldsymbol a \cdot \boldsymbol a}} * \frac{1}{|\boldsymbol a|} = \frac{1}{\sqrt{\boldsymbol a \cdot \boldsymbol a}}
* @f] * @f]
* @see length(), Math::sqrtInverted(), normalized(), resized() * @see @ref length(), @ref Math::sqrtInverted(), @ref normalized(),
* @ref resized()
*/ */
T lengthInverted() const { return T(1)/length(); } T lengthInverted() const { return T(1)/length(); }
/** /**
* @brief Normalized vector (of unit length) * @brief Normalized vector (of unit length)
* *
* @see isNormalized(), lengthInverted(), resized() * @see @ref isNormalized(), @ref lengthInverted(), @ref resized()
*/ */
Vector<size, T> normalized() const { return *this*lengthInverted(); } Vector<size, T> normalized() const { return *this*lengthInverted(); }
@ -456,12 +472,12 @@ template<std::size_t size, class T> class Vector {
* @brief Resized vector * @brief Resized vector
* *
* Convenience equivalent to the following code. Due to operation order * Convenience equivalent to the following code. Due to operation order
* this function is faster than the obvious way of sizing normalized() * this function is faster than the obvious way of sizing
* vector. * @ref normalized() vector.
* @code * @code
* vec*(vec.lengthInverted()*length) // the brackets are important * vec*(vec.lengthInverted()*length) // the brackets are important
* @endcode * @endcode
* @see normalized() * @see @ref normalized()
*/ */
Vector<size, T> resized(T length) const { Vector<size, T> resized(T length) const {
return *this*(lengthInverted()*length); return *this*(lengthInverted()*length);
@ -473,7 +489,7 @@ template<std::size_t size, class T> class Vector {
* Returns vector projected onto @p line. @f[ * Returns vector projected onto @p line. @f[
* \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b * \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b
* @f] * @f]
* @see dot(), projectedOntoNormalized() * @see @ref dot(), @ref projectedOntoNormalized()
*/ */
Vector<size, T> projected(const Vector<size, T>& line) const { Vector<size, T> projected(const Vector<size, T>& line) const {
return line*dot(*this, line)/line.dot(); return line*dot(*this, line)/line.dot();
@ -482,8 +498,8 @@ template<std::size_t size, class T> class Vector {
/** /**
* @brief %Vector projected onto normalized line * @brief %Vector projected onto normalized line
* *
* Slightly faster alternative to projected(), expects @p line to be * Slightly faster alternative to @ref projected(), expects @p line to
* normalized. @f[ * be normalized. @f[
* \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b = * \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b =
* (\boldsymbol a \cdot \boldsymbol b) \boldsymbol b * (\boldsymbol a \cdot \boldsymbol b) \boldsymbol b
* @f] * @f]
@ -495,6 +511,7 @@ template<std::size_t size, class T> class Vector {
* @brief Sum of values in the vector * @brief Sum of values in the vector
* *
* @see operator+() * @see operator+()
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
T sum() const; T sum() const;
@ -502,6 +519,7 @@ template<std::size_t size, class T> class Vector {
* @brief Product of values in the vector * @brief Product of values in the vector
* *
* @see operator*(const Vector<size, T>&) const * @see operator*(const Vector<size, T>&) const
* @todoc Make explicit reference when Doxygen can handle operators
*/ */
T product() const; T product() const;
@ -533,6 +551,7 @@ template<std::size_t size, class T> class Vector {
@brief Multiply number with vector @brief Multiply number with vector
Same as Vector::operator*(T) const. Same as Vector::operator*(T) const.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class T> inline Vector<size, T> operator*( template<std::size_t size, class T> inline Vector<size, T> operator*(
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -552,6 +571,7 @@ template<std::size_t size, class T> inline Vector<size, T> operator*(
\boldsymbol c_i = \frac b {\boldsymbol a_i} \boldsymbol c_i = \frac b {\boldsymbol a_i}
@f] @f]
@see Vector::operator/(T) const @see Vector::operator/(T) const
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class T> inline Vector<size, T> operator/( template<std::size_t size, class T> inline Vector<size, T> operator/(
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -842,6 +862,7 @@ operator>>(const Vector<size, Integral>& vector,
Similar to Vector::operator*=(T), except that the multiplication is done in Similar to Vector::operator*=(T), except that the multiplication is done in
floating-point. The computation is done in-place. floating-point. The computation is done in-place.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class Integral, class FloatingPoint> inline template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -861,6 +882,7 @@ operator*=(Vector<size, Integral>& vector, FloatingPoint number) {
Similar to Vector::operator*(T) const, except that the multiplication is done Similar to Vector::operator*(T) const, except that the multiplication is done
in floating-point. in floating-point.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class Integral, class FloatingPoint> inline template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -877,6 +899,7 @@ operator*(const Vector<size, Integral>& vector, FloatingPoint number) {
@brief Multiply floating-point number with integral vector @brief Multiply floating-point number with integral vector
Same as operator*(const Vector<size, Integral>&, FloatingPoint). Same as operator*(const Vector<size, Integral>&, FloatingPoint).
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class FloatingPoint, class Integral> inline template<std::size_t size, class FloatingPoint, class Integral> inline
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -893,6 +916,7 @@ operator*(FloatingPoint number, const Vector<size, Integral>& vector) {
Similar to Vector::operator/=(T), except that the division is done in Similar to Vector::operator/=(T), except that the division is done in
floating-point. The computation is done in-place. floating-point. The computation is done in-place.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class Integral, class FloatingPoint> inline template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -912,6 +936,7 @@ operator/=(Vector<size, Integral>& vector, FloatingPoint number) {
Similar to Vector::operator/(T) const, except that the division is done in Similar to Vector::operator/(T) const, except that the division is done in
floating-point. floating-point.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class Integral, class FloatingPoint> inline template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -929,6 +954,7 @@ operator/(const Vector<size, Integral>& vector, FloatingPoint number) {
Similar to Vector::operator*=(const Vector<size, T>&), except that the Similar to Vector::operator*=(const Vector<size, T>&), except that the
multiplication is done in floating-point. The computation is done in-place. multiplication is done in floating-point. The computation is done in-place.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class Integral, class FloatingPoint> inline template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -946,10 +972,11 @@ operator*=(Vector<size, Integral>& a, const Vector<size, FloatingPoint>& b) {
/** @relates Vector /** @relates Vector
@brief Multiply integral vector with floating-point vector component-wise @brief Multiply integral vector with floating-point vector component-wise
Similar to Vector::operator*(const Vector<size, T>&) const, except that the Similar to Vector::operator*(const Vector<size, T>&) const, except that
multiplication is done in floating-point. The result is always integral vector, the multiplication is done in floating-point. The result is always integral
convert both arguments to the same floating-point type to have floating-point vector, convert both arguments to the same floating-point type to have
result. floating-point result.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class Integral, class FloatingPoint> inline template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -966,6 +993,7 @@ operator*(const Vector<size, Integral>& a, const Vector<size, FloatingPoint>& b)
@brief Multiply floating-point vector with integral vector component-wise @brief Multiply floating-point vector with integral vector component-wise
Same as operator*(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&). Same as operator*(const Vector<size, Integral>&, const Vector<size, FloatingPoint>&).
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class FloatingPoint, class Integral> inline template<std::size_t size, class FloatingPoint, class Integral> inline
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -982,6 +1010,7 @@ operator*(const Vector<size, FloatingPoint>& a, const Vector<size, Integral>& b)
Similar to Vector::operator/=(const Vector<size, T>&), except that the division Similar to Vector::operator/=(const Vector<size, T>&), except that the division
is done in floating-point. The computation is done in-place. is done in floating-point. The computation is done in-place.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class Integral, class FloatingPoint> inline template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
@ -999,10 +1028,11 @@ operator/=(Vector<size, Integral>& a, const Vector<size, FloatingPoint>& b) {
/** @relates Vector /** @relates Vector
@brief Divide integral vector with floating-point vector component-wise @brief Divide integral vector with floating-point vector component-wise
Similar to Vector::operator/(const Vector<size, T>&) const, except that the Similar to Vector::operator/(const Vector<size, T>&) const, except that
division is done in floating-point. The result is always integral vector, the division is done in floating-point. The result is always integral vector,
convert both arguments to the same floating-point type to have floating-point convert both arguments to the same floating-point type to have floating-point
result. result.
@todoc Make explicit reference when Doxygen can handle operators
*/ */
template<std::size_t size, class Integral, class FloatingPoint> inline template<std::size_t size, class Integral, class FloatingPoint> inline
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT

28
src/Magnum/Math/Vector2.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Vector2 * @brief Class @ref Magnum::Math::Vector2
*/ */
#include "Magnum/Math/Vector.h" #include "Magnum/Math/Vector.h"
@ -38,7 +38,8 @@ namespace Magnum { namespace Math {
@tparam T Data type @tparam T Data type
See @ref matrix-vector for brief introduction. See @ref matrix-vector for brief introduction.
@see Magnum::Vector2, Magnum::Vector2i, Magnum::Vector2ui, Magnum::Vector2d @see @ref Magnum::Vector2, @ref Magnum::Vector2i, @ref Magnum::Vector2ui,
@ref Magnum::Vector2d
@configurationvalueref{Magnum::Math::Vector2} @configurationvalueref{Magnum::Math::Vector2}
*/ */
template<class T> class Vector2: public Vector<2, T> { template<class T> class Vector2: public Vector<2, T> {
@ -50,15 +51,15 @@ template<class T> class Vector2: public Vector<2, T> {
* @code * @code
* Matrix3::translation(Vector2::xAxis(5.0f)); // same as Matrix3::translation({5.0f, 0.0f}); * Matrix3::translation(Vector2::xAxis(5.0f)); // same as Matrix3::translation({5.0f, 0.0f});
* @endcode * @endcode
* @see yAxis(), xScale(), Matrix3::right() * @see @ref yAxis(), @ref xScale(), @ref Matrix3::right()
*/ */
constexpr static Vector2<T> xAxis(T length = T(1)) { return {length, T(0)}; } constexpr static Vector2<T> xAxis(T length = T(1)) { return {length, T(0)}; }
/** /**
* @brief %Vector in direction of Y axis (up) * @brief %Vector in direction of Y axis (up)
* *
* See xAxis() for more information. * See @ref xAxis() for more information.
* @see yScale(), Matrix3::up() * @see @ref yScale(), @ref Matrix3::up()
*/ */
constexpr static Vector2<T> yAxis(T length = T(1)) { return {T(0), length}; } constexpr static Vector2<T> yAxis(T length = T(1)) { return {T(0), length}; }
@ -69,15 +70,15 @@ template<class T> class Vector2: public Vector<2, T> {
* @code * @code
* Matrix3::scaling(Vector2::xScale(-2.0f)); // same as Matrix3::scaling({-2.0f, 1.0f}); * Matrix3::scaling(Vector2::xScale(-2.0f)); // same as Matrix3::scaling({-2.0f, 1.0f});
* @endcode * @endcode
* @see yScale(), xAxis() * @see @ref yScale(), @ref xAxis()
*/ */
constexpr static Vector2<T> xScale(T scale) { return {scale, T(1)}; } constexpr static Vector2<T> xScale(T scale) { return {scale, T(1)}; }
/** /**
* @brief Scaling vector in direction of Y axis (height) * @brief Scaling vector in direction of Y axis (height)
* *
* See xScale() for more information. * See @ref xScale() for more information.
* @see yAxis() * @see @ref yAxis()
*/ */
constexpr static Vector2<T> yScale(T scale) { return {T(1), scale}; } constexpr static Vector2<T> yScale(T scale) { return {T(1), scale}; }
@ -85,12 +86,13 @@ template<class T> class Vector2: public Vector<2, T> {
* @brief 2D cross product * @brief 2D cross product
* *
* 2D version of cross product, also called perp-dot product, * 2D version of cross product, also called perp-dot product,
* equivalent to calling Vector3::cross() with Z coordinate set to `0` * equivalent to calling @ref Vector3::cross() with Z coordinate set to
* and extracting only Z coordinate from the result (X and Y * `0` and extracting only Z coordinate from the result (X and Y
* coordinates are always zero). @f[ * coordinates are always zero). @f[
* \boldsymbol a \times \boldsymbol b = \boldsymbol a_\bot \cdot \boldsymbol b = a_xb_y - a_yb_x * \boldsymbol a \times \boldsymbol b = \boldsymbol a_\bot \cdot \boldsymbol b = a_xb_y - a_yb_x
* @f] * @f]
* @see perpendicular(), dot(const Vector&, const Vector&) * @see @ref perpendicular(),
* @ref dot(const Vector<size, T>&, const Vector<size, T>&)
*/ */
static T cross(const Vector2<T>& a, const Vector2<T>& b) { static T cross(const Vector2<T>& a, const Vector2<T>& b) {
return Vector<2, T>::dot(a.perpendicular(), b); return Vector<2, T>::dot(a.perpendicular(), b);
@ -131,7 +133,9 @@ template<class T> class Vector2: public Vector<2, T> {
* Returns vector rotated 90° counterclockwise. @f[ * Returns vector rotated 90° counterclockwise. @f[
* \boldsymbol v_\bot = \begin{pmatrix} -v_y \\ v_x \end{pmatrix} * \boldsymbol v_\bot = \begin{pmatrix} -v_y \\ v_x \end{pmatrix}
* @f] * @f]
* @see cross(), dot(const Vector&, const Vector&), operator-() const * @see @ref cross(),
* @ref dot(const Vector<size, T>&, const Vector<size, T>&),
* @ref operator-() const
*/ */
Vector2<T> perpendicular() const { return {-y(), x()}; } Vector2<T> perpendicular() const { return {-y(), x()}; }

9
src/Magnum/Math/Vector3.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::Vector3 * @brief Class @ref Magnum::Math::Vector3
*/ */
#include "Magnum/Math/Vector2.h" #include "Magnum/Math/Vector2.h"
@ -39,7 +39,8 @@ namespace Magnum { namespace Math {
@tparam T Data type @tparam T Data type
See @ref matrix-vector for brief introduction. See @ref matrix-vector for brief introduction.
@see Magnum::Vector3, Magnum::Vector3i, Magnum::Vector3ui, Magnum::Vector3d @see @ref Magnum::Vector3, @ref Magnum::Vector3i, @ref Magnum::Vector3ui,
@ref Magnum::Vector3d
@configurationvalueref{Magnum::Math::Vector3} @configurationvalueref{Magnum::Math::Vector3}
*/ */
template<class T> class Vector3: public Vector<3, T> { template<class T> class Vector3: public Vector<3, T> {
@ -107,7 +108,7 @@ template<class T> class Vector3: public Vector<3, T> {
* \boldsymbol a \times \boldsymbol b = * \boldsymbol a \times \boldsymbol b =
* \begin{pmatrix}a_yb_z - a_zb_y \\ a_zb_y - a_xb_z \\ a_xb_y - a_yb_x \end{pmatrix} * \begin{pmatrix}a_yb_z - a_zb_y \\ a_zb_y - a_xb_z \\ a_xb_y - a_yb_x \end{pmatrix}
* @f] * @f]
* @see Vector2::cross() * @see @ref Vector2::cross()
*/ */
static Vector3<T> cross(const Vector3<T>& a, const Vector3<T>& b) { static Vector3<T> cross(const Vector3<T>& a, const Vector3<T>& b) {
return swizzle<'y', 'z', 'x'>(a)*swizzle<'z', 'x', 'y'>(b) - return swizzle<'y', 'z', 'x'>(a)*swizzle<'z', 'x', 'y'>(b) -
@ -199,7 +200,7 @@ template<class T> class Vector3: public Vector<3, T> {
* @brief XY part of the vector * @brief XY part of the vector
* @return First two components of the vector * @return First two components of the vector
* *
* @see swizzle() * @see @ref swizzle()
*/ */
Vector2<T>& xy() { return Vector2<T>::from(Vector<3, T>::data()); } Vector2<T>& xy() { return Vector2<T>::from(Vector<3, T>::data()); }
constexpr const Vector2<T> xy() const { return {x(), y()}; } /**< @overload */ constexpr const Vector2<T> xy() const { return {x(), y()}; } /**< @overload */

3
src/Magnum/Math/Vector4.h

@ -38,7 +38,8 @@ namespace Magnum { namespace Math {
@tparam T Data type @tparam T Data type
See @ref matrix-vector for brief introduction. See @ref matrix-vector for brief introduction.
@see Magnum::Vector4, Magnum::Vector4i, Magnum::Vector4ui, Magnum::Vector4d @see @ref Magnum::Vector4, @ref Magnum::Vector4i, @ref Magnum::Vector4ui,
@ref Magnum::Vector4d
@configurationvalueref{Magnum::Math::Vector4} @configurationvalueref{Magnum::Math::Vector4}
*/ */
template<class T> class Vector4: public Vector<4, T> { template<class T> class Vector4: public Vector<4, T> {

Loading…
Cancel
Save