Angle To...

По скольку писать в блоги я не умею (несколько раз пробовал — такая фигня получается), то попробую как-то более технически рассказать про свой игровой фреймворк. Ну и может иногда всякие программистские штуки рассказывать, с которыми приходится сталкиваться. Кто-то эти штуки может знать, а кому-то вполне пригодится.
Например определение угла между двумя точками. В своё время дёрнул метод из какого-то класса и забыл про него. А сегодня столкнулся с одной проблемой, которая заставила меня присмотреться к нему и в итоге переписать. Оказалось всё гораздо проще, чем было, буквально в одну строчку. Сейчас мой метод выглядит вот так:
public function angleTo(v:Vec2):Number {
  return Math.atan2(v.y - y, v.x - x) * 180 / Math.PI;
}

Пояснение: Vec2 — это своя реализация вектора.

Комментарии (52)

0
Раз речь зашла о игровом фреймверке, то в целях оптимизации, имеет смысл «180 / Math.PI» выносить в константу.
public static const RAD_TO_DEG: Number = 57.29577951;

return Math.atan2(v.y — y, v.x — x) * RAD_TO_DEG;
0
Кстати да, вполне себе годная мысль, пойду допилю. Спасибо.
0
Я конечно не берусь утверждать, но думаю что если написать во флешке 345+459+693 и скомпилировать, то при компиляции SWF-ки он это всё посчитает, а не будет постоянно складывать. Аналогично и с константами.
0
Возможно в 10.1+ это допилили, но раньше это было не так.
Основная причина вызов из класса (Math.PI) и деление.
А вообще всегда можно протестировать :)
0
Сейчас проверил, в 10.1 разница на моем железе:
1) от 1 миллиона итераций примерно для inline
2) от 200 тысяч итераций примерно для вызова своей функции где используется PI
Так что оптимизации похоже есть, но константа все равно быстрее :)
0
Тут скорее именно вызов функций влияет на результаты оптимизации.
0
когда v.x == x а v.y == y выдастся ошибка NaN.
0
ну так отличный результат для такого случая.
+1
Деление на ноль, нужно x проверять перед выполнением atan2.
0
Меня всегда интересовал впорос — почему при делении на ноль ошибка? Получается ведь тоже число если логически посудить. Любое число делить на ноль раз — получается тоже самое число.

-_____-
0
Подели восемь яблок на ноль человек, сколько каждому достанется?
0
Это совсем другой пример я думаю. Если мы число делим на ноль раз, то число просто не будет делится. и Останется таким какое оно есть) Тоесть никому никаких яблок не достанется их и останется восемь у какого-нибудь дяди) Тут смотря с какой стороны подходить к вопросу…
0
При делении на ноль получается бесконечность, а не то же самое число.
0
Есть такое дело как разрядность регистров процессора в битах (8,16,32,64 и т.д.).
Для деления на уровне чипа используются битовые сдвиги и маски (при беззнаковом) и вычитания при знаковом.
При этом есть проверки результатов операции на больше, меньше 0.
При 0 в качестве делителя, на выходе будет мусор, т.к. первый же сдвиг/вычитание выдаст неверный ответ.
На самом деле при деление как таковом никакой ошибки не происходит, но на выходе будет мусор или тоже самое число, а это не правильно.
Чтобы число было тоже самое, делить нужно на 1.
Вот чтобы избежать такой неоднозначности и сделали деление на ноль ошибкой, которая выдается сразу, еще до деления.
При операциях с плавающей точкой все немного сложнее, но суть таже.
Раньше подобные операции выполнялись программно, позже это перенесли на уровень чипов, но алгоритмы работы не изменились :)
0
Бесконечность человеку трудно представить, это такая большая неопределенность что по сравнению с ней нет различий между 8, 1 или 100, по сравнению с такой неопределённостью можно посчитать что эти числа равны ;) Взяв в расчет бесконечность получаем такую мега погрешность в которой все числа равны, а математика точная наука, ей такие погрешности нафик ненужны, поэтому делить не рекомендуют =)

гдето пример был похожий:
3*5 = 3*5 // =15. сократим на 5
3*5/5 = 3*5/5
3 = 3 //всё верно =) теперь с нулем
3*0 = 5*0 // =0. сократим равенство на 0, попытаемся поделить по правилам =)
3*0/0 = 5*0/0
3 = 5
0
3*0 = 3*0 // =0. сократим равенство на 0, попытаемся поделить по правилам =)
3*0/0 = 3*0/0
3 = 3
Всё работает (:
0
Подели восемь яблок на ноль человек, сколько каждому достанется?
Если яблоко поделить на ноль, то его масса будет стремиться к бесконечности --> оно сначала сколлапсирует в черную дыру, после чего, с дальнейшим увеличением, начнет втягивать вселенную в точку.
2 darkvam. Так что не советую яблоки на 0 делить ))))
0
))) я ближе к декабрю 2012 года попробую всётаки поделить. ок?
+1
Чтобы с физическим объектом такое провернуть, всего-то нужно разогнаться до скорости света при этом толкая предмет, масса которого постоянно возрастает.)) Так что беговые тренировки нужно начинать уже сейчас. ^_^
0
Отожгли или потролили? ;)

х/1 = х
х/0 = х
Значит 1 = 0, значит произведем равноценным обмен, я вам 0 миллионов, а вы мне 1.

Можно логически проследить куда стремится число при уменьшении знаменателя:
х/1 = х
х/0,5 = 2х

х/0,1 = 10х
х/0,01 = 100х
0
Тут дело не в расчётах как таковых. Математика это философия а 0 я не принимаю здесь как бесконечно минимальное значение чего либо. Я говорю о том что ноль — это ноль. И в этом вся сложность.

