#ifndef SPROUT_DARKROOM_COORDS_VECTOR_HPP #define SPROUT_DARKROOM_COORDS_VECTOR_HPP #include #include #include #include #include #include namespace sprout { namespace darkroom { namespace coords { // // x // y // z // template inline SPROUT_CONSTEXPR auto x(T&& t) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<0>(sprout::forward(t)))) -> decltype(sprout::darkroom::access::get<0>(sprout::forward(t))) { return sprout::darkroom::access::get<0>(sprout::forward(t)); } template inline SPROUT_CONSTEXPR auto y(T&& t) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<1>(sprout::forward(t)))) -> decltype(sprout::darkroom::access::get<1>(sprout::forward(t))) { return sprout::darkroom::access::get<1>(sprout::forward(t)); } template inline SPROUT_CONSTEXPR auto z(T&& t) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::darkroom::access::get<2>(sprout::forward(t)))) -> decltype(sprout::darkroom::access::get<2>(sprout::forward(t))) { return sprout::darkroom::access::get<2>(sprout::forward(t)); } // // vector3d // typedef sprout::tuples::tuple vector3d; // // length_sq // template inline SPROUT_CONSTEXPR typename sprout::darkroom::access::unit::type length_sq(Vector const& vec) { return sprout::darkroom::coords::x(vec) * sprout::darkroom::coords::x(vec) + sprout::darkroom::coords::y(vec) * sprout::darkroom::coords::y(vec) + sprout::darkroom::coords::z(vec) * sprout::darkroom::coords::z(vec) ; } // // length // template inline SPROUT_CONSTEXPR typename sprout::darkroom::access::unit::type length(Vector const& vec) { return sprout::sqrt(sprout::darkroom::coords::length_sq(vec)); } // // add // template inline SPROUT_CONSTEXPR Vector1 add(Vector1 const& lhs, Vector2 const& rhs) { return sprout::tuples::remake( lhs, sprout::darkroom::coords::x(lhs) + sprout::darkroom::coords::x(rhs), sprout::darkroom::coords::y(lhs) + sprout::darkroom::coords::y(rhs), sprout::darkroom::coords::z(lhs) + sprout::darkroom::coords::z(rhs) ); } // // sub // template inline SPROUT_CONSTEXPR Vector1 sub(Vector1 const& lhs, Vector2 const& rhs) { return sprout::tuples::remake( lhs, sprout::darkroom::coords::x(lhs) - sprout::darkroom::coords::x(rhs), sprout::darkroom::coords::y(lhs) - sprout::darkroom::coords::y(rhs), sprout::darkroom::coords::z(lhs) - sprout::darkroom::coords::z(rhs) ); } // // scale // template inline SPROUT_CONSTEXPR Vector scale(Vector const& lhs, Fac const& rhs) { return sprout::tuples::remake( lhs, sprout::darkroom::coords::x(lhs) * rhs, sprout::darkroom::coords::y(lhs) * rhs, sprout::darkroom::coords::z(lhs) * rhs ); } // // dot // template inline SPROUT_CONSTEXPR typename sprout::darkroom::access::unit::type dot(Vector const& lhs, Vector const& rhs) { return sprout::darkroom::coords::x(lhs) * sprout::darkroom::coords::x(rhs) + sprout::darkroom::coords::y(lhs) * sprout::darkroom::coords::y(rhs) + sprout::darkroom::coords::z(lhs) * sprout::darkroom::coords::z(rhs) ; } // // cross // template inline SPROUT_CONSTEXPR Vector1 cross(Vector1 const& lhs, Vector2 const& rhs) { return sprout::tuples::remake( lhs, sprout::darkroom::coords::y(lhs) * sprout::darkroom::coords::z(rhs) - sprout::darkroom::coords::z(lhs) * sprout::darkroom::coords::y(rhs) , sprout::darkroom::coords::y(lhs) * sprout::darkroom::coords::x(rhs) - sprout::darkroom::coords::x(lhs) * sprout::darkroom::coords::y(rhs) , sprout::darkroom::coords::x(lhs) * sprout::darkroom::coords::y(rhs) - sprout::darkroom::coords::y(lhs) * sprout::darkroom::coords::x(rhs) ); } // // normalize // namespace detail { template inline SPROUT_CONSTEXPR Vector normalize_impl( Vector const& vec, typename sprout::darkroom::access::unit::type const& len ) { return sprout::tuples::remake( vec, sprout::darkroom::coords::x(vec) / len, sprout::darkroom::coords::y(vec) / len, sprout::darkroom::coords::z(vec) / len ); } } // namespace detail template inline SPROUT_CONSTEXPR Vector normalize(Vector const& vec) { return sprout::darkroom::coords::detail::normalize_impl( vec, sprout::darkroom::coords::length(vec) ); } // // resize // template inline SPROUT_CONSTEXPR Vector resize(Vector const& lhs, Fac const& rhs) { return sprout::darkroom::coords::detail::normalize_impl( lhs, sprout::darkroom::coords::length(lhs) / rhs ); } // // reflect // template inline SPROUT_CONSTEXPR Incident reflect(Incident const& incid, Normal const& nor) { return sprout::darkroom::coords::sub( incid, sprout::darkroom::coords::scale(nor, sprout::darkroom::coords::dot(incid, nor) * 2) ); } } // namespace coords } // namespace darkroom } // namespace sprout #endif // #ifndef SPROUT_DARKROOM_COORDS_VECTOR_HPP