Browse Source

Math: added convenience function Vector::isNormalized().

pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
3db2aa13c4
  1. 4
      src/Math/Matrix3.h
  2. 8
      src/Math/Matrix4.h
  3. 9
      src/Math/Test/VectorTest.cpp
  4. 27
      src/Math/Vector.h

4
src/Math/Matrix3.h

@ -93,10 +93,10 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @param normal Normal of the line through which to reflect
*
* Expects that the normal is normalized.
* @see Matrix4::reflection()
* @see Matrix4::reflection(), Vector::isNormalized()
*/
static Matrix3<T> reflection(const Vector2<T>& normal) {
CORRADE_ASSERT(TypeTraits<T>::equals(normal.dot(), T(1)),
CORRADE_ASSERT(normal.isNormalized(),
"Math::Matrix3::reflection(): normal must be normalized", {});
return from(Matrix<2, T>() - T(2)*normal*RectangularMatrix<1, 2, T>(normal).transposed(), {});
}

8
src/Math/Matrix4.h

@ -88,10 +88,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* faster alternatives like rotationX(), rotationY() and rotationZ().
* @see rotation() const, Quaternion::rotation(), DualQuaternion::rotation(),
* Matrix3::rotation(Rad), Vector3::xAxis(), Vector3::yAxis(),
* Vector3::zAxis()
* Vector3::zAxis(), Vector::isNormalized()
*/
static Matrix4<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) {
CORRADE_ASSERT(TypeTraits<T>::equals(normalizedAxis.dot(), T(1)),
CORRADE_ASSERT(normalizedAxis.isNormalized(),
"Math::Matrix4::rotation(): axis must be normalized", {});
T sine = std::sin(T(angle));
@ -181,10 +181,10 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @param normal Normal of the plane through which to reflect
*
* Expects that the normal is normalized.
* @see Matrix3::reflection()
* @see Matrix3::reflection(), Vector::isNormalized()
*/
static Matrix4<T> reflection(const Vector3<T>& normal) {
CORRADE_ASSERT(TypeTraits<T>::equals(normal.dot(), T(1)),
CORRADE_ASSERT(normal.isNormalized(),
"Math::Matrix4::reflection(): normal must be normalized", {});
return from(Matrix<3, T>() - T(2)*normal*RectangularMatrix<1, 3, T>(normal).transposed(), {});
}

9
src/Math/Test/VectorTest.cpp

@ -62,6 +62,8 @@ class VectorTest: public Corrade::TestSuite::Tester {
void constructConversion();
void constructCopy();
void isNormalized();
void convert();
void data();
@ -107,6 +109,8 @@ VectorTest::VectorTest() {
&VectorTest::constructConversion,
&VectorTest::constructCopy,
&VectorTest::isNormalized,
&VectorTest::convert,
&VectorTest::data,
@ -188,6 +192,11 @@ void VectorTest::constructCopy() {
CORRADE_COMPARE(b, Vector4(1.0f, 3.5f, 4.0f, -2.7f));
}
void VectorTest::isNormalized() {
CORRADE_VERIFY(!Vector3(1.0f, 2.0f, -1.0f).isNormalized());
CORRADE_VERIFY(Vector3(0.0f, 1.0f, 0.0f).isNormalized());
}
void VectorTest::convert() {
Vec3 a{1.5f, 2.0f, -3.5f};
Vector3 b(1.5f, 2.0f, -3.5f);

27
src/Math/Vector.h

@ -99,10 +99,10 @@ template<std::size_t size, class T> class Vector {
* 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)
* @f]
* @see Quaternion::angle(), Complex::angle()
* @see isNormalized(), Quaternion::angle(), Complex::angle()
*/
inline static Rad<T> angle(const Vector<size, T>& normalizedA, const Vector<size, T>& normalizedB) {
CORRADE_ASSERT(TypeTraits<T>::equals(normalizedA.dot(), T(1)) && TypeTraits<T>::equals(normalizedB.dot(), T(1)),
CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(),
"Math::Vector::angle(): vectors must be normalized", Rad<T>(std::numeric_limits<T>::quiet_NaN()));
return Rad<T>(std::acos(dot(normalizedA, normalizedB)));
}
@ -245,6 +245,18 @@ template<std::size_t size, class T> class Vector {
return out;
}
/**
* @brief Whether the vector is normalized
*
* The vector is normalized if it has unit length: @f[
* |\boldsymbol a|^2 = |\boldsymbol a| = 1
* @f]
* @see dot(), normalized()
*/
inline bool isNormalized() const {
return TypeTraits<T>::equals(dot(), T(1));
}
/**
* @brief Negated vector
*
@ -422,7 +434,7 @@ template<std::size_t size, class T> class Vector {
* 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
* @f]
* @see dot(const Vector&, const Vector&)
* @see dot(const Vector&, const Vector&), isNormalized()
*/
inline T dot() const {
return dot(*this, *this);
@ -435,13 +447,18 @@ template<std::size_t size, class T> class Vector {
* values. @f[
* |\boldsymbol a| = \sqrt{\boldsymbol a \cdot \boldsymbol a}
* @f]
* @see isNormalized()
* @todo something like std::hypot() for possibly better precision?
*/
inline T length() const {
return std::sqrt(dot());
}
/** @brief Normalized vector (of unit length) */
/**
* @brief Normalized vector (of unit length)
*
* @see isNormalized()
*/
inline Vector<size, T> normalized() const {
return *this/length();
}
@ -468,7 +485,7 @@ template<std::size_t size, class T> class Vector {
* @f]
*/
inline Vector<size, T> projectedOntoNormalized(const Vector<size, T>& line) const {
CORRADE_ASSERT(TypeTraits<T>::equals(line.dot(), T(1)), "Math::Vector::projectedOntoNormalized(): line must be normalized", (Vector<size, T>(std::numeric_limits<T>::quiet_NaN())));
CORRADE_ASSERT(line.isNormalized(), "Math::Vector::projectedOntoNormalized(): line must be normalized", (Vector<size, T>(std::numeric_limits<T>::quiet_NaN())));
return line*dot(*this, line);
}

Loading…
Cancel
Save