Розкладання увігнутої сітки в набір опуклих сіток


10

Я хотів би мати можливість розкласти увігнуту сітку в набір опуклих сіток з 2 причин:

  1. Прозора візуалізація
  2. Фізичні форми

Чи існує алгоритм, який приймає набір трикутників (увігнутий) як вихідний і видає ряд наборів трикутників (опуклих)? Мені б хотілося, щоб вони не заповнювали отвори між частинами оригінальної сітки.

Я вже натрапив на маленьку ідею: знайдіть усі увігнуті краї та розділіть сітки уздовж крайових петель. Я на правильному шляху? Як я міг це здійснити?


Що таке "увігнута / опукла" сітка? Якщо сітка означає трикутну мережу, то це просто набір трикутників, які є опуклими. Або ви говорите про об'єм 3D-об'єктів? Може, багатогранники?
Іван Кукір

@IvanKuckir Meshes, або багатогранники, теж можуть бути увігнутими / опуклими, і визначення майже однакове. Наприклад, жодна пряма лінія не перетинатиме внутрішню частину багатогранника не один раз.
congusbongus

Відповіді:


11

Я б сказав, що ви на правильному шляху, але придумати оптимальний та / або ефективний алгоритм - інша справа: це складна проблема. Однак, якщо ваш інтерес не є академічним, достатньо хорошого рішення може бути достатньо.

По-перше, якщо вам не цікаво розробити власне рішення, CGAL містить вже алгоритм розкладання опуклих багатогранників: http://doc.cgal.org/latest/Convex_decomposition_3/index.html

Тепер про метод; як і багато проблем у 3D, часто корисно розглянути 2D-проблему, яку легше зрозуміти. Для 2D завдання полягає в тому, щоб визначити рефлекторні вершини та розділити багатокутник на дві частини, створивши з цього рефлекторної вершини новий край (і, можливо, нові вершини), і продовжуючи, поки у вас не залишиться рефлекторних вершин (а отже, і всевипуклі багатокутники ).

рефлекторні вершини

Розкладання багатокутника Дж. Марка Кіля містить такий алгоритм (у неоптимізованому вигляді):

diags = decomp(poly)
    min, tmp : EdgeList
    ndiags : Integer
    for each reflex vertex i
        for every other vertex j
            if i can see j
                left = the polygon given by vertices i to j
                right = the polygon given by vertices j to i
                tmp = decomp(left) + decomp(right)
                if(tmp.size < ndiags)
                    min = tmp
                    ndiags = tmp.size
                    min += the diagonal i to j
    return min

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

Якщо ви хочете "приємніше виглядати" декомпозиції, тобто ті, що створюють більш компактні форми, а не подовжені, ви можете також вважати цю, вироблену Марком Баязітом , яка жадібна (отже, набагато швидше) і виглядає красивіше, але має кілька недоліків. В основному це працює, намагаючись підключити рефлекторні вершини до найкращої, протилежної йому, як правило, до іншої рефлекторної вершини:

нова вершина баязит з'єднати з іншою рефлекторною вершиною

Одним із недоліків є те, що він ігнорує "кращі" декомпозиції, створюючи точки Штейнера (точки, які не існують на існуючому краю):

розклад конюшини за допомогою двох точок стейнера

Проблема в 3D може бути подібною; замість рефлекторних вершин ви ідентифікуєте "краї висічки". Наївною реалізацією було б визначити краї висівок і виконувати плоскі надрізи на багатогранні кілька разів, поки всі багатогранники не опуклі. Перегляньте "Опуклі перегородки багатогранників: нижній межі та найгірший оптимальний алгоритм" Бернарда Шазел для більш детальної інформації.

багатогранник з вирізом

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

багато зубчастих багатогранників

Але якщо у вас є нетривіальна сітка (подумайте, куляста поверхня), все одно ви отримаєте погані результати. Цілком ймовірно, що вам потрібно буде заздалегідь зробити багато спрощень, якщо вам коли-небудь доведеться використовувати це для складних сіток.


6

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

Точне опукло розкладання проти приблизного опуклого розкладання

Перегляньте такі приблизні бібліотеки опуклої декомпозиції: https://code.google.com/p/v-hacd/ http://sourceforge.net/projects/hacd/


0

Ось код, який може вам допомогти. Це в java, тому вам доведеться перетворити його на c ++.

Ось також ще одна стаття, яка може вам допомогти


1
Привіт, маска-повсталий, тут не відволікаються лише посилання. Якщо URL-адреса коли-небудь змінюється або ресурс стає недоступним, він може залишити відповіді, що повністю залежали від посилання, повністю порожніми від рішень для майбутніх користувачів. Чудово надавати посилання для кредитування та подальшого читання, якщо ваша відповідь все ще може стояти самостійно та надавати посібник щодо вирішення проблеми ще до того, як читач натисне глибше. Будь ласка, подумайте про редагування цієї відповіді, щоб включити принаймні широкий контур того, як працює рішення, яке ви посилаєтесь.
DMGregory

@DMGregory Будь ласка, видаліть відповідь, яку я не можу сам.

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

@DMGregory, але тоді це буде дублікат іншої відповіді на це повідомлення. Я просто відредагую іншу відповідь і покладу туди свою інформацію.

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