Skip to content

Commit 1fe5e6e

Browse files
committed
added new class
1 parent a33ee63 commit 1fe5e6e

File tree

10 files changed

+280
-47
lines changed

10 files changed

+280
-47
lines changed

SECURITY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
## Reporting a Vulnerability
44

5-
Please report security issues to `orange-cpp@yandex.com`
5+
Please report security issues to `orange-cpp@yandex.ru`

include/omath/Angle.hpp

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
//
2+
// Created by Orange on 11/30/2024.
3+
//
4+
5+
#pragma once
6+
#include "omath/Angles.hpp"
7+
8+
9+
namespace omath
10+
{
11+
enum class AngleFlags
12+
{
13+
Normalized = 0,
14+
Clamped = 1,
15+
};
16+
17+
template<class Type, Type min = 0, Type max = 360, AngleFlags flags = AngleFlags::Normalized>
18+
requires std::is_arithmetic_v<Type>
19+
class Angle
20+
{
21+
Type m_angle;
22+
public:
23+
24+
constexpr explicit Angle(const Type& degrees)
25+
{
26+
if constexpr (flags == AngleFlags::Normalized)
27+
m_angle = angles::WrapAngle(degrees, min, max);
28+
29+
else if constexpr (flags == AngleFlags::Clamped)
30+
m_angle = std::clamp(degrees, min, max);
31+
else
32+
{
33+
static_assert(false);
34+
std::unreachable();
35+
}
36+
}
37+
38+
[[nodiscard]]
39+
constexpr static Angle FromDegrees(const Type& degrees)
40+
{
41+
return {degrees};
42+
}
43+
44+
[[nodiscard]]
45+
constexpr static Angle FromRadians(const Type& degrees)
46+
{
47+
return {angles::RadiansToDegrees(degrees)};
48+
}
49+
50+
[[nodiscard]]
51+
constexpr const Type& operator*() const
52+
{
53+
return m_angle;
54+
}
55+
56+
[[nodiscard]]
57+
constexpr Type& operator*()
58+
{
59+
return m_angle;
60+
}
61+
62+
[[nodiscard]]
63+
constexpr const Type& Value() const
64+
{
65+
return **std::as_const(this);
66+
}
67+
68+
[[nodiscard]]
69+
constexpr Type& Value()
70+
{
71+
return **this;
72+
}
73+
74+
[[nodiscard]]
75+
constexpr Type AsRadians() const
76+
{
77+
return angles::RadiansToDegrees(m_angle);
78+
}
79+
80+
[[nodiscard]]
81+
Type Sin() const
82+
{
83+
return std::sin(AsRadians());
84+
}
85+
86+
[[nodiscard]]
87+
Type Cos() const
88+
{
89+
return std::sin(AsRadians());
90+
}
91+
92+
[[nodiscard]]
93+
Type Tan() const
94+
{
95+
return std::tan(AsRadians());
96+
}
97+
98+
[[nodiscard]]
99+
Type Atan() const
100+
{
101+
return std::atan(AsRadians());
102+
}
103+
104+
[[nodiscard]]
105+
Type Cot() const
106+
{
107+
return Cos() / Sin();
108+
}
109+
110+
[[nodiscard]]
111+
constexpr Angle& operator+=(const Type& other)
112+
{
113+
if constexpr (flags == AngleFlags::Normalized)
114+
m_angle = angles::WrapAngle(m_angle + other, min, max);
115+
116+
else if constexpr (flags == AngleFlags::Clamped)
117+
m_angle = std::clamp(m_angle + other, min, max);
118+
else
119+
{
120+
static_assert(false);
121+
std::unreachable();
122+
}
123+
124+
return *this;
125+
}
126+
127+
[[nodiscard]]
128+
constexpr Angle& operator-=(const Type& other)
129+
{
130+
return operator+=(-other);
131+
}
132+
133+
[[nodiscard]]
134+
constexpr Angle& operator+(const Type& other)
135+
{
136+
if constexpr (flags == AngleFlags::Normalized)
137+
return {angles::WrapAngle(m_angle + other, min, max)};
138+
139+
else if constexpr (flags == AngleFlags::Clamped)
140+
return {std::clamp(m_angle + other, min, max)};
141+
142+
else
143+
static_assert(false);
144+
145+
std::unreachable();
146+
}
147+
148+
[[nodiscard]]
149+
constexpr Angle& operator-(const Type& other)
150+
{
151+
return operator+(-other);
152+
}
153+
154+
155+
};
156+
}

include/omath/Angles.hpp

+31-12
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,23 @@
44

55
#pragma once
66
#include <numbers>
7+
#include <cmath>
8+
79

810
namespace omath::angles
911
{
10-
template<class type>
11-
requires std::is_floating_point_v<type>
12-
[[nodiscard]] constexpr float RadiansToDegrees(const type& radians)
12+
template<class Type>
13+
requires std::is_floating_point_v<Type>
14+
[[nodiscard]] constexpr float RadiansToDegrees(const Type& radians)
1315
{
14-
return radians * (type(180) / std::numbers::pi_v<type>);
16+
return radians * (Type(180) / std::numbers::pi_v<Type>);
1517
}
1618

17-
template<class type>
18-
requires std::is_floating_point_v<type>
19-
[[nodiscard]] constexpr float DegreesToRadians(const type& degrees)
19+
template<class Type>
20+
requires std::is_floating_point_v<Type>
21+
[[nodiscard]] constexpr float DegreesToRadians(const Type& degrees)
2022
{
21-
return degrees * (std::numbers::pi_v<type> / type(180));
23+
return degrees * (std::numbers::pi_v<Type> / Type(180));
2224
}
2325

2426
template<class type>
@@ -32,14 +34,31 @@ namespace omath::angles
3234
return RadiansToDegrees(vertFov);
3335
}
3436

35-
template<class type>
36-
requires std::is_floating_point_v<type>
37-
[[nodiscard]] type VerticalFovToHorizontal(const type& vertFov, const type& aspect)
37+
template<class Type>
38+
requires std::is_floating_point_v<Type>
39+
[[nodiscard]] Type VerticalFovToHorizontal(const Type& vertFov, const Type& aspect)
3840
{
3941
const auto fovRad = DegreesToRadians(vertFov);
4042

41-
const auto horFov = type(2) * std::atan(std::tan(fovRad / type(2)) * aspect);
43+
const auto horFov = Type(2) * std::atan(std::tan(fovRad / Type(2)) * aspect);
4244

4345
return RadiansToDegrees(horFov);
4446
}
47+
48+
template<class Type>
49+
requires std::is_arithmetic_v<Type>
50+
[[nodiscard]] Type WrapAngle(const Type& angle, const Type& min, const Type& max)
51+
{
52+
if (angle <= max && angle >= min)
53+
return angle;
54+
55+
const Type range = max - min;
56+
57+
Type wrappedAngle = std::fmod(angle - min, range);
58+
59+
if (wrappedAngle < 0)
60+
wrappedAngle += range;
61+
62+
return wrappedAngle + min;
63+
}
4564
}

0 commit comments

Comments
 (0)