Russian Qt Forum

Программирование => Алгоритмы => Тема начата: Igors от Март 07, 2021, 07:47



Название: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 07, 2021, 07:47
Добрый день

Пример: на стенах комнаты разбросаны точки, в каждую записана нормаль N (грубо говоря "перпендикуляр к стене"). Требуется:

а)  отсортировать так чтобы сначала шли точки первой стены, затем второй и.т.д

b) для заданного вектора V найти точку с ближайшей нормалью (минимальным углом между V и N)

Как-то выглядит "совершенно нерешаемо" :)

Спасибо


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Racheengel от Март 17, 2021, 15:33
а) непонятно, а что сортировать-то? стены? нормали? точки?
б) как это должно выглядеть ("на картинке"), в чём собственно суть задачи?


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 18, 2021, 08:48
а) непонятно, а что сортировать-то? стены? нормали? точки?
Точки в которых записаны нормали


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 18, 2021, 08:59
По ходу дела образовалась еще задача, которая включает предыдущую.

Я всегда считал что делать что-то для 4 и более измерений (типа "обобщать") - так, "для галочки", практического применения не имеет. Но вот "за мной пришли" :)

Как и в начальной задаче, на стенах комнаты разбросаны точки, в каждую записана нормаль. Требуется для заданной точки P с нормалью N найти все ближайшие к ней в заданном радиусе R, а также с нормалями отклоняющимися от N не более чем на заданный угол (напр 10 градусов)

Правда никаким "формальным обобщением" (типа template) здесь и не пахнет, как всегда, каждое новое измерение "меняет сущность". Тем не менее "N измерений" (N > 3) налицо


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Racheengel от Март 18, 2021, 11:09
А известно заранее, какая точка принадлежит какой стене?


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 18, 2021, 11:51
А известно заранее, какая точка принадлежит какой стене?
Нет. "Стена" - это просто для примера чего нужно добиться, данных для стены нема


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Racheengel от Март 18, 2021, 12:07
Тогда, как говорится, "мало данных". Нормали у нескольких стен могут совпадать. Необходимо как минимум иметь координаты точек в пространстве и информацию о том, к какой "стене" они принадлежат.


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 18, 2021, 12:10
Тогда, как говорится, "мало данных". Нормали у нескольких стен могут совпадать. Необходимо как минимум иметь координаты точек в пространстве и информацию о том, к какой "стене" они принадлежат.
Ну шо так тяжко, совсем старый уже? :) Конечно есть и координаты и нормали
Код
C++ (Qt)
struct CPoint {
 QVector3D position;
 QVector3D normal;
...
};


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 18, 2021, 12:23
Цитировать
Требуется для заданной точки P с нормалью N найти все ближайшие к ней в заданном радиусе R,
kd-tree?  :)


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Racheengel от Март 18, 2021, 12:31
эх "Старость не радость"...
Координаты есть - это уже хорошо. А координаты стен, может, тоже где-то лежат? :)


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 18, 2021, 13:17
kd-tree?  :)
И как Вы себе представляете отсечку/деление "по нормали"?

Координаты есть - это уже хорошо. А координаты стен, может, тоже где-то лежат? :)
Ну да, "может еще че дадут" (логика кота  :)). Стены - просто конкретный пример, в общем случае есть "3D сцена" (со всеми вытекающими)


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 18, 2021, 13:37
Цитировать
И как Вы себе представляете отсечку/деление "по нормали"?
Ну если стены известны (нормали к каждой из стен), то принадлежность произвольного вектора можно к какой либо из стен (с заданной точностью) можно определить..
Ну например, по скалярному произведению.. 


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 18, 2021, 14:14
Ну если стены известны (нормали к каждой из стен), то принадлежность произвольного вектора можно к какой либо из стен (с заданной точностью) можно определить..
Ну вот, еще один "держится за стены" :) Конечно можно, но требуется макс быстро находить(всех) ближайших, а не "проверяться" (с тем чего нет).

Ну например, по скалярному произведению.. 
А разве есть какой-то еще пример?  :)

Возможно есть смысл заняться сначала более простой задачей (стартовый пост). Расстояние между векторами нормалей обратно пропорционально скалярному произведению, и эти 2 вещи однозначно переводятся друг в друга. Но...


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 18, 2021, 16:39
Цитировать
Ну вот, еще один "держится за стены"
А за что ещё держаться, если такая постановка проблемы?
Да, возможно kd-дерево будет скудным (всего 4 стены), но хоть что-то..
А как Вы вообще себе представляете сортировку в пределах одной стены? Какой критерий?

