Speed improvements, commented legacy _t trig functions
- speed improvement: by default M_TWOPI is treated as a double float - directly calling sin16_t in cos_approx() saves a lot of overhead
This commit is contained in:
		| @@ -10,14 +10,17 @@ | |||||||
|  |  | ||||||
| //#define WLED_DEBUG_MATH | //#define WLED_DEBUG_MATH | ||||||
|  |  | ||||||
| #define modd(x, y) ((x) - (int)((x) / (y)) * (y)) | // Note: cos_t, sin_t and tan_t are very accurate but slow | ||||||
|  |  | ||||||
| // Note: cos_t, sin_t and tan_t are very accurate but may be slow |  | ||||||
| // the math.h functions use several kB of flash and are to be avoided if possible | // the math.h functions use several kB of flash and are to be avoided if possible | ||||||
| // sin16_t / cos16_t are faster and much more accurate than the fastled variants | // sin16_t / cos16_t are faster and much more accurate than the fastled variants | ||||||
| // sin_approx and cos_approx are float wrappers for sin16_t/cos16_t and have an accuracy better than +/-0.0015 compared to sinf() | // sin_approx and cos_approx are float wrappers for sin16_t/cos16_t and have an accuracy better than +/-0.0015 compared to sinf() | ||||||
| // sin8_t / cos8_t are fastled replacements and use sin16_t / cos16_t. Slightly slower than fastled version but very accurate | // sin8_t / cos8_t are fastled replacements and use sin16_t / cos16_t. Slightly slower than fastled version but very accurate | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Taylor series approximations, replaced with Bhaskara I's approximation | ||||||
|  | /* | ||||||
|  | #define modd(x, y) ((x) - (int)((x) / (y)) * (y)) | ||||||
|  |  | ||||||
| float cos_t(float phi) | float cos_t(float phi) | ||||||
| { | { | ||||||
|   float x = modd(phi, M_TWOPI); |   float x = modd(phi, M_TWOPI); | ||||||
| @@ -54,6 +57,7 @@ float tan_t(float x) { | |||||||
|   #endif |   #endif | ||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
|  | */ | ||||||
|  |  | ||||||
| // 16-bit, integer based Bhaskara I's sine approximation: 16*x*(pi - x) / (5*pi^2 - 4*x*(pi - x)) | // 16-bit, integer based Bhaskara I's sine approximation: 16*x*(pi - x) / (5*pi^2 - 4*x*(pi - x)) | ||||||
| // input is 16bit unsigned (0-65535), output is 16bit signed (-32767 to +32767) | // input is 16bit unsigned (0-65535), output is 16bit signed (-32767 to +32767) | ||||||
| @@ -85,17 +89,18 @@ uint8_t cos8_t(uint8_t theta) { | |||||||
|   return sin8_t(theta + 64); //cos(x) = sin(x+pi/2) |   return sin8_t(theta + 64); //cos(x) = sin(x+pi/2) | ||||||
| } | } | ||||||
|  |  | ||||||
| float sin_approx(float theta) | float sin_approx(float theta) { | ||||||
| { |   uint16_t scaled_theta = (int)(theta * (float)(0xFFFF / M_TWOPI)); // note: do not cast negative float to uint! cast to int first (undefined on C3) | ||||||
|   uint16_t scaled_theta = (int)(theta * (0xFFFF / M_TWOPI)); // note: do not cast negative float to uint! cast to int first (undefined on C3) |  | ||||||
|   int32_t result = sin16_t(scaled_theta); |   int32_t result = sin16_t(scaled_theta); | ||||||
|   float sin = float(result) / 0x7FFF; |   float sin = float(result) / 0x7FFF; | ||||||
|   return sin; |   return sin; | ||||||
| } | } | ||||||
|  |  | ||||||
| float cos_approx(float theta) | float cos_approx(float theta) { | ||||||
| { |   uint16_t scaled_theta = (int)(theta * (float)(0xFFFF / M_TWOPI)); // note: do not cast negative float to uint! cast to int first (undefined on C3) | ||||||
|   return sin_approx(theta + M_PI_2); |   int32_t result = sin16_t(scaled_theta + 16384); | ||||||
|  |   float cos = float(result) / 0x7FFF; | ||||||
|  |   return cos; | ||||||
| } | } | ||||||
|  |  | ||||||
| float tan_approx(float x) { | float tan_approx(float x) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Damian Schneider
					Damian Schneider