Source

watches / lunar / sin_table.c

Full commit
#include "sin_table.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>


static const uint8_t sin_table[] = {
	0,
	25,
	50,
	74,
	98,
	121,
	142,
	162,
	181,
	198,
	213,
	226,
	237,
	245,
	251,
	255,
	255 // duplicate to avoid extra code for handling last case
};


int16_t
sin_lookup(
	uint16_t theta_in
)
{
	int sign = 1;
	uint32_t theta = theta_in;

	if (theta < 64ul*256)
	{
		// q1, upward slope, normal theta, positive sign
	} else
	if (theta < 128ul*256)
	{
		theta = 128ul*256 - theta; // downward slope, still positive
	} else
	if (theta < 192ul*256)
	{
		// q3, downward slope, negative side
		theta = theta - 128ul*256;
		sign = -1;
	} else
	{
		// q4, upward slope, negative side
		theta = 256ul*256 - theta;
		sign = -1;
	}

	int32_t s1 = ((uint32_t) sin_table[(theta >> 10) + 0]) << 8;
	int32_t s2 = ((uint32_t) sin_table[(theta >> 10) + 1]) << 8;
	int16_t result = (s1 + ((s2 - s1) * (theta & 1023)) / 1024) / 2;

	if (sign == -1)
		return -result;
	else
		return result;
}


#if 0
int main(void)
{
	unsigned theta;

	for (theta = 0 ; theta < 0x100 ; theta++)
	{
		double sx = sin_lookup(theta) / 128.0;
		double sf = sin(theta * 2 * M_PI / 256.0);
		double cx = cos_lookup(theta) / 128.0;
		double cf = cos(theta * 2 * M_PI / 256.0);

		printf("%.4f %.4f %.4f\n",
			cx,
			cf,
			cf - cx
		);
	}
}
#endif