Цитировать
А разве есть какой-то еще пример?
Ну это самый разумный..


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 19, 2021, 09:38
А за что ещё держаться, если такая постановка проблемы?
Нормальная, творческая постановка, то Вы, как всегда, тормозите.

"Точка" = структура данных, имеет по меньшей мере позицию и нормаль (псевдокод выше). В пр-ве имеется N таких точек (много мульенов). Требуется для запросной точки P быстро находить ближайших по обеим: позиции и нормали, оба критерия близости (радиус и угол отклонения) имеются.

Возможно хотелась такая постановка "чтобы сразу знать как решать", но у меня таких нет :).

Рассмотрим только нормаль (стартовый пост). В пр-ве это соответствует точкам на поверхности сферы единичного радиуса. Обычное kd-tree будет работать, нужно только перевести угол отклонения в радиус, это несложно
Цитировать
r = sin(angle / 2) * 2;
Да, но что делать если есть и позиция и нормаль? Просто 6-мерный вектор - явно глупо, измерения "неоднородны". Тогда что?


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 20, 2021, 14:37
Цитировать
Да, но что делать если есть и позиция и нормаль? Просто 6-мерный вектор - явно глупо, измерения "неоднородны". Тогда что?
Вот) А что для Вас важнее? Близость по положению или близость по нормали?


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 20, 2021, 15:17
Вот) А что для Вас важнее? Близость по положению или близость по нормали?
А что важнее: рука или нога? Рука? Ну так давайте ногу отрежем, она ведь не очень нужна :) Ну ладно, все равно мыслей нет (у меня тоже), давайте покалякаем.

Есть поверхность бомбардируемая лучами, но которая и сама излучает, испуская 200 (по дефаулту) лучей в заданных напр-ях. Идея сэкономить излучающие, используя (сохраненные) рез-ты "бомбардировки" в заданном радиусе R. Пробуем порешать стандартными средствами: используя kd-tree находим всех ближайших в радиусе R. Допустим нашли 100. И вот дальше сваливаемся в унылый перебор: для каждого заданного напр-я нужно проверять все 100, что недопустимо медленно. А затевать какое-то дерево "на ходу" еще хуже.

И шо делать?


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 20, 2021, 15:27
Цитировать
А что важнее: рука или нога?
А я не знаю.. В одном случае может рука, а в другом - нога..
Я просто не вижу однозначного критерия для построения дерева..
Я бы со своим наивным подходом рассуждал бы так: Давайте вначале, в пределах заданного радиуса R найдём все ближайшие точки.
А потом отсеем из них все, которые по нормали далеки (ну с заданной точностью).. Нет? 


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 20, 2021, 15:55
Я бы со своим наивным подходом рассуждал бы так:
Ну почему "наивным" - вполне нормальным, просто он "ни на что не претендует"

Давайте вначале, в пределах заданного радиуса R найдём все ближайшие точки.
А потом отсеем из них все, которые по нормали далеки (ну с заданной точностью).. Нет?
Так отсеивать придется снова и снова (для каждого из 200 излучаемых лучей). Тут мы все и сожжем


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 20, 2021, 16:24
Цитировать
Так отсеивать придется снова и снова (для каждого из 200 излучаемых лучей). Тут мы все и сожжем
Нет! Один раз выбираем окрестность радиуса R. Во втором проходе выкидываете все точки, которые по нормали не попали..
В итоге два дерева получается - первое по близости, второе по нормали..


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 20, 2021, 16:27
Да во втором случае даже и дерево, возможно, и не понадобится..


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 20, 2021, 16:34
В итоге два дерева получается - первое по близости, второе по нормали..
В смысле "глобальных"? Так их не удается "срастить". Первое найдет 100, второе 1000, искать "пересечения" пол-дня.

Да во втором случае даже и дерева, возможно, и не понадобится..
А прямой перебор "по нормали" точно сожрет до фига.

