WIP vector: spherical/cartesian conversion

This commit is contained in:
Danny Robson 2017-11-02 18:11:16 +11:00
parent badba6de3b
commit 3ad0339474
3 changed files with 78 additions and 30 deletions

View File

@ -102,6 +102,56 @@ test_euler (util::TAP::logger &tap)
} }
///////////////////////////////////////////////////////////////////////////////
void
test_spherical (util::TAP::logger &tap)
{
static constexpr struct {
util::vector3f spherical;
util::vector3f cartesian;
const char *message;
} TESTS[] = {
{ { 1, 0, 0 }, { 0, 0, 1 }, "+zero", },
{ { -1, 0, 0 }, { 0, 0, -1 }, "-zero", },
{ { 1, 1, 0 }, { 1, 0, 0 }, "90-theta", },
{ { 1, 2, 0 }, { 0, 0, -1 }, "180-theta", },
{ { 1, 3, 0 }, { -1, 0, 0 }, "270-theta", },
{ { 1, 0, 1 }, { 0, 0, 1 }, "90-phi", },
{ { 1, 0, 2 }, { 0, 0, 1 }, "180-phi", },
{ { 1, 0, 3 }, { 0, 0, 1 }, "270-phi", },
{ { 1, 1, 1 }, { 0, 1, 0 }, "90-theta, 90-phi" },
{ { 1, 1, 2 }, { -1, 0, 0 }, "90-theta, 180-phi" },
{ { 1, 1, 3 }, { 0, -1, 0 }, "90-theta, 270-phi" },
};
for (const auto t: TESTS) {
tap.expect_eq (
util::spherical_to_cartesian (t.spherical),
t.cartesian,
"%s, spherical-cartesian",
t.message
);
tap.expect_eq (
util::cartesian_to_spherical (t.cartesian),
t.spherical,
"%s, cartesian-spherical",
t.message
);
}
{
//util::vector3f s { 1, .5f, 2/3.f };
//util::vector3f c { 0.35f, 0.61f, 0.71f };
//tap.expect_eq
}
};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
int int
main () main ()
@ -110,6 +160,7 @@ main ()
test_polar (tap); test_polar (tap);
test_euler (tap); test_euler (tap);
test_spherical (tap);
tap.expect (!is_normalised (util::vector3f::zeros ()), "zeros isn't normalised"); tap.expect (!is_normalised (util::vector3f::zeros ()), "zeros isn't normalised");
tap.expect (!is_normalised (util::vector3f::ones ()), "ones isn't normalised"); tap.expect (!is_normalised (util::vector3f::ones ()), "ones isn't normalised");

View File

@ -84,34 +84,6 @@ template util::vector2f util::to_euler (util::vector3f);
template util::vector2d util::to_euler (util::vector3d); template util::vector2d util::to_euler (util::vector3d);
//-----------------------------------------------------------------------------
template <typename T>
vector<3,T>
util::spherical_to_cartesian (vector<3,T> s)
{
return vector<3,T> {
s.x * sin (s.y) * cos (s.z),
s.x * sin (s.y) * sin (s.z),
s.x * cos (s.y),
};
}
//-----------------------------------------------------------------------------
template <typename T>
vector<3,T>
util::cartesian_to_spherical (vector<3,T> c)
{
T mag = norm (c);
return vector<3,T> {
mag,
acos (c.z / mag),
atan2 (c.y, c.x)
};
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T> template <size_t S, typename T>
void void

View File

@ -23,6 +23,7 @@
#include "json/fwd.hpp" #include "json/fwd.hpp"
#include <cstddef> #include <cstddef>
#include <cmath>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -56,8 +57,32 @@ namespace util {
template <typename T> vector<2,T> polar_to_cartesian (vector<2,T>); 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<2,T> cartesian_to_polar (vector<2,T>);
template <typename T> vector<3,T> spherical_to_cartesian (vector<3,T>); // convert vector in spherical coordinates (r,theta,phi) with theta
template <typename T> vector<3,T> cartesian_to_spherical (vector<3,T>); // inclination and phi azimuth to cartesian coordinates (x,y,z)
template <typename T>
constexpr vector<3,T>
spherical_to_cartesian (const vector<3,T> s)
{
return {
s.x * std::sin (s.y) * std::cos (s.z),
s.x * std::sin (s.y) * std::sin (s.z),
s.x * std::cos (s.y)
};
}
// convert vector in cartesian coordinates (x,y,z) to spherical
// coordinates (r,theta,phi) with theta inclination and phi azimuth.
template <typename T>
constexpr vector<3,T>
cartesian_to_spherical (vector<3,T> c)
{
auto r = norm (c);
return {
r,
std::acos (c.z / r),
std::atan (c.y / c.z)
};
}
template <typename T> vector<2,T> to_euler (vector<3,T>); template <typename T> vector<2,T> to_euler (vector<3,T>);
template <typename T> vector<3,T> from_euler (vector<2,T>); template <typename T> vector<3,T> from_euler (vector<2,T>);