Первый пример оч правелен. Но это недостаток чисел. А если расуждать не числами?) А на банальном бытовом уровне.) Хочу ещё потроллить)
0
И ещё делаем проверку.

8/1 = 8
8/0 = число стремящееся к бесконечности, тоесть — бесконечно.
Деление проверяется умножением.
бесконечность * 0 = 8.

Круто.

Ну вопще тут прослеживается недостаток математики либо не оговоренность некоторого рода)
0
Дивижан Байзира ))))
0
-_________________________-
0
Ну так 8/0 совсем не равно бесконечности и такая операция запрещена, т.к. она приводит к противоречиям :)
Другое дело, что предел число/переменная приближается к бесконечности, когда переменная приближается к 0.
0
Ну речь не о том запрещена или нет — а в том что будет если произвести такую операцию) В разных случаях я считаю будет отслеживатся разный результат. В сложных расчётах — будет приближатся к бесконечно млаому числу. А если говорить на бонально бытовом уровне — останется число.) Математика это ведь прежде всего философия)
0
Ну вот по этому то и сказали что на ноль делить нельзя, т.к. появляются адовые противоречия ))
0
вот именно поэтому математика ниразу не точная а лишь приближенная к точности наука!)))))
0
В этом мире вообще ничего точного нет ;)
0
Просто надо быть готовым что наш мир устроен несколько сложней чем человек может представить, и в нём есть особые объекты, топологичные нулю, бесконечности или мнимому числу, свойства которых не очень ощущаются человеческим разумом :)
0
От себя добавлю — не факт что вообще человек способен понять всю сложность вещей. Например у собаки тоже есть мозг, но она никогда не поймёт e=mc2.

Так что всё плачевно)
+2
Многие люди тоже никогда не поймут этой формулы, так что ок ;)
0
бесконечность * 0 равна неопределенности, поэтому можете считать, что и 8 и 1 ;)

На банальном уровне 8 яблок можно разделить между Х людьми, но если никого нет, то между никем их и нельзя разделить — они остнутся сами по себе, а никто останется без яблок ;)
0
На банальном уровне деление — «сколько раз мы можем взять одно число из другого». Сколько раз мы можем взять 0 палочек из 8 палочек? Правильно — бесконечно много раз.
0
Это всё интерпретации)
0
Раз уж на то пошло, то все в этом мире лишь интерпретация нами сигналов от органов чувств
0
и вообще всё что вокруг нас это эл. магнитные импульсы. Тоесть вполне вероятно мы — некие объекты лежащие в какойнить баракамере с присоединёными к нам передатчиками передающими нам все эти сигналы. Тоесть — МЫ В МАТРИЦЕ. И это настоко реальное предположение что даже страшно…
0
Страх это все тоже только ЭМ импульсы, так что спокойствие ;)

0 палочек мы взять при всём желании не сможем)

Отнюдь, вы можете взять ни одной палочки много-много раз
0
это уже совсем страшно. Пойду ка возьму себе истребитель пожалуй. полетаю.
0
Кстате, если есть воздух много много раз — скорей всего наешься правда?
0
0 палочек мы взять при всём желании не сможем)
0
Вообщем предлагаю завязать с оффтопом :)
0
все равно пустота это гораздо круче)
0
кстати это хороший пример, когда что-то обладает свойствами ничего и бесконечности)
0
В atan2 нет деления на ноль и ему не страшен любой нулевой аргумент. Проверка x == 0 происходит внутри для выдачи соответствующего результата (+PI/2 или -PI/2).
Другое дело если оба аргумента равны нулю 0о — это абсурд. Угол поворота точки мы не проходили.
И проверку этой ситуации внутри angleTo() для вывода какого-то другого результата я бы не стал делать — нерациональное замедление работы ради нелепого случая, которого можно избегать уровнем выше.
0
Ну-ну, случаи бываю разные, и сделать банальную быструю проверку конечно же сложнее, чем потом искать странности поведения.

Это абсурд, но такая ситуация возможна — две точки находятся в одном месте, или вы считаете, что проверка нахождения точек в одном месте будет быстрее?
0
А чем отличается «проверка нахождения точек в одном месте» от проверки на два нуля, которую мы здесь обуждаем? Это собственно она и есть в данном контексте.

И я не говорю, что эту проверку не следует делать. Я лишь говорю, что не стал бы вносить ее в тело angleTo («избегал бы уровнем выше»). Ведь я могу обходить заведомо ненулевые вектора быстрее, чем если бы это сделал, скажем, angleTo2, спотыкающийся об if.
0
В качестве защиты от дурака, например. Если эта функция входит в библиотеку, которой могут пользоваться другие.

Думаю, что проверка равенства двух чисел нулю все равно намного быстрее вычисления арктангенса.
0
В сравнении — безусловно.
Но при большом количестве точек я бы не жертвовал в фонд дураков своими миллисекундами )

И кстати — это только у меня Math.atan2(0, 0) выдает просто 0 без каких либо ошибок?
+1
Вот и закончилась наша дискуссия ни о чем ))

atan2(0, 0) = 0

а это вполне соответствует… действительности?
0
Да, как-то поверил комментарию про бесконечноть ;)

Но не совсем ничем, в данном случае вы были правы — проверка должна проводиться уровнем выше, т.к. в контексте результат может быть некорректен.

Поясню: предположим есть пушка, которая следит за мышью. Если мышь навести точно на пушку — то вычисление даст угол 0, но в данном случае корректно было бы оставить предыдущее значение — потом что при наведении отведении угол будет скакать между действительным углом и нулем.
0
Ну вы аццкие флудеры! Перед Новым Годом скучно? (:
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.