Не горячитесь, задача очень непростая, не исключено что (хорошего) решения вообще нет


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 20, 2021, 17:30
Цитировать
В смысле "глобальных"? Так их не удается "срастить". Первое найдет 100, второе 1000, искать "пересечения" пол-дня.
Я имею в виду, что коль скоро определён критерий близости точек, то зная радиус R, можно за порядка log(N) найти все точки, лежайшие внутри этого радиуса..
А у же потом отсеять все лишние.. Т.е. kd-дерево строится по принципу ближайших к заданной точки. Дело, конечно, не однозначное.. Ну можно среднее взять и с ним сравнивать..
Ну или.. Постановка проблемы не однозначна просто..
И да, тот чувак не из Ярославля, а с Ростова-на-Дону :)    Кстати, красивый город)


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 21, 2021, 11:38
Я имею в виду, что коль скоро определён критерий близости точек, то зная радиус R, можно за порядка log(N) найти все точки, лежайшие внутри этого радиуса..
А у же потом отсеять все лишние..
Впечатление что "опять не въехал"  :'( Ладно, еще пожуем

Из данной точки выбрасываются 200 (по дефаулту) лучей. Напр-е каждого (нормаль) известно. Перед выбросом каждого просматриваем ближайшие точки в радиусе R. Если найдена хоть одна с близким напр-ем, то используем ее/их, луч не выбрасываем.

Очевидное решение: найти все точки в радиусе R и сохранить их в pre-allocated массиве. Дальше для каждого из 200 лучей отсеивать/просеивать содержимое этого массива. Ну т.е. по расстоянию ищем деревом, по нормали - перебором. Все ясно, но увы - это тормоз. Напр найдено 100 ближайших, 100 * 200 = 20K перебор.


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 21, 2021, 14:37
Цитировать
И да, тот чувак не из Ярославля, а с Ростова-на-Дону
Если  мы об одном человеке говорим?


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 21, 2021, 14:50
Цитировать
Из данной точки выбрасываются 200 (по дефаулту) лучей. Напр-е каждого (нормаль) известно. Перед выбросом каждого просматриваем ближайшие точки в радиусе R.
Так какое  условие? Есть реализация kd-дерева - выложу. Когда однозначно критерий определите, тогда и решение будет..


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 21, 2021, 15:06
Так какое  условие?
Прочтите хотя бы мой предыдущий пост

Есть реализация kd-дерева - выложу.
Спасибо, но не нужно, последние 25 лет пользуюсь своей

Когда однозначно критерий определите, тогда и решение будет..
С чего Вы взяли что умеете решать такие задачи?  :) Напр я таких иллюзий не питаю, может удастся, но очень может быть что и нет.  Не надо петь вечную песню "плохая, неясная постановка", если мыслей нет - то их и нет. Тем более обещать что, мол, "будет"  :)


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 22, 2021, 15:28
Мы, похоже, разными категориями мыслим..

Цитировать
Прочтите хотя бы мой предыдущий пост

Цитировать
Из данной точки выбрасываются 200 (по дефаулту) лучей. Напр-е каждого (нормаль) известно. Перед выбросом каждого просматриваем ближайшие точки в радиусе R. Если найдена хоть одна с близким напр-ем, то используем ее/их, луч не выбрасываем.
Что значит "луч не выбрасываем"? Как я понял имеется набор точек (x, y, z) для каждой из которых задан вектор нормали. Хорошо. Теперь Вы генерируете 200 векторов (лучей) исходящих из заданной точки. У Вас есть kd-дерево, и значит что можно найти все ближайшие точки в окрестности радиуса R.
Проблема теперь сводится к тому, чтобы из всех этих точек выкинуть те, которые по критерию близости по направлению не подходят?
 


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 22, 2021, 16:32
Проблема теперь сводится к тому, чтобы из всех этих точек выкинуть те, которые по критерию близости по направлению не подходят?
Да, причем придется это делать для каждого из 200 сгенерированных лучей
Мы, похоже, разными категориями мыслим..
Да мЫшление тут еще не началось..


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 22, 2021, 16:41
Цитировать
Да, причем придется это делать для каждого из 200 сгенерированных лучей
Ну да.. А какие ещё есть варианты, когда для каждого из лучей нужно условие проверить?


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 22, 2021, 16:49
А какие ещё есть варианты, когда для каждого из лучей нужно условие проверить?
Не понял вопроса. Пока критериев 2: близость по расстоянию (от точки выбросв) и направлению. Идея простейшая: если "примерно такой же" луч уже был - юзаем его, т.к. выброс и последующий шейдинг - удовольствие дорогое


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 22, 2021, 17:06
Цитировать
Не понял вопроса. Пока критериев 2: близость по расстоянию (от точки выбросв) и направлению. Идея простейшая: если "примерно такой же" луч уже был - юзаем его, т.к. выброс и последующий шейдинг - удовольствие дорогое
Это больше риторический вопрос.. Первый критерий решается построением дерева. А вот второй - ничего не остаётся, как прямой перебор..


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 23, 2021, 13:15
Это больше риторический вопрос.. Первый критерий решается построением дерева. А вот второй - ничего не остаётся, как прямой перебор..
Ах как быстро завершен мыслительный процесс (а он вообще начинался?). Ну да, как же мы можем "искать быстро" если заранее не построили нужных структур для поиска? А строить их всякий раз наверняка обойдется дороже перебора. Вот и все, и нефиг тут думать! Низзя!

