Bir içbükey ağın bir dışbükey ağ kümesine ayrılması


10

Bir içbükey ağı 2 nedenden dolayı bir dışbükey kafes kümesine ayrıştırabilmek istiyorum:

  1. Şeffaf işleme
  2. Fizik şekilleri

Girdi olarak bir üçgen kümesi (içbükey) alan ve bir dizi üçgen (dışbükey) çıkışı sağlayan bir algoritma var mı? Orijinal ağın parçaları arasındaki delikleri doldurmamasını istiyorum.

Zaten küçük bir fikre rastladım: tüm içbükey kenarları bulun ve kafesleri kenar halkaları boyunca bölün. Ben doğru yolda mıyım? Bunu nasıl uygulayabilirim?


"İçbükey / dışbükey" örgü nedir? Kafes üçgen ağ anlamına geliyorsa, sadece dışbükey olan bir üçgen kümesidir. Yoksa 3D nesnelerin hacminden mi bahsediyorsunuz? Belki çokyüzlülük?
Ivan Kuckir

@IvanKuckir Meshes veya polyhedra da içbükey / dışbükey olabilir ve tanım hemen hemen aynıdır. Örneğin, hiçbir düz çizgi çokyüzlünün iç kısmından bir kereden fazla kesişmeyecektir.
congusbongus

Yanıtlar:


11

Doğru yolda olduğunuzu söyleyebilirim, ancak optimal ve / veya verimli bir algoritma bulmak başka bir konudur: bu zor bir sorundur. Ancak, ilginiz akademik değilse, yeterince iyi bir çözüm yeterli olabilir.

İlk olarak, kendi çözümünüzü bulmak istemiyorsanız , CGAL zaten dışbükey polihedra ayrışması için bir algoritma içerir: http://doc.cgal.org/latest/Convex_decomposition_3/index.html

Şimdi yöntem için; 3D'deki birçok problem gibi, anlaşılması daha kolay olan 2D problemini düşünmek genellikle yararlıdır. 2B için görev, refleks köşelerini tanımlamak ve bu refleks tepe noktasından yeni bir kenar (ve muhtemelen yeni köşeler) oluşturarak ve refleks köşeleri (ve dolayısıyla tüm dışbükey çokgenler) bırakılıncaya kadar devam ederek çokgeni ikiye bölmektir. ).

refleks köşeleri

J. Mark Keil tarafından Poligon Ayrışması aşağıdaki algoritmayı içerir (optimize edilmemiş formda):

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

Temel olarak olası tüm bölümleri kapsamlı bir şekilde karşılaştırır ve üretilen en az köşegenleri olanı döndürür. Bu anlamda bir şekilde kaba kuvvet ve optimaldir.

"Daha hoş görünümlü" dekompozisyonlar istiyorsanız, yani uzun olanlardan ziyade daha kompakt şekiller üreten olanlar, Mark Bayazit tarafından üretilen , açgözlü (dolayısıyla daha hızlı) ve daha güzel görünen ancak birkaç eksikliğe sahip olanı da düşünebilirsiniz . Temel olarak refleks köşelerini, bunun tersi olan en iyi olana, tipik olarak başka bir refleks tepe noktasına bağlamaya çalışarak çalışır:

bayazit yeni köşe bayazit başka bir refleks köşesine bağlanır

Eksikliklerden biri, Steiner noktaları (mevcut bir kenarda mevcut olmayan noktalar) oluşturarak "daha iyi" ayrışmaları görmezden gelmesidir :

iki diken noktası kullanarak yonca ayrışması

3D'deki problem benzer olabilir; refleks köşeleri yerine "çentik kenarlarını" tanımlarsınız. Saf bir uygulama, çentik kenarlarını tanımlamak ve tüm polihedra dışbükey olana kadar tekrar tekrar polihedron üzerinde düzlemsel kesimler yapmak olacaktır. Daha fazla bilgi için Bernard Chazelle'nin "Çokyüzlü Dışbükey Bölmeleri: Bir Alt Sınır ve En Kötü Durum Optimal Algoritması" na göz atın .

çentikli çokyüzlünün

Bu yaklaşımın en kötü durumda üstel sayıda alt-polihedra üretebileceğini unutmayın. Bunun nedeni şu gibi dejenere olmanız olabilir:

birçok çentikli çokyüzlünün

Ancak önemsiz olmayan bir ağınız varsa (engebeli yüzeyi düşünün), yine de kötü sonuçlar alırsınız. Karmaşık ağlar için kullanmanız gerekiyorsa, önceden çok fazla basitleştirme yapmak isteyeceksiniz.


6

Bir yüzeyin S tam olarak dışbükey bir ayrışmasının hesaplanması NP zor bir sorundur ve genellikle çok sayıda küme üretir. Bu sınırlamaların üstesinden gelmek için, tam dışbükeylik kısıtlaması gevşetilebilir ve bunun yerine S'nin yaklaşık dışbükey ayrışması hesaplanır. Burada amaç, her bir kümenin kullanıcı tanımlı bir eşikten daha düşük bir içbükeyliğe sahip olmasını sağlarken, örgü üçgenlerinin minimum sayıda kümeye sahip bir bölümünü belirlemektir.

Tam dışbükey ayrışma ve yaklaşık dışbükey ayrışma

Aşağıdaki yaklaşık dışbükey ayrışma kitaplıklarına göz atın: https://code.google.com/p/v-hacd/ http://sourceforge.net/projects/hacd/


0

Burada size yardımcı olabilecek bazı kodlar . Java içinde yani c ++ dönüştürmek zorunda.

İşte size yardımcı olabilecek başka bir makale


1
Merhaba Maskeli Asi, sadece bağlantı cevapları burada önerilmez. URL hiç değişmezse veya kaynak kullanılamaz hale gelirse, bağlantıya bağlı olarak tamamen gelecekteki kullanıcılar için çözümlerden tamamen boş olan yanıtlar bırakabilir. Cevabınız hala kendi başına durabildiği ve okuyucu daha derine tıklamadan önce bile sorunu çözmek için bir rehber sağladığı sürece, kredi ve daha fazla okuma için bağlantılar sağlamak harika. Lütfen bu yanıtı, bağlantı oluşturduğunuz çözümün nasıl çalıştığına ilişkin en azından geniş bir taslağı içerecek şekilde düzenlemeyi düşünün.
DMGregory

@DMGregory Lütfen kendim yapamadığım yanıtı silin.

Cevap mutlaka silinmeye ihtiyaç duymaz. Sadece daha fazla bilgi içerecek şekilde düzenlemek onu harika bir cevap haline getirebilir.
DMGregory

@DMGregory ama bu yazıdaki başka bir cevabın kopyası olacak. Diğer cevabı düzenleyeceğim ve bilgilerimi oraya koyacağım.

Bu cevabı en başta paylaştığınızda eklemek için yeni bir şey olduğunu düşündüğünüzü düşünüyorum. Bağladığınız kodu, var olan bir cevabın karbon kopyası olmayan bir şekilde açıklayabileceğinizden şüphe etmiyorum. Yine de silmeyi tercih ederseniz, bağlantıyı sitenin masaüstü sürümünde kullanabilirsiniz.
DMGregory
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.