Bitişik üçgenler oluşturmak için algoritma


14

Bir sahnede bir düğüm yerleştirmek için bir kez tıklayabileceğiniz bir sistemim var. 3 düğüm yerleştirdiğinizde, bir üçgen oluşturur. Gelecekteki düğümleri yerleştirdiğinizde, bu düğümü varolan en yakın 2 düğüme birleştirerek yeni bir üçgen oluşturur.

Bu çoğu zaman iyi çalışır, ancak çok akut açılara sahip üçgenlerin yakınında kullanıldığında kusurludur, çünkü en yakın 2 düğümden biri genellikle kullanılması gereken bir düğüm değildir.

Örneğin, aşağıdaki resme bakın. Macenta üçgen yerleştirilen ilk üçgendir. Daha sonra X işaretli konuma tıklarsam, elde ettiğim şey mavi yer paylaşımının olduğu yeni bir üçgendir. İstediğim yeşil bindirmenin olduğu yeni bir üçgen. (yani bu örnekte macentaya simetriktir. Açıklama: Yeşil ve macenta üçgenler üst üste binmez - yeşil olan mavi olanın altında en soldaki düğüme uzanır)

Gerçek ve istenen davranış örneği

Yeni üçgen oluştururken hangi 2 mevcut köşenin kullanılacağını nasıl belirleyebilirim, böylece üçgenler bu şekilde üst üste gelmez?

DÜZENLEME : En yakın kenarı aramak daha iyi sonuçlar verir , ancak mükemmel sonuçları vermez. Bu durumu düşünün:

resim açıklamasını buraya girin

'En yakın kenar' testi belirsizdir ve AB veya AC'yi döndürebilir (her ikisi için X'e en yakın nokta A'da olduğu için). İstenen sonuç, kenarlar üst üste binmeden ACX üçgenini oluşturmak için AC olacaktır. Bu sonucu nasıl sağlayabilirim? (Yüzer nokta hassasiyeti sorunları göz önüne alındığında, en yakın kenar testinin 2'yi tam olarak eşit olmayacağından endişe duyduğum için mümkünse bir kravat kırıcı olarak bireysel kenar çakışma testleri yapmak istemem.)


Yerleştirilen son 5 köşeye bakmak ve yeni yerleştirilen tepe noktasına en yakın iki köşeyi seçmek yeterli değil mi? Sizi üçgen şeritler için algoritmalara işaret ediyorum ( codercorner.com/Strips.htm ) ama bunlar genellikle sadece son iki veya son üçünü bir atlayarak kullanıyor.
Roy T.

1
Yeşil üçgen macenta ile örtüşüyor mu? Bunun amacı nedir? Kullanıcının üçgenlerin nerede ve nasıl oluşturulduğu üzerinde kontrole ihtiyacı var mıdır veya bir nokta bulutu üçgenleme kabul edilebilir mi?
bummzack

Bunu bir grafik bağlamına koymak için, esas olarak, kenarları üst üste binmeden düğümlerinizi bağlamak mı istiyorsunuz? (Eflatun / yeşil üçgenlerin bir kenarı paylaşacağı varsayılarak)
MichaelHouse

Roy T: hayır - sadece en yakın 2'yi seçmek yanlış, örneğin gösterdiği gibi. Net olmayan bir şey mi var? Bummzack - Yeşil olan kırmızı ile çakışmıyor. Amaç, bu üçgenlerin bir kafes veya grafiğini yapmaktır. Kullanıcının kontrole ihtiyacı var, evet. Byte56 - evet, hiçbir kenar geçmemelidir.
Kylotan

2
Kullanıcı tek tek üçgenleri görecek mi? Yoksa sürekli bir yüzey mi olacak?
bummzack

Yanıtlar:


11

Düğümlere olan minimum mesafeyi bulmak yerine, kenara olan minimum mesafeyi (düğümler tarafından tanımlanan çizgi segmenti) bulun .

Daha sonra, en yakın nokta bir tepe noktasıysa (bazı kayan nokta epsilon ** testi kullanmanız gerekir), yeni noktadan tepe noktasına kadar olan çizgi ile o tepe noktasına bağlı kenarların her biri arasındaki açıyı karşılaştırın. Minimum mutlak açıya sahip olanı seçin:

MinAngle(newPoint, vertex, edge1, edge2)
{
   newEdgeUnit = norm(newPoint - vertex); // don't actually need to normalize this
   edge1Unit = norm(edge1 - vertex);      // you probably have these from your dist to line tests
   edge2Unit = norm(edge2 - vertex);

   edge1Dot = dot(edge1Unit, newEdgeUnit);
   edge2Dot = dot(edge2Unit, newEdgeUnit);

   // you can simply compare dot products to find the minimum absolute angle
   if (edge1Dot > edge2Dot) return edge1;     // set up this way so you can generalize to an array
   return edge2;
}

** Epsilon testini bozabilecek dejenere üçgenler eklemekten kaçınmak için, her tepe noktasına, ekleme noktalarına izin verilmeyen bir bölge koymak isteyebilirsiniz (yukarıda kullanılan epsilonun bazı katlarına izin vermeme gibi bir şey).


3
+1 - bu, IMHO'nun diğerlerinden çok daha basit bir cevap ve doğru sonuçları sağlama olasılığı daha yüksektir. Segmente olan mesafenin akıllı bir şema ile hesaplanması da kolaydır.
Steven Stadnicki

Anlaşıldı, bu daha temiz bir yöntem. Muhtemelen daha çok düşünürsem
gelebilirdim

Ah, çok yakın! Ancak, Byte56'nın cevabı ve Jimmy'nin şemasında olduğu gibi, bazen 2 eşit kenar vardır ve bunlardan biri kısıtlamaları ihlal eder. Sorumu güncelledim.
Kylotan

@Kylotan Belki de bu durumda, hangisinin çakıştığını kontrol etmek ve diğer seçeneği kullanmak yeterlidir? Seçtiğiniz kenarı paylaşan üçgenleri arayın ve yeni üçgenin bu kenarın mevcut kenarıyla aynı tarafta olup olmadığını kontrol edin.
Kevin Reid

@Kylotan Üçgenlerinizin her zaman aynı sargıya sahip olduğundan emin misiniz? Evetse, yeni tepe noktanızdan normal bir işaret gösteren kenarı dışlayabilirsiniz (nokta ürünü kullanarak).
bummzack

6

İlk üçgen yerleştirildikten sonra, yeni bir tepe yerleştirirken her zaman iki yeni kenar üreteceksiniz. Yeni üçgenin üçüncü kenarı her zaman önceki üçgeni olan bir paylaşılan kenar olacaktır. Paylaşılan kenarı belirlemenin bir yolunu bulabilirseniz, hangi köşelere bağlanacağınızı bilirsiniz, ancak bu zor kısmıdır. Yeni tepe noktanızdan oluşturulan son üç kenarın (veya muhtemelen en yakın 3 kenarın) her birinin merkezine bir çizgi çizerek bunu yapabileceğinize inanıyorum.

resim açıklamasını buraya girin

Köşenizden kenarın ortasına doğru olan çizgi değil diğer iki kenar birini çapraz, kendi paylaşılan kenar var. Paylaşılan kenar size yeni tepe noktanızı hangi iki köşeye bağlayacağınızı söyleyecektir.

Jimmy, davayı yeni üçgenin nereye gideceğine dair belirsiz bir noktaya getirdi:

belirsiz üçgen

Bu size iki geçerli üçgen arasında seçim yapma fırsatı verecektir. Belki de kopma kırılması hangi merkez noktanın en yakın olduğudır.

Güncellemeniz düşünüldüğünde, daha karmaşık olsa da, çözümüm yalnızca iki geçerli üçgeniz olduğunda bir kravat ile sonuçlanacaktır. Bu yöntem kullanıldığında ikinci örnek resminiz istediğiniz sonucu verir.

resim açıklamasını buraya girin


Çizgilerden ikisinin kenarlarla kesişmediği bir durum olması mümkündür (X, bir tepe noktasına kenardan daha yakın olduğunda)
Jimmy

@Jimmy böyle bir durumun resmini çizebilir misiniz?
MichaelHouse


Ah evet, o zaman üçgeni nereye koyacağınız konusunda iki seçeneğiniz var! Her iki taraf da işe yarar. Belki de merkeze en kısa mesafeyle mola verebilirsiniz.
MichaelHouse