Хотя есть одна идейка... Простая, всем известная, можно сказать "детская"  :)


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 26, 2021, 01:37
Цитировать
Хотя есть одна идейка... Простая, всем известная, можно сказать "детская"  :)
Ну дык, не томите)


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 26, 2021, 10:19
Ну дык, не томите)
Ну вообще-то хотелось бы от Вас что-то услышать/почерпнуть. А то с 5-го разв наконец "дошло", секунду поразмыслил и сказал что решения нет :) А то что сам знаю от меня никуда не убежит.

Собсно проблема в том что "кратность" поиска здесь мала, напр всего 200. Значит нужно делать "самые дешевые" структуры что помогут искать быстрее. Напрашивается "регулярная сетка". Прогоняем все найденные по расстоянию и заносим их в свои ячейки. Потом для каждого из 200 смотрим что сидит в ихней ячейке (и, возможно, соседних). Вряд ли это "так уж ускорит", но позорное пятно квадратичного перебора смоет.

Правда, реализация совсем не очевидна. Нужно быстро "спрыгивать на ячейку" (типа хеш), как это сделать для векторов напр-я (точек лежащих на сфере)?

Ну вот, сейчас опять начнется "чего-то не понял" и.т.п. :'(


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 26, 2021, 14:27
Цитировать
Ну вот, сейчас опять начнется "чего-то не понял" и.т.п.   :'(
Ну как уж тут не  без этого..

Псевдокод:
Код
C++ (Qt)
typedef vector<pair<point3d, point3d>> data_t;
/*
первый point3d - положение точки, второй - вектор нормали
*/

 
data_t data;
// ...
kd_tree tree(data) // формируем дерево. Один раз.
//...
double R; // радиус
point3d p; // выбираемая пользователем точка
 
data_t result = tree.nearest_in_radius(p, R);
 
 
Здесь result отсортирован по положениям, ближайшим к p?
А нужно ещё по-быстрому отсортировать его по нормалям к p?
Так?


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 27, 2021, 12:15
Здесь result отсортирован по положениям, ближайшим к p?
А нужно ещё по-быстрому отсортировать его по нормалям к p?
Так?
Не так. Требуется находить все данные удовлетворяющие критериям "расстояние" и "напр-е"  для каждого из 200 лучей исходящих из заданной точки. А как это делать - и есть тема обсуждения.

Сортировка по 2 и более ключам здесь смысла не имеет. Ну отсортировали, как бум искать? Кстати kd-tree сортированный result вовсе не гарантирует


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 27, 2021, 15:58
Цитировать
Кстати kd-tree сортированный result вовсе не гарантирует
Да, согласен..

Цитировать
Сортировка по 2 и более ключам здесь смысла не имеет. Ну отсортировали, как бум искать?
Ну тогда никакие структуры и "кластеризация" данных Вам не поможет.. Это всегда будет за O(N log (N))..
Если только не интерполировать начальные данные какой-либо "гладкой" функцией..


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 28, 2021, 06:05
Ну тогда никакие структуры и "кластеризация" данных Вам не поможет.. Это всегда будет за O(N log (N))..
Чего это? Та же регулярная (или нерегулярная) сетка имеет сложность O(N). Правда нужны хорошие "руки" чтобы здесь ее реализовать.

Кстати если так уж хотелось покритиковать постановку - это можно было легко сделать. При миллионах исходных точек скорее всего "чистый" поиск по нормали выдаст много тысяч подходящих/ближайших даже при отклонении < 1 градуса. А при углах 5-10 и подавно.


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 28, 2021, 11:29
Цитировать
Чего это? Та же регулярная (или нерегулярная) сетка имеет сложность O(N). Правда нужны хорошие "руки" чтобы здесь ее реализоват
Ну и как Вы это себе представляете?
Оно вообще того стоит?
Стоит ли создавать некие новые структуры, если речь идёт о O(N) против O(N log(N))?
Вот у Вас есть result (vector<pair<point3d, point3d>>) не отсортированный ни по положениям, ни по нормалям.
Как Вы хотите, имея только его, за O(N) найти все точки, удвл. условию?

