Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.133.149.168] |
|
Сообщ.
#1
,
|
|
|
Всем доброго времени суток
Подскажите, существует ли способ быстро (очень быстро) определить превышает ли разница между 2 углами pi/2, или к примеру pi/6 Под разницей я понимаю минимальное расстояние (радианах) между 2 углами на тригонометрической окружности. Т.е. если есть 2 угла 10 и 350 градусов, разница между ними равна 20 градусов Углы даны в радианах Заранее спасибо |
Сообщ.
#2
,
|
|
|
ИМХО быстрее чем тупо посчитать угол и сравнить не получится.
#define PI 3.1415 float distance(float a, float b) // считает разницу между двумя углами { float r1, r2; if (a>b) { r1 = a-b; r2 = b-a+2*PI } else { r1 = b-a; r2=a-b+2*PI; } return (r1>r2) ? r2 : r1; } Недостаточно быстро? |
Сообщ.
#3
,
|
|
|
Цитата Yakudza @ ИМХО быстрее чем тупо посчитать угол и сравнить не получится. #define PI 3.1415 float distance(float a, float b) // считает разницу между двумя углами { float r1, r2; if (a>b) { r1 = a-b; r2 = b-a+2*PI } else { r1 = b-a; r2=a-b+2*PI; } return (r1>r2) ? r2 : r1; } Недостаточно быстро? Примерно так и считаю, хотелось бы пошустрее конечно. (речь идет о тысячах таких операций в секунду) |
Сообщ.
#4
,
|
|
|
Цитата Daiver @ хотелось бы пошустрее конечно Быстрее только таблицу готовую сделать. Можешь заинлайнить еще. Добавлено Цитата Daiver @ речь идет о тысячах таких операций в секунду Несколько тысяч вызовов этой функции отработают на порядок быстрее 1 сек. |
Сообщ.
#5
,
|
|
|
shm Насчет таблицы - можно поподробней?
Пускай не тысячи, а десятки тысяч, плюс все пишется на питоне Добавлено Важно даже не получить точную разницу, а узнать что эта разница больше/меньше определенного угла (pi/6 к примеру) |
Сообщ.
#6
,
|
|
|
Цитата Daiver @ Насчет таблицы - можно поподробней? Да все банально: создаешь двухмерный массив n*n, чем больше n, тем больше будет точность, но тем больше потребуется памяти. Пусть столбцы будут первым углом, а стоки вторым. Ну и заполняешь эту матрицу своей функцией. Потом дял получения искомого результата пользуешься уже вычисленным значением. Правда не знаю как это будет выглядеть на питоне. |
Сообщ.
#7
,
|
|
|
Цитата shm @ Да все банально: создаешь двухмерный массив n*n, чем больше n, тем больше будет точность Я бы создавал одномерный и индексировал его по (a-b). Так и памяти меньше и индексировать проще. С другой стороны будет ли залезть в этот массив быстрее? Еще же углы нужно к индексам привести, проинтерполировать между соседними точками... Исходная функция-то дешевенькая. Хотя если сделать плотный массив, приведеие к индексу свести к приведению типа и брать первый попавшийся элемент без интерполяции, то должно помочь. Хотя, если в некоторых вычислительных пакетах пришли к тому, что интеграл быстрее лишний раз взять численно, чем из памяти его доставать... Если совсем проблема будет с ускорением, то можно на С модуль к питону (плагин? как оно называется) написать и просить эту функцию. |
Сообщ.
#8
,
|
|
|
Yakudza Боюсь что сам вызов сишной ф-ии будет слишком дорогой
|
Сообщ.
#9
,
|
|
|
Если развивать идею с хешем.
Если набор углов фиксирован, то ускорения можно добиться тупо массивом bool. bool hash_half_pi[720]; // fill for pi/2 for (int i = 0; i < 90; ++i) hash_half_pi[i] = false; for (int i = 90; i < 270; ++i) hash_half_pi[i] = true; for (int i = 270; i < 450; ++i) hash_half_pi[i] = false; for (int i = 450; i < 630; ++i) hash_half_pi[i] = true; for (int i = 630; i < 720; ++i) hash_half_pi[i] = false; bool is_larger(float a, float b, bool* hash) { return hash[int(a-b)+360]; } Но на границах может врать. |
Сообщ.
#10
,
|
|
|
откуда берутся эти углы и какова более общая задача?
А то, может, углы вычисляются через arc-функции... |
Сообщ.
#11
,
|
|
|
Yakudza Хэш не совсем пойдет, т.к. углы могут быть произвольными
MBo Гм, в общем-то да, углы вычисляются через arctan2. Так я ищу угол наклона градиента А задача - реализация SWT-оператора с последующей фильтрацией. Углы сравниваются на этапе отслеживания лучей |
Сообщ.
#12
,
|
|
|
Daiver
Получается, что есть два вектора? Тогда угол между ними можно найти, не вычисляя угол наклона каждого по отдельности. Кроме того, для проверки попадания угла в диапазон и арктангенс не понадобится, достаточно будет найти отношение векторного и скалярного произведений векторов |
Сообщ.
#13
,
|
|
|
Пожалуй, самый быстрый способ найти угол между двумя углами (лучами) это:
da = a1 - a2 # Ищем разность if da < -pi: da += 2*pi # и загоняем её в промежуток +-pi elif da > pi: da -= 2*pi Цитата MBo @ Не совсем, можно нарваться на ошибку деления на ноль. Так что лучше раскрывать пропорцию.достаточно будет найти отношение векторного и скалярного произведений векторов Но действительно, вычислять арктангенс, даже если предполагается сравнивать каждый угол с каждым незачем. Это дольше, чем сравнивать пропорции. |
Сообщ.
#14
,
|
|
|
Цитата Daiver @ Под разницей я понимаю минимальное расстояние (радианах) между 2 углами на тригонометрической окружности Так и флаг в руки Цитата const double TOLERANCE = 0.0001; if (deltaAngle > TOLERANCE) { } else { } А уж что на вход дельтаУгол - сам решай. Мне хватает двух точек - точки вставки (база) и точки ориентации (направление). |