Files
tp/include/JSystem/JMath/JMATrigonometric.h
T

184 lines
4.3 KiB
C++
Raw Normal View History

2021-03-28 22:49:05 +02:00
#ifndef JMATRIGONOMETRIC_H
#define JMATRIGONOMETRIC_H
#include "dolphin/types.h"
#include <cmath>
#include <utility>
#ifdef __cplusplus
extern "C" {
#endif
extern double asin(double);
extern double atan(double);
#ifdef __cplusplus
}
#endif
2025-09-04 07:56:59 -07:00
namespace JMath {
2024-02-11 00:29:35 -05:00
template<typename T>
struct TAngleConstant_;
2024-04-12 00:10:30 -06:00
/**
* @ingroup jsystem-jmath
*
*/
2024-02-11 00:29:35 -05:00
template<>
struct TAngleConstant_<f32> {
2024-10-15 16:59:31 -04:00
static f32 RADIAN_DEG090() { return 1.5707964f; }
static f32 RADIAN_DEG180() { return 3.1415927f; }
static f32 RADIAN_DEG360() { return 6.2831855f; }
static f32 RADIAN_TO_DEGREE_FACTOR() { return 180.0f / RADIAN_DEG180(); }
2024-02-11 00:29:35 -05:00
};
2024-04-12 00:10:30 -06:00
/**
* @ingroup jsystem-jmath
*
*/
2024-04-04 19:05:50 -04:00
template<int N, typename T>
struct TSinCosTable {
2024-04-04 19:05:50 -04:00
std::pair<T, T> table[1 << N];
2021-12-23 20:56:02 -08:00
TSinCosTable() {
init();
}
void init() {
for (int i = 0; i < 1 << N; i++) {
table[i].first = sin((i * f64(TAngleConstant_<f32>::RADIAN_DEG360())) / (1 << N));
table[i].second = cos((i * f64(TAngleConstant_<f32>::RADIAN_DEG360())) / (1 << N));
}
}
2024-04-04 19:05:50 -04:00
T sinShort(s16 v) const { return table[(u16)v >> (16U - N)].first; }
T cosShort(s16 v) const { return table[(u16)v >> (16U - N)].second; }
2023-08-01 10:17:21 +03:00
2025-12-08 00:49:42 -05:00
inline T sinLap(T v) const {
2024-04-04 19:05:50 -04:00
if (v < (T)0.0) {
return -table[(u16)(-(T)(1 << N) * v) & ((1 << N) - 1)].first;
2023-08-01 10:17:21 +03:00
}
2024-04-04 19:05:50 -04:00
return table[(u16)((T)(1 << N) * v) & ((1 << N) - 1)].first;
2023-08-01 10:17:21 +03:00
}
2025-12-08 00:49:42 -05:00
inline T sinDegree(T degree) const {
2024-04-04 19:05:50 -04:00
if (degree < (T)0.0) {
2024-10-23 19:25:13 -04:00
return -table[(u16)(-((T)(1 << N) / (T)360.0) * degree) & ((1 << N) - 1)].first;
}
2024-10-23 19:25:13 -04:00
return table[(u16)(((T)(1 << N) / (T)360.0) * degree) & ((1 << N) - 1)].first;
}
2025-12-08 00:49:42 -05:00
inline T cosDegree(T degree) const {
2024-04-04 19:05:50 -04:00
if (degree < (T)0.0) {
degree = -degree;
}
2024-10-23 19:25:13 -04:00
return table[(u16)(((T)(1 << N) / (T)360.0) * degree) & ((1 << N) - 1)].second;
}
2024-02-11 00:29:35 -05:00
2025-12-08 00:49:42 -05:00
inline T sinRadian(T radian) const {
2024-04-04 19:05:50 -04:00
if (radian < (T)0.0) {
return -table[(u16)(-(T)(1 << N) / TAngleConstant_<T>::RADIAN_DEG360() * radian) & ((1 << N) - 1)].first;
2024-02-11 00:29:35 -05:00
}
2024-04-04 19:05:50 -04:00
return table[(u16)((T)(1 << N) / TAngleConstant_<T>::RADIAN_DEG360() * radian) & ((1 << N) - 1)].first;
2024-02-11 00:29:35 -05:00
}
};
2024-04-12 00:10:30 -06:00
/**
* @ingroup jsystem-jmath
*
*/
2026-01-07 09:53:53 -08:00
template<int N, typename T>
struct TAtanTable {
2026-01-07 09:53:53 -08:00
T table[N + 1];
u8 pad[0x1C];
TAtanTable() {
init();
}
void init() {
// u32 cast needed for cmplwi instead of cmpwi
for (int i = 0; i < (u32)N; i++) {
table[i] = atan(i / (f64)N);
}
table[0] = 0.0f;
table[N] = TAngleConstant_<T>::RADIAN_DEG180() / 4.0f;
}
};
2024-04-12 00:10:30 -06:00
/**
* @ingroup jsystem-jmath
*
*/
2025-09-04 07:56:59 -07:00
template<int N, typename T>
struct TAsinAcosTable {
2026-01-07 09:53:53 -08:00
T table[N + 1];
u8 pad[0x1C];
2024-10-15 16:59:31 -04:00
TAsinAcosTable() {
init();
}
void init() {
for (int i = 0; i < 1024; i++) {
table[i] = asin(i / (f64)N);
}
table[0] = 0.0f;
table[N] = TAngleConstant_<T>::RADIAN_DEG180() / 4.0f;
}
2025-09-04 07:56:59 -07:00
T acos_(T x) const {
2024-10-15 16:59:31 -04:00
if (x >= 1.0f) {
return 0.0f;
} else if (x <= -1.0f) {
2025-09-04 07:56:59 -07:00
return TAngleConstant_<T>::RADIAN_DEG180();
2024-10-15 16:59:31 -04:00
} else if (x < 0.0f) {
2025-09-04 07:56:59 -07:00
return table[(u32)(-x * 1023.5f)] + TAngleConstant_<T>::RADIAN_DEG090();
2024-10-15 16:59:31 -04:00
} else {
2025-09-04 07:56:59 -07:00
return TAngleConstant_<T>::RADIAN_DEG090() - table[(u32)(x * 1023.5f)];
2024-10-15 16:59:31 -04:00
}
}
2025-09-04 07:56:59 -07:00
T acosDegree(T x) const {
return acos_(x) * TAngleConstant_<T>::RADIAN_TO_DEGREE_FACTOR();
2024-10-15 16:59:31 -04:00
}
};
2024-04-04 19:05:50 -04:00
extern TSinCosTable<13, f32> sincosTable_;
2026-01-07 09:53:53 -08:00
extern TAtanTable<1024, f32> atanTable_;
2025-09-04 07:56:59 -07:00
extern TAsinAcosTable<1024, f32> asinAcosTable_;
2024-10-15 16:59:31 -04:00
inline f32 acosDegree(f32 x) {
return asinAcosTable_.acosDegree(x);
}
}; // namespace JMath
2025-08-12 03:18:42 +03:00
inline f32 JMACosShort(s16 v) {
2023-02-26 22:18:40 -08:00
return JMath::sincosTable_.cosShort(v);
}
inline f32 JMASinShort(s16 v) {
return JMath::sincosTable_.sinShort(v);
2021-12-23 20:56:02 -08:00
}
2023-02-26 22:18:40 -08:00
inline f32 JMASCos(s16 v) {
2025-08-12 03:18:42 +03:00
return JMACosShort(v);
2023-02-26 22:18:40 -08:00
}
inline f32 JMASSin(s16 v) {
return JMASinShort(v);
2021-12-23 20:56:02 -08:00
}
2023-08-01 10:17:21 +03:00
inline f32 JMASinLap(f32 v) {
return JMath::sincosTable_.sinLap(v);
}
inline f32 JMASinDegree(f32 degree) {
return JMath::sincosTable_.sinDegree(degree);
}
inline f32 JMACosDegree(f32 degree) {
return JMath::sincosTable_.cosDegree(degree);
}
2024-02-11 00:29:35 -05:00
inline f32 JMASinRadian(f32 radian) {
return JMath::sincosTable_.sinRadian(radian);
}
2021-03-28 22:49:05 +02:00
#endif /* JMATRIGONOMETRIC_H */