SA_Maths
Sapphire Suite's C++ Maths Library
Loading...
Searching...
No Matches
Lerp.hpp
Go to the documentation of this file.
1// Copyright (c) 2023 Sapphire development team. All Rights Reserved.
2
3#pragma once
4
5#ifndef SAPPHIRE_MATHS_LERP_GUARD
6#define SAPPHIRE_MATHS_LERP_GUARD
7
8#include <algorithm>
9
10#include <SA/Maths/Debug.hpp>
11
14
25namespace SA
26{
27 namespace Maths
28 {
42 template <typename T>
43 T LerpUnclamped(const T& _start, const T& _end, float _alpha) noexcept
44 {
45 return (1.0f - _alpha) * _start + _alpha * _end;
46 }
47
61 template <typename T>
62 T Lerp(const T& _start, const T& _end, float _alpha) noexcept
63 {
64 SA_WARN(_alpha >= 0.0f && _alpha <= 1.0f, SA.Maths, (L"Alpha[%1] clamped to range [0, 1]! Use LerpUnclamped if intended instead.", _alpha));
65
66 return LerpUnclamped(_start, _end, std::clamp(_alpha, 0.0f, 1.0f));
67 }
68
69
83 template <typename T>
84 T SLerpUnclamped(const T& _start, const T& _end, float _alpha) noexcept
85 {
91 using TScalar = typename T::Type;
92 TScalar dot = T::Dot(_start, _end);
93 TScalar endSign = 1.0f;
94
95 // Ensure shortest path between _start and _end.
96 if (dot < 0.0f)
97 {
98 endSign = -1.0f;
99 dot = -dot;
100 }
101
102 // Dot too close to 1 cause angle of 0.
103 if (Maths::Equals1(dot))
104 {
105 // Basic linear interpolation.
106 return LerpUnclamped(_start, _end * endSign, _alpha);
107 }
108
109 // Current angle.
110 Rad<TScalar> angle = ACos(dot);
111
112 // Angle step to apply.
113 Rad<TScalar> angleStep = angle * _alpha;
114
115 // Current sin.
116 TScalar sin = Sin(angle);
117
118 // Sin Step ratio.
119 TScalar sinRatio = Sin(angleStep) / sin;
120
121 TScalar s0 = Cos(angleStep) - dot * sinRatio;
122
123 return s0 * _start + sinRatio * _end * endSign;
124 }
125
139 template <typename T>
140 T SLerp(const T& _start, const T& _end, float _alpha) noexcept
141 {
142 SA_WARN(_alpha >= 0.0f && _alpha <= 1.0f, SA.Maths, (L"Alpha[%1] clamped to range [0, 1]! Use LerpUnclamped if intended instead.", _alpha));
143
144 return SLerpUnclamped(_start, _end, std::clamp(_alpha, 0.0f, 1.0f));
145 }
146 }
147}
148
157#endif // GUARD
Cosinus method implementation.
constexpr T Cos(Rad< T > _in) noexcept
Compute the cosine of the input.
Definition Cos.hpp:32
constexpr Rad< T > ACos(T _in) noexcept
Compute the arc-cosine of the input.
Definition Cos.hpp:46
Maths module Debug compatibility definition.
T LerpUnclamped(const T &_start, const T &_end, float _alpha) noexcept
Unclamped Lerp from _start to _end at _alpha.
Definition Lerp.hpp:43
T SLerp(const T &_start, const T &_end, float _alpha) noexcept
Clamped SLerp from _start to _end at _alpha.
Definition Lerp.hpp:140
T Lerp(const T &_start, const T &_end, float _alpha) noexcept
Clamped Lerp from _start to _end at _time.
Definition Lerp.hpp:62
T SLerpUnclamped(const T &_start, const T &_end, float _alpha) noexcept
Unclamped SLerp from _start to _end at _alpha.
Definition Lerp.hpp:84
Sinus method implementation.
constexpr T Sin(Rad< T > _in) noexcept
Compute the sine of the input.
Definition Sin.hpp:32
Maths Radian type.
Definition Radian.hpp:36