Put this in a new file called "advmath.zh" (so that if anyone else uses it in their scripts, it will have the same name)
Code:
//Code adapted from the snippet located here:
//http://discussion.forum.nokia.com/forum/showthread.php?t=72840
//The original code was placed in the public domain
//The translated code below is also public domain
//I had to truncate these constants, since ZScript uses fixed place floats.
const float sq2p1 = 2.4142; // .414213562373095048802;
const float sq2m1 = 0.4142; // .414213562373095048802;
const float p4 = 16.1536; // .1536412982230228262;
const float p3 = 268.4255; // .42548195503973794141;
const float p2 = 1153.0294; // .0293515404850115428136;
const float p1 = 1780.4063; // .40631643319697105464587;
const float p0 = 896.7860; // .78597403663861959987488;
const float q4 = 58.9570; // .95697050844462222791;
const float q3 = 536.2654; // .265374031215315104235;
const float q2 = 1666.7838; // .7838148816337184521798;
const float q1 = 2079.3350; // .33497444540981287275926;
const float q0 = 896.7860; // .78597403663861962481162;
const float PIO2 = 1.5708; // .5707963267948966135;
const float PIO1 = 3.1416;
const float iRt2 = 0.7071;
const float PIO3 = 57.2958;
const float PIO4 = 0.0175;
// reduce
float mxatan(float arg) {
float argsq = arg*arg;
float value = (((p4*argsq + p3)*argsq + p2)*argsq + p1)*argsq + p0;
value /= ((((argsq + q4)*argsq + q3)*argsq + q2)*argsq + q1)*argsq + q0;
return value*arg;
}
// reduce
float msatan(float arg) {
if(arg < sq2m1)
return mxatan(arg);
if(arg > sq2p1)
return PIO2 - mxatan(1/arg);
return PIO2/2 + mxatan((arg-1)/(arg+1));
}
// implementation of atan
float atan(float arg) {
if(arg > 0)
return msatan(arg);
return -msatan(-arg);
}
// implementation of asin
float asin(float arg) {
float temp;
int sign;
sign = 0;
if(arg < 0) {
arg = -arg;
sign++;
}
if(arg > 1)
return 0.0; //should be NaN
temp = Sqrt(1 - arg*arg);
if(arg > iRt2)
temp = PIO2 - atan(temp/arg);
else
temp = atan(arg/temp);
if(sign > 0)
temp = -temp;
return temp;
}
// implementation of acos
float acos(float arg) {
if(arg > 1 || arg < -1)
return 0.0; //should be NaN
return PIO2 - asin(arg);
}
// convert radian angle to degrees
float rad2deg(float arg) {
return arg * PIO3;
}
// convert degree angle to radians
float deg2rad(float arg) {
return arg * PIO4;
}
float findAngle(float x1, float y1, float x2, float y2) {
float ret;
float dx = x2 - x1;
float dy = y2 - y1;
ret = ArcTan(dy, dx);
return PI / 2 - ret;
}
* Implements the ATan, ACos and ASin functions (until we get built in versions of the same)
* Does not rely on std.zh
* Easily importable into any script
* As a bonus, includes two functions to convert between degrees and radians!
* As a super special bonus, includes a function to find the angle from one point to another!
Function prototypes:
See this page for what they do: http://www.xgc.com/manuals/xgclib/x940.html
Code:
float asin(float x);
float acos(float x);
float atan(float x);
//atan2 is provided by the as yet undocumented function "ArcTan(y,x)"
float deg2rad(float deg);
float rad2deg(float rad);
float findAngle(float x1, float y1, float x2, float y2);
EDIT: Hurrr. I meant to post this in Script Showcase...