Browse Source

Add reflect and refract function

pull/420/head
Nghia Truong 6 years ago
parent
commit
b846cc5829
  1. 26
      src/Magnum/Math/Functions.h
  2. 16
      src/Magnum/Math/Test/FunctionsTest.cpp

26
src/Magnum/Math/Functions.h

@ -654,6 +654,32 @@ template<std::size_t size, class T> inline Vector<size, T> sqrtInverted(const Ve
return Vector<size, T>(T(1))/Math::sqrt(a); return Vector<size, T>(T(1))/Math::sqrt(a);
} }
/**
@brief Reflect a vector off a surface given the surface outward normal. Note that the normal vector must be normalized.
@m_keyword{reflect(),GLSL reflect(),}
*/
template<std::size_t size, class T> inline Vector<size, T> reflect(const Vector<size, T>& v, const Vector<size, T>& n) {
return v - T(2) * dot(v, n) * n;
}
/**
@brief Refract a vector through a medium given the surface outward normal and ratio of indices of refraction eta. Note that the normal vector must be normalized.
@m_keyword{refract(),GLSL refract(),}
*/
template<std::size_t size, class T> inline Vector<size, T> refract(const Vector<size, T>& v, const Vector<size, T>& n, T eta) {
const Vector<size, T> vi = v.normalized();
const T dt = dot(vi, n);
const T k = T(1) - eta * eta * (T(1) - dt * dt);
if(k > 0) {
return eta * (vi - n * dt) - n * std::sqrt(k);
}
return Vector<size, T>{};
}
/*@}*/ /*@}*/
}} }}

16
src/Magnum/Math/Test/FunctionsTest.cpp

@ -68,6 +68,9 @@ struct FunctionsTest: Corrade::TestSuite::Tester {
void isInfVector(); void isInfVector();
void isNan(); void isNan();
void isNanfVector(); void isNanfVector();
void reflect();
void refract();
void trigonometric(); void trigonometric();
void trigonometricWithBase(); void trigonometricWithBase();
@ -124,6 +127,9 @@ FunctionsTest::FunctionsTest() {
&FunctionsTest::isInfVector, &FunctionsTest::isInfVector,
&FunctionsTest::isNan, &FunctionsTest::isNan,
&FunctionsTest::isNanfVector, &FunctionsTest::isNanfVector,
&FunctionsTest::reflect,
&FunctionsTest::refract,
&FunctionsTest::trigonometric, &FunctionsTest::trigonometric,
&FunctionsTest::trigonometricWithBase, &FunctionsTest::trigonometricWithBase,
@ -440,6 +446,16 @@ void FunctionsTest::isNanfVector() {
CORRADE_COMPARE(Math::isNan(Vector3{0.3f, -Constants::inf(), 1.0f}), Math::BoolVector<3>{0x00}); CORRADE_COMPARE(Math::isNan(Vector3{0.3f, -Constants::inf(), 1.0f}), Math::BoolVector<3>{0x00});
} }
void FunctionsTest::reflect() {
CORRADE_COMPARE(Math::reflect(Vector3{1.0f, 2.0f, 3.0f}, Vector3{0.0f, 1.0f, 0.0f}), (Vector3{1.0f, -2.0f, 3.0f}));
CORRADE_COMPARE(Math::reflect(Vector3{2.0f, 1.0f, 1.0f}, Vector3{1.0f, -1.0f, 1.0f}.normalized()), (Vector3{2.0f / 3.0f, 2.0f + 1.0f/3.0f, -1.0f/3.0f}));
}
void FunctionsTest::refract() {
CORRADE_COMPARE(Math::refract(Vector3{1.0f, 0.0f, 1.0f}, Vector3{0.0f, 0.0f, -1.0f}, Float{1.0f / 1.5f}), (Vector3{0.471405, 0, 0.881917}));
CORRADE_COMPARE(Math::refract(Vector3{4.0f, 1.0f, 1.0f}, Vector3{0.0f, -2.0f, -1.0f}.normalized(), Float{1.0f / 1.5f}), (Vector3{0.628539, 0.661393, 0.409264}));
}
void FunctionsTest::trigonometric() { void FunctionsTest::trigonometric() {
CORRADE_COMPARE(Math::sin(Deg(30.0f)), 0.5f); CORRADE_COMPARE(Math::sin(Deg(30.0f)), 0.5f);
CORRADE_COMPARE(Math::sin(Rad(Constants::pi()/6)), 0.5f); CORRADE_COMPARE(Math::sin(Rad(Constants::pi()/6)), 0.5f);

Loading…
Cancel
Save