@@ -9,20 +9,16 @@ static inline float pb_fast_sin(float theta) {
99
1010 // 1. Range Reduction to [-PI, PI]
1111 #if defined(__ARM_ARCH_7M__ ) || defined(__ARM_ARCH_7EM__ )
12- // Spike Prime (Cortex-M4F) optimized wrap
1312 float x_wrap = theta * 0.159154943f ;
1413 x = theta - (float )((int )(x_wrap + (x_wrap > 0.0f ? 0.5f : -0.5f ))) * 6.2831853f ;
1514 #else
16- // EV3 / ARM9 wrap
1715 while (x > 3.14159265f ) x -= 6.28318531f ;
1816 while (x < -3.14159265f ) x += 6.28318531f ;
1917 #endif
2018
21- // 2. Normalizing
2219 if (x > 1.5707963f ) x = 3.1415926f - x ;
2320 else if (x < -1.5707963f ) x = -3.1415926f - x ;
2421
25- // 3. Minimax approximation (Horner's method)
2622 float x2 = x * x ;
2723 return x * (0.99999906f + x2 * (-0.16665554f + x2 * (0.00831190f + x2 * -0.00018488f )));
2824}
@@ -32,43 +28,40 @@ static inline float pb_fast_cos(float theta) {
3228}
3329
3430// ----------------------------------------------------------------------------
35- // Quake III Style - Fast Inverse Square Root (Modified for ^1.2 )
31+ // Quake III Style - Fast Inverse Square Root (Legalized for modern compilers )
3632// ----------------------------------------------------------------------------
3733static inline float pb_fast_pow_1_2_ultra (float x ) {
3834 if (x > -0.0001f && x < 0.0001f ) return 0.0f ;
3935
40- long i ;
41- float x2 , y ;
36+ // We use a union to tell the compiler: "This memory is both a float AND a long"
37+ // This bypasses strict-aliasing errors while keeping the bit-hacking intact.
38+ union {
39+ float f ;
40+ uint32_t i ;
41+ } conv ; //evil floating point bit level hacking
42+
43+ float x2 ;
4244 const float threehalfs = 1.5f ;
4345
4446 x2 = x * 0.5f ;
45- y = x ;
46- i = * ( long * ) & y ; // evil floating point bit level hacking
47- i = 0x5f3759df - ( i >> 1 ); // what the fuck?
48- y = * ( float * ) & i ;
47+ conv . f = x ;
48+ conv . i = 0x5f3759df - ( conv . i >> 1 ) ; // what the fuck?
49+
50+ float y = conv . f ;
4951 y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
50- // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
52+ // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, can be removed
5153
52- // Convert the inverse square root back to the ^1.2 required for the S-Curve
5354 float yn2 = y * y ;
5455 float yn4 = yn2 * yn2 ;
5556 return (x * x ) * yn4 ;
5657}
5758
58- // Skrauzys nightmare derivative
5959static inline float pb_fast_s_curve_accel (float x , float a , float b , float c ) {
6060 float x2 = x * x ;
61-
62- // Calculate the slope of the cubic spline
6361 float u = 3.0f * a * x2 + 2.0f * b * x + c ;
64-
65- // Calculate the second derivative (curvature numerator)
6662 float num = 6.0f * a * x + 2.0f * b ;
67-
68- // Base value for the power function
6963 float base = num / ((u * u ) + 1.0f );
7064
71- // Apply the legendary hack to find acceleration
7265 return 560.0f * pb_fast_pow_1_2_ultra (base );
7366}
7467
0 commit comments