Знаходження в яких точках трикутників


16

Припустимо, у мене є 2D сітка, що складається з неонових трикутників , і набору точок { p i } M i = 1N k = 1 T K{Tk}k=1N{pi}i=1Mk=1NTK . Який найкращий спосіб визначити, у якому трикутнику лежить кожна з точок?

Наприклад, на наступному зображенні маємо , p 2T 4 , p 3T 2 , тому я хотів би функцію f, яка повертає список f ( p 1 , p 2 , p 3 ) = [ 2 , 4 , 2 ] .p1T2p2T4p3T2ff(p1,p2,p3)=[2,4,2]

введіть тут опис зображення

Matlab має функцію pointlocation, яка робить те, що я хочу для мереж Delaunay, але воно не вдається для загальних сіток.

Моя перша (німа) думка полягає в тому, що для всіх вузлів перегляньте всі трикутники, щоб з'ясувати, в якому трикутнику знаходиться p i . Однак це вкрай неефективно - вам, можливо, доведеться перебирати трикутник для кожної точки, тому це може зайняти роботу O ( N M ) .pipiO(NM)

Моя така думка, для всіх точок , знайти найближчий вузол сітки з допомогою найближчих сусідів пошуку, потім подивитися через трикутники , приєднані до цього найближчого вузла. У цьому випадку робота буде O ( a M l o g ( N ) ) , де a - максимальна кількість трикутників, приєднаних до будь-якого вузла в сітці. З цим підходом є кілька вирішуваних, але дратівливих проблем,piO(aMlog(N))a

  • Це вимагає здійснення ефективного пошуку найближчого сусіда (або пошуку бібліотеки, яка має його), що може бути нетривіальним завданням.
  • Він вимагає збереження списку, який трикутники приєднані до кожного вузла, на який мій код наразі не налаштований - зараз є лише список координат вузла та список елементів.

Загалом це здається неелегантним, і я думаю, що повинен бути кращий шлях. Це має бути проблема, яка виникає дуже багато, тому мені було цікаво, чи хтось може порекомендувати найкращий спосіб підійти до пошуку трикутників, у яких є вузли, теоретично чи з точки зору наявних бібліотек.

Спасибі!

Відповіді:


16

Звичайний рандомізований метод перестрибування ребер повинен працювати. В основному почніть з будь-якого трикутника сітки, а потім визначте, який із ребер цільова точка лежить на протилежній стороні від. Тобто визначте, який з ребер, витягнувши на лінію, відокремте точку від внутрішньої частини трикутника. Коли є дві можливості, виберіть одну навмання і розгляньте трикутник, що прилягає до цього спільного краю, і повторіть. Рандомізація повинна змусити цей метод сходитись з ймовірністю 1 для триангуляцій Делоне, і я не можу придумати причину, яка б не спрацювала для довільних триангуляцій.

