|
Hello all.
About a year ago I researched math functions so I could write some for
the RCX. I found some power series functions that work really well.
I see another message here posted by "nanobapt" has also posted some
functions so I tested his against the ones I found and the ones I found
last year are more accurate (sine is anyway).
Ironically he uses his sine to calculate cosine, and his cosine is more
accurate than sine! weird.
Anyway I don't remember where I got these series functions, since they
came from different sources on the web, the square root function
definitely came from Isaac Newton, I think the others were derived from
Newton's with improvements made by later math geniuses (all much smarter
than me!).
I also have inverse functions, last year I tested all of these functions
using a spreadsheet and the built-in "SERIESSUM" function to emulate
these C functions before I actually wrote the C functions. The goal then
was to test them out, and see how many iterations of the series was
needed to get the desired accuracy.
I hope others will find this useful, incidentally the built-in functions
use a different approach. Instead of doing a power series, they do
another type of binary math that is more accurate, all calculators and
math-co's use this binary approach. I found a PDF file explaining it but
at the time didn't spend enough time to figure out how to implement it.
How I tested these in a real RCX was by writing a short program to
divide a circle into 50 equal pieces, in radians, from -PI to +PI.
Then calculate the sine and cosine of each value, I did this with my
functions, the functions supplied by nanobapt, and the built-in
spreadsheet functions, and plotted them all on a chart. My sine follows
the built-in sine all the way across the chart, my cosine isn't quite as
accurate as it starts to rise above the built-in cosine between -PI and
-2.65 and again at +2.65 to +PI. Nano's cosine does the same, in the
same spot, in the other direction. His sine went way off the built-in
sine until -1.5, and after +1.5, which is odd because his sine is used
to calculate his cosine, which is as accurate as the one I used! I may
have made a mistake somewhere. If I did his equations may be better
since they seem more simple, and may be faster, but they all run so fast
I can't tell. All of them are accurate enough for robot navigation,
which is probably why you want them :)
Apparently I can't attach files so the jpg of a graph made with
OpenOffice Calc comparing these functions is at:
http://billkoontz.com/files/compare_trigs.jpg
A slightly earlier version of this math header is available on my web
site also.
--------
/*
* rcxmath.h
*
* Basic RCX math library
*
* Version 1.0
* Date: 12/30/2002
* Author
* Bill Koontz
* wkoontz@insight.rr.com
*
* int abs(int value); Returns absolute value of value.
* float sqrt(float x); Returns square root of x.
* float hypot(float x, float y);
* length of hypotenuse of a right triangle
* whose shorter sides are x and y.
* In other words, the distance between (0,0) and (x,y).
* float cos(float x); Returns cosine of x, where x is in radians.
* float sin(float x); Returns sine of x, where x is in radians.
* float asin(float x); Returns the value whose sine is x.
* float acos(float x); Returs the value whose cosine is x.
* float pow(float x, float y); Returns x to power of y.
*
*/
#include <unistd.h>
/* Define real pi (sorta) */
#define PI 3.14159
int abs(int value);
float cos(float x);
float sin(float x);
float sqrt(float x);
float hypot(float x, float y);
float asin(float x);
float acos(float x);
float pow(float x, float y);
int abs(int value) {
if(value<0) {
return value*-1;
} else {
return value;
}
}
float sqrt(float x) {
float newsq=x;
float oldsq=0;
float try=0;
while((newsq != oldsq) && (try<10)) {
oldsq=newsq;
newsq=(oldsq+x/oldsq)/2;
try++;
}
return newsq;
}
float hypot(float x, float y) {
return sqrt( (x*x) + (y*y) );
}
float pow(float x, float y) {
float r=1,i=0;
for(i=0;i<y;i++) {
r=r*x;
}
return r;
}
float cos(float x) {
float cosine;
cosine=1;
cosine-=(pow(x,2)/2);
cosine+=(pow(x,4)/24);
cosine-=(pow(x,6)/720);
cosine+=(pow(x,8)/40320);
return cosine;
}
float sin(float x) {
float sine;
sine=x;
sine-=(pow(x,3)/6);
sine+=(pow(x,5)/120);
sine-=(pow(x,7)/5040);
sine+=(pow(x,9)/362880);
return sine;
}
float asin(float x) {
float arcsine;
arcsine=x;
arcsine+=(pow(x,3)*(float)0.166667);
arcsine+=(pow(x,5)*(float)0.075);
arcsine+=(pow(x,7)*(float)0.044643);
arcsine+=(pow(x,9)*(float)0.030381944);
return arcsine;
}
float acos(float x) {
return PI/2-asin(x);
}
|
|
1 Message in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|