src/engine/eAxis.cpp

Go to the documentation of this file.
00001 #include "eAxis.h"
00002 
00003 eAxis::eAxis(int number)
00004 {
00005     windings = NULL;
00006     windingAngles = NULL;
00007     Init(number);
00008 }
00009 
00010 void eAxis::Init(int number)
00011 {
00012     numberWinding = (number < 1) ? 4 : number;
00013     if (windings)
00014         delete [] windings;
00015     if (windingAngles)
00016         delete [] windingAngles; // [] not really required as we are dealing with floats, not objects.
00017 
00018     windings = new eCoord[numberWinding]();
00019     windingAngles = new REAL[numberWinding];
00020 
00021     ComputeWinding();
00022     SnapWinding();
00023     ComputeAngles();
00024 }
00025 
00026 void eAxis::Init(int number, eCoord predefinedAxis[], bool normalize)
00027 {
00028     if ( number < 1 || predefinedAxis == NULL)
00029     {
00030         Init(4);
00031         return;
00032     }
00033 
00034     numberWinding = number;
00035     if (windings)
00036         delete [] windings;
00037     if (windingAngles)
00038         delete [] windingAngles; // [] not really required as we are dealing with floats, not objects.
00039 
00040     windings = new eCoord[numberWinding]();
00041     windingAngles = new REAL[numberWinding];
00042 
00043     for(int i=0; i<number; i++)
00044     {
00045         windings[i] = predefinedAxis[i];
00046         if (normalize) {
00047             windings[i].Normalize();
00048         }
00049     }
00050 
00051     SnapWinding();
00052     ComputeAngles();
00053 }
00054 
00055 
00056 eAxis::~eAxis()
00057 {
00058     if (windings)
00059         delete [] windings;
00060     if (windingAngles)
00061         delete [] windingAngles; // [] not really required as we are dealing with floats, not objects.
00062 }
00063 
00064 void eAxis::Turn(int &currentWinding, int direction)
00065 {
00066     if (direction > 1) direction = 1;
00067     if (direction < -1) direction = -1;
00068     currentWinding += direction + numberWinding; // + numberWinding to avoid any negative. They dont modulate well!
00069     currentWinding %= numberWinding;
00070 }
00071 
00072 void eAxis::TurnRight(int &windingDirection)
00073 {
00074     windingDirection--;
00075     windingDirection += numberWinding; // + numberWinding to fix negative modulos
00076     windingDirection %= numberWinding;
00077 }
00078 
00079 void eAxis::TurnLeft(int &windingDirection)
00080 {
00081     windingDirection++;
00082     windingDirection %= numberWinding;
00083 }
00084 
00085 /*
00086  * Compute evenly spaced windings 
00087  */
00088 void eAxis::ComputeWinding()
00089 {
00090     unsigned int i;
00091     REAL tetha;
00092     for(i=0; i<numberWinding; i++)
00093     {
00094         tetha = M_PI*2*(numberWinding - i - 1)/numberWinding;
00095         windings[i].x = (cosf(tetha));
00096         windings[i].y = (sinf(tetha));
00097     }
00098 }
00099 
00100 void eAxis::SnapWinding()
00101 {
00102     unsigned int i;
00103     for(i=0; i<numberWinding; i++)
00104     {
00105         eCoord & winding = windings[i];
00106         if ( fabs(winding.x) < EPS )
00107             winding.x = 0;
00108         if ( fabs(winding.y) < EPS )
00109             winding.y = 0;
00110     }
00111 }
00112 
00113 void eAxis::ComputeAngles()
00114 {
00115     unsigned int i;
00116     for(i=0; i<numberWinding; i++)
00117     {
00118         windingAngles[i] = eCoordToRad(windings[i]);
00119     }
00120 }
00121 
00122 REAL remf(REAL x, REAL y) {
00123     return x - y*floorf(x/y);
00124 }
00125 
00126 REAL angledifff(REAL x, REAL y) {
00127     return fabsf(remf(x - y + M_PI, 2*M_PI) - M_PI);
00128 }
00129 
00130 /*
00131  * Given the direction described by (0,0) to pos, return the winding number
00132  * describing the closest axis/direction 
00133  * 
00134  */
00135 int eAxis::NearestWinding (eCoord pos)
00136 {
00137     REAL posAngle = eCoordToRad(pos);
00138 
00139     REAL closestval = angledifff(windingAngles[0], posAngle);
00140     unsigned int i, closestid = 0;
00141     for(i=1; i<numberWinding; i++) {
00142         REAL diff = angledifff(windingAngles[i], posAngle);
00143         if(diff < closestval) {
00144             closestid = i;
00145             closestval = diff;
00146         }
00147     }
00148     return closestid;
00149 }
00150 
00151 eCoord eAxis::GetDirection (int winding)
00152 {
00153     winding %= numberWinding;
00154     return windings[winding];
00155 }

Generated on Sat Mar 15 22:55:43 2008 for Armagetron Advanced by  doxygen 1.5.4