Program Listing for File trigonometry.hpp

Return to documentation for file (/home/runner/work/Legion-Engine/Legion-Engine/legion/engine/core/math/trigonometry.hpp)

#pragma once

#include <core/math/precision.hpp>
#include <core/platform/platform.hpp>
#include <core/math/constants.hpp>
#include <cmath>

namespace legion::core::math
{
#pragma region primitive
    template<class T>
    constexpr T rad2deg_c()
    {
        return T(180) / pi<T>();
    }

    template <class T>
    constexpr T rad2deg(T v)
    {
        return rad2deg_c<T>() * v;
    }


    template <class T>
    constexpr T deg2rad_c()
    {
        return pi<T>() / T(180);
    }

    template <class T>
    constexpr T deg2rad(T v)
    {
        return deg2rad_c<T>() * v;
    }
#pragma endregion

    template <data_precision p = data_precision::bit32>
    class angle
    {
    public:
        using storage_type = precision_chooser_t<p>;

        angle(const angle& other) = default;
        angle(angle&& other) noexcept = default;
        angle& operator=(const angle& other) = default;
        angle& operator=(angle&& other) noexcept = default;
        ~angle() = default;

        static constexpr angle deg(storage_type value);

        static constexpr angle rad(storage_type value);

        L_NODISCARD constexpr storage_type as_degrees() const;

        L_NODISCARD constexpr storage_type as_radians() const;

        storage_type sin();

        storage_type cos();

        storage_type tan();

        static angle arcsin(storage_type v);

        static angle arccos(storage_type v);

        static angle arctan(storage_type v);

        static angle arctan2(storage_type y, storage_type x);

    private:
        angle(storage_type v) : m_angle_value(v) {}

        //the default is radians!
        storage_type m_angle_value;
    };

    template <data_precision p>
    typename angle<p>::storage_type angle<p>::sin()
    {
        return std::sin(m_angle_value);
    }

    template <data_precision p>
    typename angle<p>::storage_type angle<p>::cos()
    {
        return std::cos(m_angle_value);
    }

    template <data_precision p>
    typename angle<p>::storage_type angle<p>::tan()
    {
        return std::tan(m_angle_value);
    }

    template <data_precision p>
    angle<p> angle<p>::arcsin(storage_type v)
    {
        return angle<p>::rad(std::asin(v));
    }

    template <data_precision p>
    angle<p> angle<p>::arccos(storage_type v)
    {
        return angle<p>::rad(std::acos(v));
    }

    template <data_precision p>
    angle<p> angle<p>::arctan(storage_type v)
    {
        return angle<p>::rad(std::atan(v));
    }

    template <data_precision p>
    angle<p> angle<p>::arctan2(storage_type y, storage_type x)
    {
        return angle<p>::rad(std::atan2(y, x));
    }


    template <data_precision p>
    constexpr angle<p> angle<p>::deg(storage_type value)
    {
        return angle<p>(deg2rad(value));
    }

    template <data_precision p>
    constexpr angle<p> angle<p>::rad(storage_type value)
    {
        return angle<p>(value);
    }

    template <data_precision p>
    constexpr typename angle<p>::storage_type angle<p>::as_degrees() const
    {
        return rad2deg(m_angle_value);
    }

    template <data_precision p>
    constexpr typename angle<p>::storage_type angle<p>::as_radians() const
    {
        return m_angle_value;
    }

    using anglef = angle<>;
    using angled = angle<data_precision::bit64>;
    using angleld = angle<data_precision::lots>;

}