Алгоритъм за 2D контур за проектирана 3D мрежа

Дадено: 3D мрежа, дефинирана с набор от върхове и триъгълници, изграждащи мрежата с тези точки.

Проблем: Намерете 2d контура на проектираната произволно завъртяна мрежа върху произволна равнина.

Прожекцията е лесна. Предизвикателството се състои в намирането на "корпуса" на проектираните ръбове на триъгълник в равнината. Имам нужда от помощ с въвеждане/указатели за изследване на този алгоритъм. За простота можем да приемем, че 3D ръбовете са проектирани право надолу върху равнината xy.


person ralphtheninja    schedule 18.06.2009    source източник
comment
Синята линия не изглежда изпъкнала тук.   -  person Svante    schedule 19.06.2009
comment
Да, прав си. Бързо откраднах това изображение от сайт и нарисувах няколко червени линии върху него, за да илюстрирам. Все още се надявам идеята да се осъществи :)   -  person ralphtheninja    schedule 19.06.2009
comment
@MagnusSkog: Трябва да направя точно това. Кой метод ви подхожда най-добре в крайна сметка?   -  person PeteUK    schedule 10.03.2013
comment
@PeteUK Работи много добре, като избра напр. най-източния възел, измерете ъгли и отидете с най-близкия. Едно предупреждение: Бъдете внимателни с точността на плаваща запетая на ъглите! Спомням си, че имах проблеми с това и алгоритъмът пое по грешен път в мрежата.   -  person ralphtheninja    schedule 12.03.2013
comment
@MagnusSkog Благодаря за отговора и предупреждението относно проблеми с FP. Сега се чувствам по-уверен да правя това :)   -  person PeteUK    schedule 12.03.2013


Отговори (6)


  • Започнете с най-дясната точка (точката с най-голямата x координата)
  • Вземете всички ръбове от тази точка
  • Следвайте ръба с най-малък ъгъл спрямо положителната ос x и също го добавете към набора от решения
  • От достигнатата точка проследете и добавете ръба с най-малък ъгъл към ръба, от който идвате
  • Повторете, докато стигнете до първоначалната точка
person Svante    schedule 18.06.2009
comment
Какво се случва, ако проектирате тор върху равнината x-y? Това няма да доведе до вътрешния отвор. - person nsanders; 19.06.2009
comment
Ами ако има два ръба, и двата равни на най-малкия ъгъл? - person Richard Inglis; 21.06.2009
comment
Хм... Вземете по-късия от двата. - person Richard Inglis; 21.06.2009
comment
Не, измервайте ъгъла само в една посока, напр. обратно на часовниковата стрелка. - person Svante; 22.06.2009
comment
благодаря за хубавото решение @Svante. Бихте ли посъветвали как ще работи това за други указания за проекция, моля? - person flatronka; 19.06.2018
comment
Това решение е само в 2D. Начинът, по който стигате до 2D вход е напълно независим. Можете да нанесете всяка равнина на равнината xy. - person Svante; 19.06.2018

Виждам отговори само за изпъкнали решения, така че ето моят за неизпъкнали. (Беше малко объркващо какво беше намерението.)

Вземете всички ръбове от вашите 2D-триъгълници и ги групирайте. Ако две ребра споделят и двете крайни точки, те са в една и съща група. Всички групи само с един ръб са част от обвивката.

Накрая можете да комбинирате ръбовете на черупката в един пръстен, като ги съедините.

person LaZe    schedule 21.06.2009

Техниката на алфа формите, спомената в този въпрос, обработва общ набор от точки, където връзките на върховете не са известни:

Има ли ефективен алгоритъм за генериране на 2D вдлъбнат корпус?

Въпреки това, тъй като вече знаете информация за "лицето", която може да бъде запазена чрез проекцията, това вероятно не е най-добрият подход.