Редагувати : Я повинен додати, що перехід через край повинен бути з розумною константою для однієї точки, так що це буде O ( M log N ) для MO(logN)O(MlogN)М точок. Однак, якщо ви сортуєте свої точки за місцевістю (наприклад, спочатку замовляючи криву Гільберта), ви можете ініціалізувати кожен новий запит трикутником попереднього запиту, щоб ще більше скоротити час виконання (я не теоретик CS, щоб я міг " я скажу вам, що там би велике О).

Edit2 : знайшов цей PDF описує таку схему "прогулянки", яка гарантовано припиняється, та розглядає більш наївні підходи.

Іншою альтернативою для використання чотиривіршів є використання ієрархії тріангуляції. Дивіться Олів'є Дияволів. Поліпшення покрокової рандомізованої триангуляції Делоне. У Зб. 14-а Ану. ACM Sympos. Обчислення. Геом., Стор. 106-115, 1998. Це найкраще працює для триангуляцій Делоне, але також може працювати і для неделоно.

В основному все, що ви робите для прискорення розташування точки, вимагатиме побудови допоміжної структури даних. У випадку з квадратами чи іншим просторовим підрозділом потрібно створити дерево підрозділу. У разі перестрибування краю потрібно побудувати трикутник, що примикає до топологічної структури. Ієрархія тріангуляції також вимагає побудови дерева грубіших триангуляцій.


Віктор - ти знаєш якийсь код з відкритим кодом, який впливає на підхід, що підскакує? Це виглядає зображення, це може бути дуже хорошим рішенням для мого випадку. (модель відстеження частинок, керована поточними полями в сітці сімейства тренінгів) -Дякую
Кріс Баркер

У мене є код для цього, і я можу вам його надіслати; це в C / C ++. Ще не встигли його почистити та опублікувати на Github. Мені довелося писати це принаймні двічі в житті, один раз із структурою даних на півмежі, знову з квадратом, але це можна легко використовувати, коли таких немає, і вам потрібно побудувати топологічну структуру самостійно. Подивіться на мою сторінку профілю для мого веб-сайту, де ви можете знайти контактну інформацію. Ми можемо обговорити це ще в автономному режимі.
Віктор Лю

Я майже закінчив реалізувати це в matlab, використовуючи впорядкування кривих Гільберта та рандомізовану трикутну прогулянку. Це дослідницький код: не оптимізований, не задокументований тощо, але все ще досить швидко - я можу надати вам код, якщо вас зацікавить.
Нік Алгер

2
Про: "" "перехід через край повинен бути O (logN)" "" Я цього не бачу. Наприклад, у патологічному випадку великої тривалої смуги трикутника (як вузький канал лише на трикутнику шириною), в гіршому випадку, вам доведеться переходити від одного трикутника до наступного аж до кінця. У середньому випадку на півдорозі. Отже, якщо подвоїти кількість трикутників, це було б O (N) У більш нормальному випадку розташування трикутників з квадратним ішем я б очікував O (sqrt (N)). Або я щось пропускаю? -Кріс
Кріс Баркер

@Chris - Ласкаво просимо до scicomp! У рамках ведення господарства scicomp я перемістив ваші відповіді та подальшу розмову як коментар до відповіді Віктора. Ми з нетерпінням чекаємо вашої участі на сайті.
Арон Ахмадія

8

Я не впевнений, що ваше рішення насправді правильне. Розглянемо ситуацію, коли у вас є ці вузли:

  • A: (-3, 1)
  • B: (0, 2)
  • C: (3, 1)
  • D: (0, -5)

Існують трикутники ABC і ACD. Тепер B є найближчою точкою до початку, але початок знаходиться в трикутнику ACD, який не містить B.

Для решти ця відповідь пропонує рішення, яке може бути у вироджених випадках так само повільним О(NМ), але, як правило, буде швидше - особливо це стосується триангуляцій Делоне та триангуляції, близьких до певного сенсу.

Я б розглядав варіант побудови квадрату, який містить самі трикутники. Тобто, у вас є четвертинне дерево, яке зберігається у кожному вузлі (що відповідає обмежувальній коробці):

  • Координати, за якими розділяється вікно, або, як альтернатива, обмежувальні поля чотирьох підрядів;
  • Покажчики на підряди;
  • Сукупність трикутників, які повністю потрапляють в обмежувальний ящик цього прямокутника, але не повністю в межах будь-якого з чотирьох підрядів. Іншими словами, трикутники, які перетинаються з будь-яким із двох підрозділювальних відрізків ліній квадрату.

Коли вам дано крапку P, пройдіть усі вузли на шляху від кореня квадратури до найменшого поля, що містить P. Вам потрібно буде вивчити всі трикутники, з якими ви стикаєтесь у цих вузлах. Для тріангуляції «добре поводиться», має бути лише щось подібнен трикутники, які потрібно оглянути на рівні вузла, який містить н трикутники в його піддереві, а глибина повинна бути обмежена на журналн. Для тріангуляції, що погано поводиться, ви можете отриматиО(NМ) робота.


Хм ти маєш рацію. З іншого боку, якби тріангуляція була Делоне, я думаю, що найближчий сусід працював би. Це занадто обмежуюче для того, що я намагаюся зробити, але у випадку Делоне розгляньте подвійну діаграму Вороного - клітини Вороного - це набір точок, найближчих до вузла, а краї трикутників делауна всі відповідають краям Вороного комірки під прямим кутом, тому будь-яка точка повинна знаходитися в трикутнику, з'єднаному з найближчим його вузлом. Цікаво, чи це так, як функція pointLocation matlab працює під кришкою ..?
Нік Алгер

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.