summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2023-07-21 15:39:46 -0700
committerVito Caputo <vcaputo@pengaru.com>2023-07-21 15:39:46 -0700
commit29a42f48fcddf51bdf0ae640aa2513f1091e10d3 (patch)
tree9e6449568afe5e5d20fcb68138b3248190b245b0 /src/modules
parentb249494bd62713a5a2fcb1cd4180e5001643f2ac (diff)
modules/shapes: drop atan2_approx()
With the addition of the "radcache" in b6362c, the need for a faster approximate atan2f() is largely eliminated. And there seems to be a bug in the implementation as-is taken from https://mazzo.li/posts/vectorized-atan2.html You can see the bug as vertical line artifact around the center where the X coordinate would be 0. Rather than debug what's wrong with this approximation's implementation surrounding its quadrant adjustments, let's just resume using atan2f() and let the cache keep things quick.
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/shapes/shapes.c47
1 files changed, 4 insertions, 43 deletions
diff --git a/src/modules/shapes/shapes.c b/src/modules/shapes/shapes.c
index 3943652..b32d7ce 100644
--- a/src/modules/shapes/shapes.c
+++ b/src/modules/shapes/shapes.c
@@ -238,45 +238,6 @@ static void shapes_prepare_frame(til_module_context_t *context, til_stream_t *st
}
-/* simple approximation taken from https://mazzo.li/posts/vectorized-atan2.html */
-static inline float atan_scalar_approximation(float x) {
- /* TODO: this is probably more terms/precision than needed, but when I try just dropping some,
- * the circle+slight pinches gets artifacts. So leaving for now, probably needs slightly different
- * values for fewer terms.
- */
- float a1 = 0.99997726f;
- float a3 = -0.33262347f;
- float a5 = 0.19354346f;
- float a7 = -0.11643287f;
- float a9 = 0.05265332f;
- float a11 = -0.01172120f;
- float x_sq = x*x;
-
- return x * (a1 + x_sq * (a3 + x_sq * (a5 + x_sq * (a7 + x_sq * (a9 + x_sq * a11)))));
-}
-
-
-static float atan2_approx(float y, float x) {
- // Ensure input is in [-1, +1]
- int swap = fabs(x) < fabs(y);
- float atan_input = (swap ? x : y) / (swap ? y : x);
-
- // Approximate atan
- float res = atan_scalar_approximation(atan_input);
-
- // If swapped, adjust atan output
- res = swap ? (atan_input >= 0.0f ? M_PI_2 : -M_PI_2) - res : res;
-
- // Adjust quadrants
- if (x < 0.0f && y >= 0.0f)
- res = M_PI + res; // 2nd quadrant
- else if (x < 0.0f && y < 0.0f)
- res = -M_PI + res; // 3rd quadrant
-
- return res;
-}
-
-
static void shapes_render_fragment(til_module_context_t *context, til_stream_t *stream, unsigned ticks, unsigned cpu, til_fb_fragment_t **fragment_ptr)
{
shapes_context_t *ctxt = (shapes_context_t *)context;
@@ -337,7 +298,7 @@ static void shapes_render_fragment(til_module_context_t *context, til_stream_t *
YYY = Y * Y;
if (!radcache->initialized) {
for (unsigned x = xstart; x < xend; x++, X++, XX += s) {
- float a = rads[y * radcache->width + x] = atan2_approx(YY, XX);
+ float a = rads[y * radcache->width + x] = atan2f(YY, XX);
if (YYY+X*X < r_sq * (1.f - fabsf(cosf(n_pinches * a + pinch)) * pinch_s))
til_fb_fragment_put_pixel_unchecked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, x, y, 0xffffffff); /* TODO: stop relying on checked for clipping */
@@ -378,7 +339,7 @@ static void shapes_render_fragment(til_module_context_t *context, til_stream_t *
YYYY = YY * YY;
if (!radcache->initialized) {
for (unsigned x = xstart; x < xend; x++, XX += s) {
- float a = rads[y * radcache->width + x] = atan2_approx(YY, XX);
+ float a = rads[y * radcache->width + x] = atan2f(YY, XX);
float r = cosf(n_points * (a + spin)) * .5f + .5f;
r *= 1.f - fabsf(cosf(n_pinches * (a + pinch))) * pinch_s;
@@ -426,7 +387,7 @@ static void shapes_render_fragment(til_module_context_t *context, til_stream_t *
X = -(size >> 1) + xskip;
if (!radcache->initialized) {
for (unsigned x = xstart; x < xend; x++, X++, XX += s) {
- float a = rads[y * radcache->width + x] = atan2_approx(YY, XX);
+ float a = rads[y * radcache->width + x] = atan2f(YY, XX);
if (abs(Y) + abs(X) < r * (1.f - fabsf(cosf(n_pinches * a + pinch)) * pinch_s))
til_fb_fragment_put_pixel_unchecked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, x, y, 0xffffffff);
@@ -466,7 +427,7 @@ static void shapes_render_fragment(til_module_context_t *context, til_stream_t *
YYYY = YY * YY;
if (!radcache->initialized) {
for (unsigned x = xstart; x < xend; x++, XX += s) {
- float a = rads[y * radcache->width + x] = atan2_approx(YY, XX);
+ float a = rads[y * radcache->width + x] = atan2f(YY, XX);
float r = (M_2_PI * asinf(sinf(n_points * (a + spin)) * .5f + .5f)) * .5f + .5f;
/* ^^^^^^^^^^^^^^^^^^^ approximates a triangle wave */
© All Rights Reserved