Алгоритъмът за груба сила може да е осъществим, особено ако се използват структури за пространствено сортиране. например за всеки аспект:

  1. Проектирайте фасет върху равнината
  2. Проверете дали проектираният фасет е напълно затворен от съществуваща геометрия, ако да: готово (няма нужда да разширявате проектирания силует)
  3. Ако точките попадат извън съществуващата геометрия, направете пресичане на триъгълник-триъгълник, за да определите кои части попадат навън, изградете произволен n-ъгълник (евентуално вдлъбнат), за да запълните липсващото пространство, след което нарежете n-ъгълника на триъгълници

Друга идея, в зависимост от прецизността, която изисквате, е просто да изстреляте куп лъчи нормално от вашата проекционна равнина към вашата оригинална геометрия. Създайте 2d попадение/пропускане и го използвайте, за да определите своите граници.

person nsanders    schedule 18.06.2009

2D контурът на проекцията на мрежата е подмножество на проекцията на нейните ръбове.

Използвайки това наблюдение, можете да определите 2D контура, като използвате следния метод:

  • проекцията на всеки ръб, принадлежащ само на едно лице, е част от 2D контура,
  • за други ръбове, определете нормалния вектор на съседните му лица
  • изчислете точковите произведения на тези нормали с нормалата на равнината на проекцията
  • проекцията на този ръб принадлежи на 2D контура, ако всички признаци на точковите произведения не са еднакви (което означава, че едно лице сочи към проекционната равнина, докато поне едно друго не сочи, което идентифицира ръба като част от контур).

Обърнете внимание, че този метод ще отчете всички ръбове, които са ортогонални на проекционната равнина, дори тези, които не се виждат от гледна точка на проекционната равнина. Например, с тор, той ще намери вътрешните и външните очертания, дори когато торът е завъртян по такъв начин, че вътрешният му отвор да не се вижда от гледна точка на равнината на проекцията. За да сортирате кои ръбове се виждат, ще ви трябва някакъв вид тест за видимост. Ако предвидената употреба е за потребителски дисплей, можете да използвате буфер за дълбочина, изчислен с ортогонална проекционна матрица, за да изобразите геометрията от гледната точка на проекционната равнина и да направите някои z-тестове, за да определите кои ръбове са видими от равнината. Ако имате нужда от точност, ще трябва да извършите пресичане на лъч/триъгълник, за да определите видимостта.

person Sebastien Pellizzari    schedule 23.03.2014
comment
Бих препоръчал да направите теста за ориентация след проекция. Опитвам се да си спомня защо предварителната проекция не работи. Все пак не мога да измисля добра математическа причина. Вероятно аз трансформирах нормалното погрешно, когато го направих. - person starmole; 20.04.2015

Само да добавя: Много интуитивен начин за намиране на ръбове в проекция е изрязването на задната страна! Всеки ръб между отстранено и неотбрано лице трябва да бъде контур. Ако искате да скриете вътрешните ръбове, просто използвайте z-буфера. Отстраняването на задната повърхност е просто редът на върховете след проекцията и е много евтин за изчисляване.

person starmole    schedule 20.04.2015

  1. Намерете точката, чието x е min
  2. Намерете всички ръбове за тази точка
  3. започнете от тази точка, като си представите, че имате пръчка (зелена), тя се търкаля по посока на часовниковата стрелка, за да намерите първия ръб, който среща. Нека го наречем edge-A. edge-A
  4. Потърсете пресечки в този ръб-A. Намерете ръба-B, който причинява пресичането, нека го наречем inter-A, този inter-A е вашата втора контурна точка. edge-B
  5. Нека тогава да помислим, между двете точки на ръб-B, коя е следващата контурна точка. Свързване между A и началната точка След това можем да превъртим пръчката, за да намерим следващата очертана точка. (кандидат точка 1 е тази) въведете описание на изображението тук
  6. повторете горните стъпки, докато намерите точки, които вече съществуват във вашата колекция.

вижте демонстрация за намиране на контур за зайче Ето имплементация на описания по-горе алгоритъм.

person tt h    schedule 17.04.2021