![]() |
ATAN2 своими руками
Привет всем! вот наконец я и добрался рассказать как мучался с такой вещью в JAVAME без матлиб и т.п.
для чего такая байда нужна? обычно нужно чтобы объект научился "смотреть" на другой... заключается сия функция в расчете углов по двум координатам (а-ля угол вектора) покопался в нете, нарыл формулу по которой раскладывается атан: atn=32*x*x + 9*y*y; гы! я тут всем в аську проспамил может думаю какое друое решение есть, а то в этом умножений много... тормозить будет, а я из тех программистов которые раскладывают все формулы на листочке и записывают простейший вариант в код, не люблю когда выдумают жутко громоздкую формулу и потом комп парится их вычисляет... не надо надо мной смеяться придумывая как я бы расписывал массив... я упрощаю все в пределах разумного... :@ так! где я там остановился... ага... атан, мать его! ну короче мучались мы поисками мучались, нифига не нашли, и PAX замутил код: Код:
public float atan2(float x, float y) { и придумал я свой вариант... чисто специализированный... к другому коду не подойдет... итак: сначала рисунок: ![]() пестровато конечно, но попробую объяснить всю суть моей затеи... по прямой 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; вот так вот... :) |
Re: ATAN2 своими руками
Ну и заключительный штрих:
строчки: j=(yp1*16)/xp1; заменить на: j=(yp1<<4)/xp1; и теперь у нас вообще остается 5 условий и одно деление. :) |
Re: ATAN2 своими руками
Ммм, не думаю, что 5 условий и одно деление будут быстрее, чем 4 умножения (которое всё же быстрее деления) и одно сложение. Тест в студию!
|
Re: ATAN2 своими руками
в коде PAX'a:
atn1=32*x*x + 9*y*y; atn=32*(x*y)/atn1; (итого 6 умножений и одно деление) плюс 4 условия (на 4 угла) в моем: одно деление и 7 условий (на 16 углов) ИМХО тест не нужен ибо преимущество очевидно... конечно можно себе представить ситуацию, когда все условия будут неправильно предсказаны предсказателем перехода и соот-но неправильно загружены в кеш, на что уйдут дополнительные такты, а механизм умножения представлен операционным усилителем и за один такт будет происходит ЦАП-Умножение-АЦП, то в этом случае мой механизм может конечно и проиграть, что на мой взгляд маловероятно... PS Условия считал с точки зрения процессора при выполнении кода... :) |
Часовой пояс GMT +4, время: 09:31. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot