vector: add polar_to_cartesian

This commit is contained in:
Danny Robson 2015-04-02 14:57:30 +11:00
parent 4aa35f4c70
commit a300f99b87
4 changed files with 86 additions and 2 deletions

View File

@ -277,6 +277,7 @@ TEST_BIN = \
test/signal \
test/stringid \
test/uri \
test/vector \
test/version

67
test/vector.cpp Normal file
View File

@ -0,0 +1,67 @@
#include "vector.hpp"
#include "maths.hpp"
using util::vector;
using util::vector2f;
void
test_polar (void)
{
static const struct {
util::vector2f polar;
util::vector2f cartesian;
const char *desc;
} TESTS[] {
{
{ 0.f, 0.f },
{ 0.f, 0.f },
"all zeroes"
},
{
{ 1.f, 0.f },
{ 1.f, 0.f },
"unit length, unrotated"
},
{
{ 1.f, PI_f / 2.f },
{ 0.f, 1.f },
"unit length, rotated"
},
{
{ 1.f, 2 * PI_f },
{ 1.f, 0.f },
"full rotation, unit length"
}
};
for (const auto &t: TESTS) {
// Compare the difference of cartesian representations. Don't use
// direct equality comparisons here as the numeric stability can be
// poor and we have nice whole numbers to start with.
auto in_cart = t.cartesian;
auto to_cart = util::polar_to_cartesian (t.polar);
CHECK_LT ((in_cart - to_cart).magnitude (), 0.00001f);
// Compare polar representations. Make sure to normalise them first.
auto in_polar = t.polar;
auto to_polar = util::cartesian_to_polar (t.cartesian);
in_polar[1] = std::fmod (in_polar[1], 2 * PI_f);
to_polar[1] = std::fmod (to_polar[1], 2 * PI_f);
CHECK_EQ (in_polar, to_polar);
}
}
int
main ()
{
test_polar ();
}

View File

@ -98,10 +98,12 @@ util::vector<S,T>::normalised (void) const {
return out;
}
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
template <typename T>
util::vector<2,T>
util::polar_to_cartesian (util::vector<2,T> v) {
util::polar_to_cartesian (util::vector<2,T> v)
{
return util::vector<2,T> {
v[0] * std::cos (v[1]),
v[0] * std::sin (v[1])
@ -111,6 +113,18 @@ util::polar_to_cartesian (util::vector<2,T> v) {
//-----------------------------------------------------------------------------
template <typename T>
util::vector<2,T>
util::cartesian_to_polar (util::vector<2,T> v)
{
return util::vector<2,T> {
std::hypot (v.x, v.y),
std::atan2 (v.y, v.x)
};
}
///////////////////////////////////////////////////////////////////////////////
template <typename T>
util::vector<3,T>
util::cross (const util::vector<3,T> &a,
const util::vector<3,T> &b)
@ -236,6 +250,7 @@ INSTANTIATE(double)
//-----------------------------------------------------------------------------
namespace util {
template vector<2,float> polar_to_cartesian (util::vector<2,float>);
template vector<2,float> cartesian_to_polar (util::vector<2,float>);
template <> vector<1,float> random (void) { util::vector<1,float> out; randomise (out.data); return out; }
template <> vector<2,float> random (void) { util::vector<2,float> out; randomise (out.data); return out; }

View File

@ -57,6 +57,7 @@ namespace util {
// free vector operators
template <typename T> vector<2,T> polar_to_cartesian (vector<2,T>);
template <typename T> vector<2,T> cartesian_to_polar (vector<2,T>);
template <typename T> vector<3,T> cross (const vector<3,T>&, const vector<3,T>&);
template <typename T> vector<3,T> spherical_to_cartesian (const vector<3,T>&);