Browse Source

math: add orthogonal() and orthonormal() for 3-component vectors.

undefined
Sam Hocevar 11 years ago
parent
commit
7108f8566d
2 changed files with 43 additions and 0 deletions
  1. +17
    -0
      src/lol/math/vector.h
  2. +26
    -0
      test/unit/vector.cpp

+ 17
- 0
src/lol/math/vector.h View File

@@ -1298,12 +1298,29 @@ extern Quat<T> slerp(Quat<T> const &qa, Quat<T> const &qb, T f);
}

#define LOL_VEC_3_FUNS(tname, tprefix, type) \
/* Return the cross product (vector product) of "a" and "b" */ \
tprefix \
inline tname<type> cross(tname<type> const &a, tname<type> const &b) \
{ \
return tname<type>((type)(a.y * b.z - a.z * b.y), \
(type)(a.z * b.x - a.x * b.z), \
(type)(a.x * b.y - a.y * b.x)); \
} \
\
/* Return a vector that is orthogonal to "a" */ \
tprefix \
inline tname<type> orthogonal(tname<type> const &a) \
{ \
return lol::abs(a.x) > lol::abs(a.z) \
? tname<type>(-a.y, a.x, (type)0) \
: tname<type>((type)0, -a.z, a.y); \
} \
\
/* Return a vector that is orthonormal to "a" */ \
tprefix \
inline tname<type> orthonormal(tname<type> const &a) \
{ \
return normalize(orthogonal(a)); \
}

#define LOL_BINARY_NONVECTOR_OPS(tname, tprefix, type) \


+ 26
- 0
test/unit/vector.cpp View File

@@ -124,6 +124,32 @@ LOLUNIT_FIXTURE(VectorTest)
LOLUNIT_ASSERT_EQUAL(c.w, 0.0f);
LOLUNIT_ASSERT_EQUAL(a3, a1);
}

LOLUNIT_TEST(Orthogonal)
{
vec3 a(1.f, 0.f, 0.f);
vec3 b(0.f, 1.f, 0.f);
vec3 c(0.f, 0.f, 1.f);

LOLUNIT_ASSERT_DOUBLES_EQUAL(dot(orthogonal(a), a), 0.f, 1e-6f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(dot(orthogonal(b), b), 0.f, 1e-6f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(dot(orthogonal(c), c), 0.f, 1e-6f);

/* The length of the orthogonal vector should be at least
* sqrt(2)/2 times the length of the original vector. */
LOLUNIT_ASSERT_GREATER(length(orthogonal(a)), 0.7f);
LOLUNIT_ASSERT_GREATER(length(orthogonal(b)), 0.7f);
LOLUNIT_ASSERT_GREATER(length(orthogonal(c)), 0.7f);

LOLUNIT_ASSERT_DOUBLES_EQUAL(dot(orthonormal(a), a), 0.f, 1e-6f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(dot(orthonormal(b), b), 0.f, 1e-6f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(dot(orthonormal(c), c), 0.f, 1e-6f);

/* The length of the orthonormal vector should be 1. */
LOLUNIT_ASSERT_DOUBLES_EQUAL(length(orthonormal(a)), 1.f, 1e-6f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(length(orthonormal(b)), 1.f, 1e-6f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(length(orthonormal(c)), 1.f, 1e-6f);
}
};

} /* namespace lol */


Loading…
Cancel
Save