Привет всем! вот наконец я и добрался рассказать как мучался с такой вещью в JAVAME без матлиб и т.п.
для чего такая байда нужна? обычно нужно чтобы объект научился "смотреть" на другой...
заключается сия функция в расчете углов по двум координатам (а-ля угол вектора)
покопался в нете, нарыл формулу по которой раскладывается атан: atn=32*x*x + 9*y*y;
гы! я тут всем в аську проспамил может думаю какое друое решение есть, а то в этом умножений много... тормозить будет, а я из тех программистов которые раскладывают все формулы на листочке и записывают простейший вариант в код, не люблю когда выдумают жутко громоздкую формулу и потом комп парится их вычисляет... не надо надо мной смеяться придумывая как я бы расписывал массив... я упрощаю все в пределах разумного...
так! где я там остановился... ага... атан, мать его! ну короче мучались мы поисками мучались, нифига не нашли, и PAX замутил код:
public float atan2(float x, float y) {
float atn,atn1;
atn1=32*x*x + 9*y*y;
if (atn1==0) {//если угол перпендикулярен оси х
if (x>0) {return 90;} else{ return 270; }
}
atn=32*(x*y)/atn1;
if (x>=0) {
if (y>=0){
return atn;//первая четверть
}else{
return 360-atn;//четвертая четверть
}
}else{
if (y>=0){
return 90+atn;//вторая четверть
}else{
return 270-atn;//третья четверть
}
}
}
но меня это все не устраивало... казалось мне, что можно более простой вариант придумать... тем более что у меня в игре не 360 углов а всего 16... этот код еще преобразовывать надо было бы...
и придумал я свой вариант... чисто специализированный... к другому коду не подойдет...
итак:
сначала рисунок:
пестровато конечно, но попробую объяснить всю суть моей затеи...
по прямой OY координата Y равна нулю, точно также и по ОХ. По синей прямой кордината X будет всегда равна Y... уже половину углов можно описать простейшими условиями, и без вычислений... Но это всеголишь 8 углов... а у меня 16... и я придумал такую весчъ!
придумал делить одну координату на другую и сравнивать с заранее высчитанным результатом... а прежде сравнивать их, если, при положительный координатах, X больше чем Y, то угол будет в коричневом секторе, если наоборот то желтом.
для угла 45 градусов результат будет 1, для угла в 22.5 градуса высчитывается по формуле cos(22,5)/sin(22,5), и все это равно 2,414213562373... теперь мы точно можем сказать, что если результат деления одной координаты на другую получился в пределах от 1 до 2,41, то нужно повергуться на угол гдето между двойкой и тройкой!
но это маленько не то, что нам было нужно... нам нужно знать примерный угол "3"! для этого поделим секторы между (2 и 3) и (3 и 4) еще пополам... таким образом у нас получились лучи расположенные под углами 11.5 и 33.75... высчитаем у них результаты деления одной координаты на другую...
cos(11,25)/sin(11,25)*=*5,027339492126
cos(33,75)/sin(33,75)*=*1,496605762665
вот теперь то, что надо! теперь если результат деления одной координаты на другую будет больше чем 5, то это будет угол 4 (красный сектор), если от 1.49 до 5 то угол 3 (зеленый сектор), а если меньше 1.49, то угол 2...
и такими темпами есь круг... итого требудется всего одно деление и условия (которые обрабатываются значительно быстрее)...
итого: надо выбрать четверть, потом восьмую часть (путем сравнения координат кака больше) и поделить координаты!
начал я мутить программу по такому вот кнцепту... и получилось что там еще надо добавить немножко условий, а именно: чтоб исключить деление на ноль, а в остальном все так и осталось как и было:

xp=PositionX-PositionX1;
yp=PositionY-PositionY1;
xp1=xp; if (xp1<0) xp1=-xp1;
yp1=yp; if (yp1<0) yp1=-yp1;
if (xp>0) {
if (yp>0) {
if (xp1>yp1) {
if (yp1==0) angle=12; else {
j=(xp1*16)/yp1;
if (j>=80) angle=12;
if (j<80 && j>=24) angle=13;
if (j<24) angle=14;
}
} else {
if (xp1==0) angle=0; else {
j=(yp1*16)/xp1;
if (j>=80) angle=0;
if (j<80 && j>=24) angle=15;
if (j<24) angle=14;
}
}
} else {
if (xp1>yp1) {
if (yp1==0) angle=12; else {
j=(xp1*16)/yp1;
if (j>=80) angle=12;
if (j<80 && j>=24) angle=11;
if (j<24) angle=10;
}
} else {
if (xp1==0) angle=8; else {
j=(yp1*16)/xp1;
if (j>=80) angle=8;
if (j<80 && j>=24) angle=9;
if (j<24) angle=10;
}
}
}
} else {
if (yp>0) {
if (xp1>yp1) {
if (yp1==0) angle=4; else {
j=(xp1*16)/yp1;
if (j>=80) angle=4;
if (j<80 && j>=24) angle=3;
if (j<24) angle=2;
}
} else {
if (xp1==0) angle=0; else {
j=(yp1*16)/xp1;
if (j>=80) angle=0;
if (j<80 && j>=24) angle=1;
if (j<24) angle=2;
}
}
} else {
if (xp1>yp1) {
if (yp1==0) angle=4; else {
j=(xp1*16)/yp1;
if (j>=80) angle=4;
if (j<80 && j>=24) angle=5;
if (j<24) angle=6;
}
} else {
if (xp1==0) angle=8; else {
j=(yp1*16)/xp1;
if (j>=80) angle=8;
if (j<80 && j>=24) angle=7;
if (j<24) angle=6;
}
}
}
}
в ходе кода встретлся с проблемой, низя юзать десятичные дроби, пэтому пришлось юзать умножение... и сравнивать потом с заранее умноженными вариантами... зато теперь теоретически прога должна выполняться быстрее

, на каждом проходе получается - 5 условий, одно умножение и одно деление...
вот так вот...
