This solution is based on maximizing cos(theta-theta_i) where theta_i is 0,45,90,...,315 degrees. I used the angle-difference identity cos(a-b)=cos(a)cos(b)-sin(a)sin(b) and worked with x=r*cos(a) and y=r*sin(a) to simplify the different expressions, so no actual trig functions have to be used:
int getIndex_simple(float x, float y){
float rCosThetaMinusThetaI[8];
rCosThetaMinusThetaI[0]=x;
rCosThetaMinusThetaI[1]=(x+y)*M_SQRT1_2;
rCosThetaMinusThetaI[2]=y;
rCosThetaMinusThetaI[3]=(y-x)*M_SQRT1_2;
rCosThetaMinusThetaI[4]=-x;
rCosThetaMinusThetaI[5]=(-x-y)*M_SQRT1_2;
rCosThetaMinusThetaI[6]=-y;
rCosThetaMinusThetaI[7]=(x-y)*M_SQRT1_2;
int best_i=0;
float best_rCosThetaMinusThetaI=rCosThetaMinusThetaI[0];
for(int i=1; i<8; i++)
if( rCosThetaMinusThetaI[i]>best_rCosThetaMinusThetaI ){
best_i=i;
best_rCosThetaMinusThetaI=rCosThetaMinusThetaI[i];
}
return best_i;
}
There are a few simple things you can do to speed this up. For example rCosThetaMinusThetaI[i] == -rCosThetaMinusThetaI[i-4]
for i>=4, so you only need four variables. Obviously you don't have to use an array, I just did this to make it easy to read. Also, since rCosThetaMinusThetaI[0]==x
and rCosThetaMinusThetaI[2]==y
, you only really need two variables. So we can rewrite the above as just a series of eight if
statements:
int getIndex_optimized(float x, float y){
float cosTheta1 = (x+y)*M_SQRT1_2;
float cosTheta3 = (y-x)*M_SQRT1_2;
int best_i=0;
float best_cosTheta=x;
if( best_cosTheta < cosTheta1 ){ best_i=1; best_cosTheta=cosTheta1; }
if( best_cosTheta < y ){ best_i=2; best_cosTheta=y; }
if( best_cosTheta < cosTheta3 ){ best_i=3; best_cosTheta=cosTheta3; }
if( best_cosTheta < -x ){ best_i=4; best_cosTheta=-x; }
if( best_cosTheta < -cosTheta1){ best_i=5; best_cosTheta=-cosTheta1; }
if( best_cosTheta < -y ){ best_i=6; best_cosTheta=-y; }
if( best_cosTheta < -cosTheta3){ best_i=7; best_cosTheta=-cosTheta3; }
return best_i;
}
These two functions are C99 code; you can compile them with -std=c99. You need to include math.h to get the constant M_SQRT1_2=0.7071...