Да даже меньше.. Есть std::partial_sort,,


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 28, 2021, 18:48
Стоит ли создавать некие новые структуры, если речь идёт о O(N) против O(N log(N))?
Какой "log", откуда он тут взялся? O(N * M), где N - число запросных точек, M - найденных по первому критерию близости (расстоянию). Рабочий случай N = 200, M = 100, бОльшие значения возможны.

Ну и как Вы это себе представляете?
...
Вот у Вас есть result (vector<pair<point3d, point3d>>) не отсортированный ни по положениям, ни по нормалям.
Как Вы хотите, имея только его, за O(N) найти все точки, удвл. условию?
Я уже сказал как - хеш. Получается O(M) + O(N) (занесение в хеш + поиск в нем). Правда неизвестно насколько это быстрее

Оно вообще того стоит?
"стоит или нет" означает "это для меня слишком трудно, сложно, давайте искать как обойти". В принципе это нормально, но "вторая часть" почему-то никогда не звучит :)


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: m_ax от Март 28, 2021, 19:14
Цитировать
Какой "log", откуда он тут взялся?
Смотрите: У Вас есть result.. Вы его можете отсортировать по положениям точек (O(N log(N))) и аналогично по нормалям.
Т.е. грубо говоря, у Вас будет два контейнера, отсортированных.
В чём проблема, имея их, вытащить нужные точки?

Цитировать
Я уже сказал как - хеш.
Так это не спасёт.. Формирование хэша тоже дорого обходится..
Пользователь задаёт точку и радиус. kd-tree даёт вам result..
Вы хотите result в хэш преобразовать?
 


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: Igors от Март 29, 2021, 10:39
Смотрите: У Вас есть result.. Вы его можете отсортировать по положениям точек (O(N log(N))) и аналогично по нормалям.
Т.е. грубо говоря, у Вас будет два контейнера, отсортированных.
В чём проблема, имея их, вытащить нужные точки?
Почему два? И зачем вообще сортировать если поиску это никак не помогает?

Так это не спасёт.. Формирование хэша тоже дорого обходится..
Пользователь задаёт точку и радиус. kd-tree даёт вам result..
Вы хотите result в хэш преобразовать?
Чего это оно "дорого"? Я же не собираюсь юзать std::unordered_map и.т.п. Есть массив (preallocated) что хранит головы списков. Перед началом поиска он зачищается (memset).  Обе ф-ции (занесение в хеш и поиск) получают на вход точку и по ее вектору напр-я вычисляют ячейку/эл-т этого массива. Занесение линкует точку к ячейке, поиск пробегается по списку. Здесь все ясно.

По сути все сводится к тому "как соскочить на ячейку" имея вектор напр-я (x, y, z). Шаблонное решение - получить инты из x, y, z и дальше банальный hash, остаток от деления. Как это усилить? Предположим на входе 2D вектор (x, y). Тогда ячейка вычисляется гораздо проще, как индексы двумерного массива. Да и точнее. Механически переносить это на 3 измерения, как обычно, плохо (опустим подробности). Вспоминаем что длины всех векторов = 1. Так не использовать ли проекцию вектора на плоскость, напр XZ ? Правда за отбрасывание одной координаты придется заплатить - нужно иметь 2 хеша (один для +y, др для -y). Ну это в общем случае, и это приемлемо. Однако проекции векторов распределены на плоскости совсем неравномерно, можно ли это учесть?

Успеваете за ходом мысли? Если нет, не торопитесь чего-то отвечать, подумайте. А я пока чайку нагною.. :)


Название: Re: Сортировка и поиск по вектору нормали
Отправлено: qtkoder777 от Сентябрь 27, 2021, 12:53
Добрый день

Пример: на стенах комнаты разбросаны точки, в каждую записана нормаль N (грубо говоря "перпендикуляр к стене"). Требуется:

а)  отсортировать так чтобы сначала шли точки первой стены, затем второй и.т.д

b) для заданного вектора V найти точку с ближайшей нормалью (минимальным углом между V и N)

Как-то выглядит "совершенно нерешаемо" :)

Спасибо

В лоб нельзя?