I was thinking about what other sort of resources might be worth while producing (Hoping to get what would amount to maybe 5 pages or so - enough to kick off a new "resources" script category). In a
previous post i put up some basic string parsing & a proper dynamic list structure - which covers two pages. Math functions (sin/cos/tan and inverses + sqrt) are certainly worth considering for a third. Perhaps stacks/queues? or maybe something a little more interesting?
The second part of this is of course what formatting I should use. I've been writing with folding regions as defined by my updated notepad++ files (I want
to have these replace the outdated version but I can't upload files to the wiki! If somebody would be so kind as to upload the latest version it would be v. useful).
But perhaps it is better to strip out all but very simplistic comments - moving the documentation into the wiki page for each resource?
Of course, I don't want to be soloing this resources idea so if anyone would like to get working on it too it'd help out alot!
I probably wont get around to this until after my map for teamnesia & have made more progress on my current WIP anyway.
Edit:
Here's the progress i'm willing to make on the math part for now - i'm tired and mathed out - not all fully tested (atan2 is untested but simply lifted from
gamedev so it should work?) Again, all of this has folding regions as per the updated np++ files.
//Begin Math
//+ Constants
const float PI = 3.1415926535f;
const float HPI = PI * 0.5f;
const float PI2 = PI * 2.0f;
//-
//+ Sign Of
int sign(float &in x) { if(x==0.0f) return 0; return (x>0.0f)?1:-1; }
int sign(int &in x) { if(x==0) return 0; return (x>0)?1:-1; }
//-
//+ Abs
float abs(float &in x) { return (x>0.0f)?x:-x; }
int abs(int &in x) { return (x>0)?x:-x; }
//-
//+ Approx
//Determines if two numbers are approximately equal (Differ by no more than epsilon)
bool approx(float &in x, float &in y, float &in epsilon) {
float delta = x-y; return ((delta>0?delta:-delta) <= (epsilon>0?epsilon:-epsilon)); }
//-
//+ Sqrt
//Prereq: Approx
//Returns the squareroot of x
const uint32 _SQRTITERATIONS=16; //Maximum number of iterations for sqrt computation
const float _SQRTDELTA=0.00001f; //Margin of error allowable if complete before iteration ceiling
float sqrt(float &in x) {
if(x<=0) return 0; //Early out - not valid input.
uint32 i = 0; float o = x * 0.5f;
while( i<_SQRTITERATIONS && !approx(o*o,x,_SQRTDELTA) && o != 0)
{ o = 0.5f * (o + x/o); i++; }
return o; }
//-
//+ Max/Min
//Max: Returns largest of two numbers
//Min: Returns smallest of two numbers
float max(float &in x, float &in y) { return x>y?x:y; }
int max(int &in x, int &in y) { return x>y?x:y; }
float min(float &in x, float &in y) { return x<y?x:y; }
int min(int &in x, int &in y) { return x<y?x:y; }
float clamp(float &in x, float &in upper, float &in lower) { return (x<lower?lower:(x<upper?x:upper)); }
int clamp(int &in x, int &in upper, int &in lower) { return (x<lower?lower:(x<upper?x:upper)); }
//-
//+ Factorial
uint32 fact(uint32 &in x) { if(x==0) return 1;
uint32 y = x; for(uint32 i=x-1; i>0; i--) y*=i; return y; }
int fact(int &in x) { if(x<=0) return 1;
int y = x; for(int i=x-1; i>0; i--) y*=i; return y; }
//-
//+ Conversions
//Degrees to radians
float degtorad(float &in x) { return x * 0.0174532925f; }
//Radians to degrees
float radtodeg(float &in x) { return x * 57.2957795f; }
//-
//+ Trig Functions
//+ ..Helper
const float _TRIGARCTANLIM=128.0f; //Value when x exceeds 90 is returned
const uint32 _TRIGITERATIONS=32; //Maximum number of iterations for sqrt computation
const float _TRIGDELTA=0.00001f; //Smallest diff for trig vals
//Constrains X : -PI<X<PI
float trigClamp(float &in x) {
if(x > PI || x < -PI)
{ int t = x/PI2; return x-t*PI2; }
else return x;
}
//-
//+ ..Sin/Cos/Tan
//COSINE
float cos(float &in y) {
float x = trigClamp(y);
float t,s; t=1.0f; s = 1.0f; uint32 p=0;
while( p<_TRIGITERATIONS)
{ p++; t = (-t * x * x) / ((2 * p - 1) * (2 * p)); s+=t; }
return s;
}
//SINE
float sin(float &in y) {
return cos(y-HPI);
}
//TAN (Tan(90 deg) Returns 0xFFFFFFFF [Use isInf()])
float tan(float &in y) {
float x = trigClamp(y);
float c = cos(x);
if(c > -_TRIGDELTA/2 && c <_TRIGDELTA/2) return float(0xFFFFFFFF); //Return #+INF
return cos(x-HPI)/c;
}
//-
//+ ..ARC Sin/Cos/Tan [APPROX]
float arccos(float &in x) {
return trigClamp((-0.69813170079773212f * x * x - 0.87266462599716477f) * x + 1.5707963267948966f); }
float arcsin(float &in x) { return trigClamp(HPI-arccos(x)); }
float arctan(float &in x) { if(x > _TRIGARCTANLIM) return HPI;
else if(x < -_TRIGARCTANLIM) return -HPI; else return trigClamp(HPI-arccos(x/sqrt(x*x+1.1f))); }
float arctan2(float &in x, float &in y) {
float c1 = HPI * 0.5f; float c2 = 3.0f * c1; float abs_y = abs(y); float angle;
if (x >= 0) { float r = (x - abs_y) / (x + abs_y); angle = c1 - c1 * r; }
else { float r = (x + abs_y) / (abs_y - x); angle = c2 - c1 * r; }
return y<0?-angle:angle; }
//Can somebody actually get a good expansion to work here?
//-
//-
//+ Rounding
int floor(float &in x) { return int(x); }
int ceil(float &in x) { int y = int(x); return (y==x?y:y+1); }
int round(float &in x) { int y = int(x); return (y+0.5f>x)?y:(y+1);}
//-
//End
Edit 2:
arctan2 works.