нет необходимости выполнять функцию atan.
если вы выполните: y / x, вы получите наклон линии. Судя по полученному номеру, вы можете определить угол / октант.
для положительных х (х> 0)
- (у / х)> 2,4 - => 90 градусов (север)
- 2,4> (г / х)> 0,4 - => 45 градусов (северо-запад)
- 0,4> (г / х)> -0,4 - => 0 градусов (запад)
- -0,4> (г / х)> -2,4 - => -45 градусов (юго-запад)
- -2,4> (г / х) - => 90 градусов (юг)
и аналогичный список для отрицательных х
и, наконец, исключительные случаи:
- (x == 0 && y> 0) - => -90 градусов (юг)
- (x == 0 && y <0) - => 90 градусов (юг)
addendum: я сообщаю об этом методе только для расчета atan, который не разрешен (например, во встроенной системе))
Мне пришлось немного покопаться. Вот очень оптимизированная процедура, которую я использую (используется в мобильных играх).
вход: x1, y1 = начальная точка вектора
x2, y2 = конечная точка вектора
выход (0-7) = 0 = север, 1 = северо-запад, 2 = запад, ... и т. д.
int CalcDir( int x1, int y1, int x2, int y2 )
{
int dx = x2 - x1, dy = y2 - y1;
int adx = (dx<0)?-dx:dx, ady = (dy<0)?-dy:dy, r;
r=(dy>0?4:0)+(dx>0?2:0)+(adx>ady?1:0);
r=(int []){2,3,1,0,5,4,6,7}[r];
return r;
}
void CalcDirTest(){
int t = CalcDir(0, 0, 10, 1);
printf("t = %d",t);
t = CalcDir(0, 0, 9, 10);
printf("t = %d",t);
t = CalcDir(0, 0, -1, 10);
printf("t = %d",t);
t = CalcDir(0, 0, -10, 9);
printf("t = %d",t);
t = CalcDir(0, 0, -10, -1);
printf("t = %d",t);
t = CalcDir(0, 0, -9, -10);
printf("t = %d",t);
t = CalcDir(0, 0, 1, -10);
printf("t = %d",t);
t = CalcDir(0, 0, 10, -9);
printf("t = %d",t);
}
Это приведет к следующему выводу:
t = 7
t = 6
t = 5
t = 4
t = 3
t = 2
t = 1
t = 0
(векторы для теста могут выглядеть странно выбранными, но я немного подправил их, чтобы они были четко в одном октанте, а не на точной границе)