SH4ZAM! 0.1.0
Fast math library for the Sega Dreamcast's SH4 CPU
Loading...
Searching...
No Matches
shz_trig.h
Go to the documentation of this file.
1/*! \file
2 * \brief Trigonometry functions and macros.
3 * \ingroup trig
4 *
5 * This file provides an API offering fast versions of trigonometry functions.
6 *
7 * \author 2025, 2026 Falco Girgis
8 * \author 2025 Paul Cercueil
9 *
10 * \copyright MIT License
11 */
12
13#ifndef SHZ_TRIG_H
14#define SHZ_TRIG_H
15
16#include "shz_scalar.h"
17
18/*! \defgroup trig Trigonometry
19 \brief Trig functions and utilities.
20
21 The following API provides a series of routines implementing trigonometric
22 functions. While some of these are specialized, many are meant to be
23 drop-in replacements for the equivalent functions provided by <math.h>.
24*/
25
26//! Single-precision floating-point PI approximation (do not use M_PI!)
27#define SHZ_F_PI 3.1415926f
28//! Single-precision FP PI approximation divided by 2.
29#define SHZ_F_PI_2 (SHZ_F_PI * 0.5f)
30//! Single-precision FP PI approximation divided by 4.
31#define SHZ_F_PI_4 (SHZ_F_PI * 0.25f)
32//! Multiplicative factor for passing the FSCA instruction angles in radians
33#define SHZ_FSCA_RAD_FACTOR 10430.37835f
34//! Multiplicative factor for passing the FSCA instrution angles in degrees
35#define SHZ_FSCA_DEG_FACTOR 182.04444443f
36//! Maximum FP error for FSCA instruction
37#define SHZ_FSCA_ERROR_MAX 4.76837158e-7
38
39//! Converts the given angle in degrees to radians
40#define SHZ_DEG_TO_RAD(deg) ((deg) * SHZ_F_PI / 180.0f)
41//! Converts the given angle in radians to degrees
42#define SHZ_RAD_TO_DEG(rad) ((rad) * 180.0f / SHZ_F_PI)
43
44SHZ_DECLS_BEGIN
45
46/*! Pair representing the sine and cosine of a given angle.
47 *
48 * The SH4 provides a single instruction, `FSCA`, for retrieving fast
49 * approximations of \b both the sine and cosine of a given angle. As such,
50 * when you need both values, it's most efficient to grab them both at once as
51 * a pair using this structure than it is to retrieve them separately.
52 *
53 * \sa shz_sincosf(), shz_sincosf_deg()
54 */
55typedef struct shz_sincos {
56 float sin; //!< sinf() approximation for the angle
57 float cos; //!< cosf() approximation for the angle
58} shz_sincos_t;
59
60//! Alternate C shz_sincos_t typedef for those who hate POSIX style.
61typedef shz_sincos_t shz_sincos;
62
63/*! \name Sin/Cos Pairs
64 \brief Routines involving precomputed sine + cosine pairs.
65 @{
66*/
67
68//! Returns sinf()/cosf() pairs for the given unsigned 16-bit angle in radians.
69SHZ_FORCE_INLINE shz_sincos_t shz_sincosu16(uint16_t radians16) SHZ_NOEXCEPT;
70
71//! Returns sinf()/cosf() pairs for the given floating-point angle in radians.
72SHZ_FORCE_INLINE shz_sincos_t shz_sincosf(float radians) SHZ_NOEXCEPT;
73
74//! Returns sinf/cosf() pairs for the given floating-point angle in degrees.
75SHZ_FORCE_INLINE shz_sincos_t shz_sincosf_deg(float degrees) SHZ_NOEXCEPT;
76
77//! Returns tanf() from the given pre-computed \p sincos pair.
78SHZ_FORCE_INLINE float shz_sincos_tanf(shz_sincos_t sincos) SHZ_NOEXCEPT;
79
80//! Returns the floating-point secant (1.0f / cosf(x)) from the given pre-computed \p sincos pair.
81SHZ_FORCE_INLINE float shz_sincos_secf(shz_sincos_t sincos) SHZ_NOEXCEPT;
82
83//! Returns the floating-point cosecant (1.0f / sinf(x)) from the given pre-computed \p sincos pair.
84SHZ_FORCE_INLINE float shz_sincos_cscf(shz_sincos_t sincos) SHZ_NOEXCEPT;
85
86//! Returns the floating-point cotangent (1.0f / tanf(x)) from the given pre-computed \p sincos pair.
87SHZ_FORCE_INLINE float shz_sincos_cotf(shz_sincos_t sincos) SHZ_NOEXCEPT;
88
89//! @}
90
91/*! \name Independent Functions
92 \brief Routines providing single trigonometric functions.
93 @{
94*/
95
96//! One-off routine for returning only sinf() from an angle in radians.
97SHZ_FORCE_INLINE float shz_sinf(float radians) SHZ_NOEXCEPT;
98
99//! One-off routine for returning only sinf() from an angle in degrees.
100SHZ_FORCE_INLINE float shz_sinf_deg(float degrees) SHZ_NOEXCEPT;
101
102//! One-off routine for returning only cosf() from an angle in radians.
103SHZ_FORCE_INLINE float shz_cosf(float radians) SHZ_NOEXCEPT;
104
105//! One-off routine for returning only cosf() from an angle in degrees.
106SHZ_FORCE_INLINE float shz_cosf_deg(float degrees) SHZ_NOEXCEPT;
107
108//! One-off routine for returning only tanf() from an angle in radians.
109SHZ_FORCE_INLINE float shz_tanf(float radians) SHZ_NOEXCEPT;
110
111//! One-off routine for returning only tanf() from an angle in degrees.
112SHZ_FORCE_INLINE float shz_tanf_deg(float degrees) SHZ_NOEXCEPT;
113
114//! One-off routine for returning only secant (1 / cos(x)) from an angle in radians.
115SHZ_FORCE_INLINE float shz_secf(float radians) SHZ_NOEXCEPT;
116
117//! One-off routine for returning only secant (1 / cos(x)) from an angle in degrees.
118SHZ_FORCE_INLINE float shz_secf_deg(float degrees) SHZ_NOEXCEPT;
119
120//! One-off routine for returning only cosecant (1 / sin(x)) from an angle in radians.
121SHZ_FORCE_INLINE float shz_cscf(float radians) SHZ_NOEXCEPT;
122
123//! One-off routine for returning only cosecant (1 / sin(x)) from an angle in degrees.
124SHZ_FORCE_INLINE float shz_cscf_deg(float degrees) SHZ_NOEXCEPT;
125
126//! One-off routine for returning only cotangent (1 / tan(x)) from an angle in radians.
127SHZ_FORCE_INLINE float shz_cotf(float radians) SHZ_NOEXCEPT;
128
129//! One-off routine for returning only cotangent (1 / cot(x)) from an angle in degrees.
130SHZ_FORCE_INLINE float shz_cotf_deg(float degrees) SHZ_NOEXCEPT;
131
132//! @}
133
134/*! \name Inverse Functions
135 \brief Routines providing inverse trigonometric functions.
136 @{
137*/
138
139//! Fast arcsine approximation; equivalent to C's asinf().
140SHZ_INLINE float shz_asinf(float x) SHZ_NOEXCEPT;
141
142//! Fast arccosine approximation; equivalent to C's acosf().
143SHZ_INLINE float shz_acosf(float x) SHZ_NOEXCEPT;
144
145//! Fast arctangent approximation for unit values between `0.0f` and `1.0f`.
146SHZ_FORCE_INLINE float shz_atanf_unit(float x) SHZ_NOEXCEPT;
147
148//! Fast arctangent approximation for values lying within the first quadrant (`>= 0.0f`).
149SHZ_INLINE float shz_atanf_q1(float x) SHZ_NOEXCEPT;
150
151//! Fast arctangent approximation; equvalent to C's atanf().
152SHZ_INLINE float shz_atanf(float x) SHZ_NOEXCEPT;
153
154//! Computes arctangent of `y / x`, using the signs of arguments to determine correct quadtrant. Equivalent to C's atan2f().
155SHZ_INLINE float shz_atan2f(float y, float x) SHZ_NOEXCEPT;
156
157//! Fast arcsecant/inverse secant approximation, taking units in radians.
158SHZ_INLINE float shz_asecf(float x) SHZ_NOEXCEPT;
159
160//! Fast arccosecant/inverse cosecant approximation; taking units in radians.
161SHZ_INLINE float shz_acscf(float x) SHZ_NOEXCEPT;
162
163//! Fast arccotangent/inverse cotangent approximation; taking units in radians.
164SHZ_INLINE float shz_acotf(float x) SHZ_NOEXCEPT;
165
166//! @}
167
168/*! \name Hyperbolic Functions
169 \brief Trigonometric functions for hyperbolas
170 @{
171*/
172
173//! Fast hyperbolic sine function.
174SHZ_INLINE float shz_sinhf(float x) SHZ_NOEXCEPT;
175
176//! Fast hyperbolic cosine function.
177SHZ_INLINE float shz_coshf(float x) SHZ_NOEXCEPT;
178
179//! Fast hyperbolic tangent function.
180SHZ_INLINE float shz_tanhf(float x) SHZ_NOEXCEPT;
181
182//! Fast hyperbolic cosecant function.
183SHZ_INLINE float shz_cschf(float x) SHZ_NOEXCEPT;
184
185//! Fast hyperbolic secant function.
186SHZ_INLINE float shz_sechf(float x) SHZ_NOEXCEPT;
187
188//! Fast hyperbolic cotangent function.
189SHZ_INLINE float shz_cothf(float x) SHZ_NOEXCEPT;
190
191//! @}
192
193/*! \name Inverse Hyperbolic Functions
194 \brief Inverse trigonometric functions for hyperbolas
195 @{
196*/
197
198//! Fast hyperbolic arcsine function.
199SHZ_INLINE float shz_asinhf(float x) SHZ_NOEXCEPT;
200
201//! Fast hyperbolic arccosine function.
202SHZ_INLINE float shz_acoshf(float x) SHZ_NOEXCEPT;
203
204//! Fast hyperbolic arctangent function.
205SHZ_INLINE float shz_atanhf(float x) SHZ_NOEXCEPT;
206
207//! Fast hyperbolic arccosecant function.
208SHZ_INLINE float shz_acschf(float x) SHZ_NOEXCEPT;
209
210//! Fast hyperbolic arcsecant function.
211SHZ_INLINE float shz_asechf(float x) SHZ_NOEXCEPT;
212
213//! Fast hyperbolic arccotangent function.
214SHZ_INLINE float shz_acothf(float x) SHZ_NOEXCEPT;
215
216//! @}
217
218#include "inline/shz_trig.inl.h"
219
220SHZ_DECLS_END
221
222#endif
float shz_cscf(float radians) SHZ_NOEXCEPT
One-off routine for returning only cosecant (1 / sin(x)) from an angle in radians.
float shz_acotf(float x) SHZ_NOEXCEPT
Fast arccotangent/inverse cotangent approximation; taking units in radians.
float shz_cothf(float x) SHZ_NOEXCEPT
Fast hyperbolic cotangent function.
float shz_tanf(float radians) SHZ_NOEXCEPT
One-off routine for returning only tanf() from an angle in radians.
#define SHZ_F_PI
Single-precision floating-point PI approximation (do not use M_PI!)
Definition shz_trig.h:27
float shz_cosf_deg(float degrees) SHZ_NOEXCEPT
One-off routine for returning only cosf() from an angle in degrees.
float shz_acosf(float x) SHZ_NOEXCEPT
Fast arccosine approximation; equivalent to C's acosf().
float shz_sincos_secf(shz_sincos_t sincos) SHZ_NOEXCEPT
Returns the floating-point secant (1.0f / cosf(x)) from the given pre-computed sincos pair.
shz_sincos_t shz_sincos
Alternate C shz_sincos_t typedef for those who hate POSIX style.
Definition shz_trig.h:61
float shz_sincos_cotf(shz_sincos_t sincos) SHZ_NOEXCEPT
Returns the floating-point cotangent (1.0f / tanf(x)) from the given pre-computed sincos pair.
shz_sincos_t shz_sincosu16(uint16_t radians16) SHZ_NOEXCEPT
Returns sinf()/cosf() pairs for the given unsigned 16-bit angle in radians.
float shz_acothf(float x) SHZ_NOEXCEPT
Fast hyperbolic arccotangent function.
float shz_cschf(float x) SHZ_NOEXCEPT
Fast hyperbolic cosecant function.
float shz_tanf_deg(float degrees) SHZ_NOEXCEPT
One-off routine for returning only tanf() from an angle in degrees.
float shz_atanf(float x) SHZ_NOEXCEPT
Fast arctangent approximation; equvalent to C's atanf().
float shz_atanf_unit(float x) SHZ_NOEXCEPT
Fast arctangent approximation for unit values between 0.0f and 1.0f.
float shz_secf(float radians) SHZ_NOEXCEPT
One-off routine for returning only secant (1 / cos(x)) from an angle in radians.
float shz_coshf(float x) SHZ_NOEXCEPT
Fast hyperbolic cosine function.
float shz_acoshf(float x) SHZ_NOEXCEPT
Fast hyperbolic arccosine function.
shz_sincos_t shz_sincosf_deg(float degrees) SHZ_NOEXCEPT
Returns sinf/cosf() pairs for the given floating-point angle in degrees.
shz_sincos_t shz_sincosf(float radians) SHZ_NOEXCEPT
Returns sinf()/cosf() pairs for the given floating-point angle in radians.
float shz_cosf(float radians) SHZ_NOEXCEPT
One-off routine for returning only cosf() from an angle in radians.
float shz_sincos_cscf(shz_sincos_t sincos) SHZ_NOEXCEPT
Returns the floating-point cosecant (1.0f / sinf(x)) from the given pre-computed sincos pair.
float shz_sinf(float radians) SHZ_NOEXCEPT
One-off routine for returning only sinf() from an angle in radians.
float shz_sechf(float x) SHZ_NOEXCEPT
Fast hyperbolic secant function.
float shz_cotf(float radians) SHZ_NOEXCEPT
One-off routine for returning only cotangent (1 / tan(x)) from an angle in radians.
float shz_cotf_deg(float degrees) SHZ_NOEXCEPT
One-off routine for returning only cotangent (1 / cot(x)) from an angle in degrees.
float shz_acscf(float x) SHZ_NOEXCEPT
Fast arccosecant/inverse cosecant approximation; taking units in radians.
float shz_asechf(float x) SHZ_NOEXCEPT
Fast hyperbolic arcsecant function.
float shz_atanhf(float x) SHZ_NOEXCEPT
Fast hyperbolic arctangent function.
float shz_asinf(float x) SHZ_NOEXCEPT
Fast arcsine approximation; equivalent to C's asinf().
float shz_cscf_deg(float degrees) SHZ_NOEXCEPT
One-off routine for returning only cosecant (1 / sin(x)) from an angle in degrees.
float shz_asecf(float x) SHZ_NOEXCEPT
Fast arcsecant/inverse secant approximation, taking units in radians.
float shz_atan2f(float y, float x) SHZ_NOEXCEPT
Computes arctangent of y / x, using the signs of arguments to determine correct quadtrant....
float shz_secf_deg(float degrees) SHZ_NOEXCEPT
One-off routine for returning only secant (1 / cos(x)) from an angle in degrees.
float shz_sinf_deg(float degrees) SHZ_NOEXCEPT
One-off routine for returning only sinf() from an angle in degrees.
float shz_asinhf(float x) SHZ_NOEXCEPT
Fast hyperbolic arcsine function.
float shz_sinhf(float x) SHZ_NOEXCEPT
Fast hyperbolic sine function.
float shz_tanhf(float x) SHZ_NOEXCEPT
Fast hyperbolic tangent function.
float shz_atanf_q1(float x) SHZ_NOEXCEPT
Fast arctangent approximation for values lying within the first quadrant (>= 0.0f).
float shz_sincos_tanf(shz_sincos_t sincos) SHZ_NOEXCEPT
Returns tanf() from the given pre-computed sincos pair.
float shz_acschf(float x) SHZ_NOEXCEPT
Fast hyperbolic arccosecant function.
Pair representing the sine and cosine of a given angle.
Definition shz_trig.h:55
float cos
cosf() approximation for the angle
Definition shz_trig.h:57
float sin
sinf() approximation for the angle
Definition shz_trig.h:56