@Kylotan bu çözüm çalışmıyor mu? Jeff'e yaptığı açıklamada Jimmy'nin imajının iki vakası olduğunu ve birisinin kısıtlamaları ihlal ettiğini söylemiştin, ama bu doğru değil. Jimmy'nin imajına göre, iki durum benim yöntemimi kullanarak geçerli üçgenler üretecekti.
MichaelHouse

1

Eflatun üçgeni ABC'ye sahip olursanız, yeni bir X köşesi eklersiniz. D'de başlayan ve ABC üçgeninin kenarları arasında kesişmeyecek iki çizgi olacağı açıktır.

Bu iki çizgi AX & BX, BX & CX veya AX & CX olabilir. Daha sonra probleminizi "iki çizgi kesişiyor mu?" Daha sonra, bu satır çiftlerinden hangisinin, örneğin bu sorudaki yöntemlerden herhangi birini izleyerek ABC üçgen kenarlarından herhangi biriyle kesişmediğini kontrol edebilirsiniz . Böylece, yeni üçgenin iki yeni kenarına sahip olacaksınız.


Bu iyi görünüyor, ancak belirttiğiniz şekilde mevcut tek bir üçgen olduğunu varsayalım. Birçoğuna nasıl genelleme yapar?
Kylotan

Vay be ... X'iniz ve ABC üçgeniniz sabitse, sanırım sadece bir tane var, değil mi?
Dan

Sistem 2. düğümden sonraki her düğüm için yeni bir üçgen oluşturur.
Kylotan

Üzgünüm, sorunuzu yanlış anladım. Bunu bir çok üçgene nasıl genişletebileceğimi göreyim.
Dan

Sanırım X'e bağlandığında herhangi bir kenarı geçmeyen X'e en yakın iki köşeyi arayabilirdiniz?
bummzack

1

Belirsiz bölgelerden birinde (aşağıda 1, 2, 3) olup olmadığını anlamak oldukça kolaydır: üçgenin her kenarına 2B düzlem gibi davranın ve yeni noktanızın düzlemin hangi tarafında olduğunu test edin. Eğer ikisi içinde ama biri dışındaysanız, o zaman üçgenin kenarına karşılık gelir ve bu yeni üçgene iki köşeye katkıda bulunur.

Bir üçgenin Voronoi bölgeleri

Birinin içinde ve ikisinin dışındaysanız, üçgenin yeni noktanıza en yakın kısmının bir köşe olduğu belirsiz durumdasınız. Bu durumda, karşı kenarın orta noktasından (içinde bulunduğunuz) ve en yakın tepe noktasından (dışarıda olduğunuz iki düzlem tarafından paylaşılan) 2B düzlem oluşturabilirsiniz. Yeni noktanızın bu tarafının hangi tarafına bağlı olduğuna göre bir kenar seçebilirsiniz.

2B'deki bir düzlem testinin 3B ile aynı şekilde çalıştığına dikkat edin: bir vektörü düzlemdeki herhangi bir noktadan uçağın normaliyle noktaya noktalayın (2B'de bu çizgi diktir).

(Bu arada, bu görüntüdeki eflatun sınırlı bölgelere Voronoi bölgeleri denir; bunlar üçgenin belirli bir özelliğine (kenar veya tepe noktası) en yakın noktaları içeren alanlardır. Düzenleme: Buradaki terminolojim aslında değil oldukça doğru, bunlar tam olarak Voronoi bölgeleri değil.)


Bunun sahnede birden çok üçgene nasıl genelleştiğini hemen anlayamadım - özellikle en yakın özellik 1'den fazla üçgenin paylaşabileceği bir tepe noktasıysa.
Kylotan

@Kylotan Tüm üçgenler için algoritmayı çalıştırın ve en yakın genel özelliği seçin. Ne olursa olsun bir parça mantığa ihtiyacın var. Paylaşılan bir köşe olmanın en yakın özelliği ile sona, o zaman gerekir belki bunu seçebilirsiniz, sadece bir üçgen için kenar-bölge (# 1, # 2, # 3) olmak?
John Calsbeek
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.