2012-06-20 4 views
4

Мне нужна помощь, чтобы сделать мой код ниже более эффективным и немного почистить его.Как сделать код тригонометрии более эффективным

Как показано на этом image, x и y могут быть любой точкой вокруг всего экрана, и я пытаюсь найти угол t. Есть ли способ уменьшить количество строк здесь?

Примечание: Происхождение находится в верхнем левом углу, и движется вправо/вниз движется в положительном направлении

o := MiddleOfScreenX - x; 
a := MiddleOfScreenY - y; 

t := Abs(Degrees(ArcTan(o/a))); 

if(x > MiddleOfScreenX)then 
    begin 
    if(y > MiddleOfScreenY)then 
     t := 180 + t 
    else 
     t := 360 - t; 
    end 
else 
    if(y > MiddleOfScreenY)then 
    t := 180 - t; 

код находится в паскале, но ответы на других языках с подобным синтаксисом или C++ или java тоже прекрасны.

:= sets the variable to that value 
Abs() result is the absolute of that value (removes negatives) 
Degrees() converts from radians to degrees 
ArcTan() returns the inverse tan 

ответ

6

см. Это http://www.cplusplus.com/reference/clibrary/cmath/atan2/ для функции C.

atan2 принимает 2 отдельных аргумента, поэтому может определять квадрант.

паскаль может иметь arctan2 см http://www.freepascal.org/docs-html/rtl/math/arctan2.html или http://www.gnu-pascal.de/gpc/Run-Time-System.html

o := MiddleOfScreenX - x; 
a := MiddleOfScreenY - y; 

t := Degrees(ArcTan2(o, a)); 
+0

Большое спасибо за вашу помощь, да, что существует точная функция, и она отлично работает (как только я выберу «Abs()»). – putonajonny

+1

Я достал абс, извините за ошибку. –

3

Количество строк кода не обязательно только оптимизации необходимо учитывать. Тригонометрические функции являются дорогостоящими с точки зрения времени, которое требуется для того, чтобы один из них завершил вычисление (т. Е. Один вызов cos() может потребовать сотни добавлений и умножений в зависимости от реализации).

В случае широко используемой функции при обработке сигналов, дискретное преобразование Фурье, результаты тысяч вычислений cos() и sin() предварительно вычисляются и сохраняются в массивной таблице поиска. Компромисс заключается в том, что при запуске приложения вы используете больше памяти, но оно работает намного быстрее.

См. Следующую статью или поиск важности «предварительно вычисленных факторов скручивания», что по сути означает вычисление тонны сложных экспонент заблаговременно.

В будущем вы также должны указать, что вы пытаетесь оптимизировать (например, используемые циклы процессора, количество используемых байтов памяти, стоимость, между прочим). Я могу только предположить, что вы хотите оптимизировать с точки зрения выполняемых инструкций и, как следствие, количество используемых циклов процессора (т. Е. Вы хотите уменьшить накладные расходы процессора).

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.34.9421&rep=rep1&type=pdf

+1

Огромное спасибо, вы много мне задумались и заглянули. – putonajonny

1

Вы должны только один тест, чтобы определить, что делать с арктангенсом .. существующие тесты восстановить информацию разрушенной Abs().

atan() обычно возвращается в диапазоне от -pi/4 до pi/4. Ваша система координат немного странная - поверните на 90 градусов по часовой стрелке, чтобы получить «стандартный» вариант, хотя вы принимаете atan из x/y в отличие от y/x. Мне уже трудно решить это в моей голове.

В любом случае, я считаю, что ваш тест должен быть таким, что если вы отрицательны a, добавьте 180 град. Если вы хотите избежать отрицательных углов; добавьте 360 град, если это отрицательно.

+0

Спасибо за вашу помощь, причина, по которой она похожа на х/у, заключается в том, что я хочу, чтобы угол к вертикальной оси не был под углом к ​​горизонтальной оси, да, я уничтожал информацию с помощью 'Abs()', поэтому я знал, что это неэффективно. – putonajonny

+0

Да, я понял это, когда подумал ... о, Противоположный и смежный. Я вижу, что он там делал. – zebediah49

Смежные вопросы