diff options
Diffstat (limited to 'src/modules')
| -rw-r--r-- | src/modules/shapes/shapes.c | 39 | 
1 files changed, 39 insertions, 0 deletions
| diff --git a/src/modules/shapes/shapes.c b/src/modules/shapes/shapes.c index 6de14ee..236861c 100644 --- a/src/modules/shapes/shapes.c +++ b/src/modules/shapes/shapes.c @@ -113,6 +113,45 @@ 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; | 
