fixed atan2_t

approximation was incorrect, now doing it right.
also removed hypotf() from octopus, saving a little flash.
This commit is contained in:
Damian Schneider 2024-10-15 20:11:33 +02:00
parent f301296f1e
commit 5e29f2c1b7
2 changed files with 21 additions and 24 deletions

View File

@ -7749,8 +7749,10 @@ uint16_t mode_2Doctopus() {
const int C_Y = (rows / 2) + ((SEGMENT.custom2 - 128)*rows)/255;
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
rMap[XY(x, y)].angle = 40.7436f * atan2_t((y - C_Y), (x - C_X)); // avoid 128*atan2()/PI
rMap[XY(x, y)].radius = hypotf((x - C_X), (y - C_Y)) * mapp; //thanks Sutaburosu
rMap[XY(x, y)].angle = int(40.7436f * atan2_t((y - C_Y), (x - C_X))); // avoid 128*atan2()/PI
int dx = (x - C_X);
int dy = (y - C_Y);
rMap[XY(x, y)].radius = sqrtf(dx * dx + dy * dy) * mapp; //thanks Sutaburosu
}
}
}

View File

@ -88,8 +88,8 @@ uint8_t cos8_t(uint8_t theta) {
float sin_approx(float theta)
{
theta = modd(theta, TWO_PI); // modulo: bring to -2pi to 2pi range
if(theta < 0) theta += M_TWOPI; // 0-2pi range
uint16_t scaled_theta = (uint16_t)(theta * (0xFFFF / M_TWOPI));
if(theta < 0) theta += TWO_PI; // 0-2pi range
uint16_t scaled_theta = (uint16_t)(theta * (0xFFFF / TWO_PI));
int32_t result = sin16_t(scaled_theta);
float sin = float(result) / 0x7FFF;
return sin;
@ -110,28 +110,23 @@ float tan_approx(float x) {
#define ATAN2_CONST_A 0.1963f
#define ATAN2_CONST_B 0.9817f
// fast atan2() approximation source: public domain
// atan2_t approximation, with the idea from https://gist.github.com/volkansalma/2972237?permalink_comment_id=3872525#gistcomment-3872525
float atan2_t(float y, float x) {
if (x == 0.0f) return (y > 0.0f) ? M_PI_2 : (y < 0.0f) ? -M_PI_2 : 0.0f;
float abs_y = (y < 0.0f) ? -y : y + 1e-10f; // make sure y is not zero to prevent division by 0
float z = abs_y / x;
float atan_approx;
if (z < 1.0f) {
atan_approx = z / (1.0f + ATAN2_CONST_A * z * z);
if (x < 0.0f) {
return (y >= 0.0f) ? atan_approx + PI : atan_approx - PI;
}
float abs_y = fabs(y);
float abs_x = fabs(x);
float r = (abs_x - abs_y) / (abs_y + abs_x + 1e-10f); // avoid division by zero by adding a small nubmer
float angle;
if(x < 0) {
r = -r;
angle = M_PI/2.0f + M_PI/4.f;
}
else {
z = x / abs_y;
atan_approx = M_PI_2 - z / (1.0f + ATAN2_CONST_A * z * z);
if (y < 0.0f) {
return -atan_approx;
}
}
return atan_approx;
else
angle = M_PI/2.0f - M_PI/4.f;
float add = (ATAN2_CONST_A * (r * r) - ATAN2_CONST_B) * r;
angle += add;
angle = y < 0 ? -angle : angle;
return angle;
}
//https://stackoverflow.com/questions/3380628