# Fix16 LUT sin cos fixmath.h

I’m facing some problem using sin/cos Look Up Table from fixmath.h
Here my code:

``````
#include "Pokitto.h"
#include "fixmath.h"

Pokitto::Core g;
Pokitto::Display d;

int main ()
{
g.begin();

while (g.isRunning())
{
if (g.update())
{

for(int a=0; a<360; a+=15)
{
Fix16 angle=fix16_from_int(a);

int xt=55+fix16_to_int(xtf);
int yt=44+fix16_to_int(ytf);

d.drawLine(55,44,xt,yt);
}

}
}
}

``````

And here the result: It should draw a line starting from the center of the screen every 15 degrees with a radius of 30 pixel.
From my test sin cos output are wrong.
Does anyone use sin cos from fixmath.h before?

Are you sure you’re supposed to be using degrees and radians instead of simply 0-255?

1 Like

I am using it a lot in P-Zero demo. I think I fixed a bug in the sine function. I will come back later when I am at my PC.

1 Like

I believe it accept a Fix16 angle in radians. But without doc is not so clear.

That’s will explain a lot of my problems. Thanks in advance.

Here are two fixed lines:

``````fix16_t fix16_sin(fix16_t inAngle) {
fix16_t tempAngle = inAngle % (fix16_pi << 1);

#ifdef FIXMATH_SIN_LUT
if(tempAngle < 0)
tempAngle += (fix16_pi << 1);

fix16_t tempOut;
if(tempAngle >= fix16_pi) {
tempAngle -= fix16_pi;
if(tempAngle >= (fix16_pi >> 1))
tempAngle = fix16_pi - tempAngle;
//tempOut = -(tempAngle >= _fix16_sin_lut_count ? fix16_one : _fix16_sin_lut[tempAngle]);
tempOut = -(_fix16_sin_lut[(255*tempAngle)/(fix16_pi>>1)]);
} else {
if(tempAngle >= (fix16_pi >> 1))
tempAngle = fix16_pi - tempAngle;
//tempOut = (tempAngle >= _fix16_sin_lut_count ? fix16_one : _fix16_sin_lut[tempAngle]);
tempOut = _fix16_sin_lut[(255*tempAngle)/(fix16_pi>>1)];

``````
1 Like Particles goes where they should go now  Thanks!!!
Ok, now why that hack?

My guest is that _fix16_sin_lut the table itself is wrong. Maybe calculated for a different architecture?

4 Likes

The sine function was expecting different number of items than the lut contained.

I will make a PR to GitHub.

2 Likes

Beware just some useless though ahead.

Summary

Don’t you think the fix is suspicious?
From the code it seems `fix16_sin` is expecting `inAngle` to be radians, in fact it apply modulo of 2PI at the begin.
But then you have to normalized the `tempAngle` to 0-255 value, to correctly access the look up array.
The exactly original same code is all scattered in the web if you make a search, how is it possible nobody fix it?

Where is the original fixmath hosted? Is this it?

It could be that it’s been reported but not acted upon.
It could be that the version bundled with the PokittoLib is out of date.
It could be that hardly anyone is actually using the library.

2 * Pi is Tau, and Tau is better than Pi.

2 Likes

That can’t be true, because the answer to the universe has no Tau: If Euler sez its so, then it is so.

Maybe the original implementation used much bigger LUT, but it is at some point optimized for MCU usage.

Ahem I hope it was not me I may have accidentally done something to the LUT at some point But not sure   3 Likes

I don’t want to derail this, but I need to point this out…

`cis(x) = e ^ (i * x) = cos(x) + (i * sin(x))`
`cos(pi) = -1` and `sin(pi) = 0` therefore `cis(pi) = -1`
`cos(tau) = 1` and `sin(tau) = 0` therefore `cis(tau) = 1`
So although `cis(pi) + 1 = 0`, equally `cis(tau) - 1 = 0`.

Such is the power of tau. `:P`

(Either that or I’m really bad at maths, which is probable.)

I have no clue about that Tau thingy But I made a PR of the fix. This time I tried to make it on-the-go, using only the GitHub web interface: created a branch, edited a file, committed, created a PR. Very handy for small, pre-tested, changes like this!

1 Like

Bingo! Original Lut Table is bigger. Too much for low mem device.
But using

``````//#define FIXMATH_SIN_LUT
#define FIXMATH_NO_CACHE
#define FIXMATH_FAST_SIN
``````

avoid completely the use of LUT with good result

3 Likes

This is great. Many hours of entertainment reading the Manifesto and following the links therein.

1 Like