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