2015-11-30 30 views
7

Çok sayıda tekboynuzun bir listesini (IntPoints listelerinin listesi olarak tanımlanmış) kontrol eden bir parça kod yazmayı deniyorum. . ŞimdiYanlış sonucu veren çokgenlere dokunma

List<List<IntPoint>> output=new List<List<IntPoint>>(); 
output = Clipper.SimplifyPolygons(input,PolyFillType.pftPositive); 

ve

Clipper c = new Clipper(); 
c.AddPaths(input, PolyType.ptClip, true); 
c.Execute(ClipType.ctUnion, output); 

herhangi poligon açık alanlar olarak biraz overzelous olan ancak bunlardan ikisi birlikte oldukça kolay çokgenler birleştirmek: Bunu yapmak için zaten şu iki yöntem denedi dikkate alınmaz ve açık alanlar sadece böyle bir şey, yani tek bir çokgene birleştirilir: Sheer horror as a two polygons that are not touching are merged into a single square devoid of any meaning or life

olur. Şimdi bu iki poligonun birbirine değmediği açıktır. Aynı sonuç her iki yöntemde de ortaya çıkar. Sonuç, girişle aynı olacaktır. Bunu düzeltmek için bir fikrin var mı? Sollution, clipper kütüphanesini kullanmak zorunda değil (ben onunla evlenmedim) ama bir nokta girişi listesi tarafından tanımlanan poligonları kullanan bir şeye ihtiyacım var. ve bir y.

Düzenleme diğer poligonun içinde hiçbir poligon olduğunda bu sorun oluşur fark, bu nedenle çözüm düzenleme düzenleme "dolu" her zaman geçerli: Burada da giriş

input[0][0] 
{ClipperLib.IntPoint} 
    X: -724 
    Y: -472 
input[0][1] 
{ClipperLib.IntPoint} 
    X: 428 
    Y: -472 
input[0][2] 
{ClipperLib.IntPoint} 
    X: 428 
    Y: -472 
    input[0][3] 
{ClipperLib.IntPoint} 
    X: 428 
    Y: 632 
input[0][4] 
{ClipperLib.IntPoint} 
    X: 428 
    Y: 632 
input[0][5] 
{ClipperLib.IntPoint} 
    X: -724 
    Y: 632 
input[0][6] 
{ClipperLib.IntPoint} 
    X: -724 
    Y: 632 
input[0][7] 
{ClipperLib.IntPoint} 
    X: -724 
    Y: -472 
input[0][8] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: -218 
input[0][9] 
{ClipperLib.IntPoint} 
    X: -107 
    Y: -218 
input[0][10] 
{ClipperLib.IntPoint} 
    X: -107 
    Y: -218 
input[0][11] 
{ClipperLib.IntPoint} 
    X: -107 
    Y: -209 
input[0][12] 
{ClipperLib.IntPoint} 
    X: -107 
    Y: -209 
input[0][13] 
{ClipperLib.IntPoint} 
    X: -320 
    Y: -172 
input[0][14] 
{ClipperLib.IntPoint} 
    X: -320 
    Y: -172 
input[0][15] 
{ClipperLib.IntPoint} 
    X: -320 
    Y: 132 
input[0][16] 
{ClipperLib.IntPoint} 
    X: -320 
    Y: 132 
input[0][17] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: 173 
input[0][18] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: 173 
input[0][19] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: -201 
input[0][20] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: -201 
input[0][21] 
{ClipperLib.IntPoint} 
    X: -88 
    Y: -218 
gibi ne olabileceğini bir örneğidir

Bu açıklamanın girdisi, içine kesilmiş bir delik içeren bir karedir.

+0

Bu sorunu en iyi nasıl tanımlayacağını bilen var mı? Çokgenlerde poligonlar birleştiriliyor mu? Enklavlara izin verilmiyor mu? – Thijser

+0

Bence bu işe yaramamış olabilir ama bu https://stackoverflow.com/questions/34263601/algoritm-for-translating-list-of-wallsections-into-coherent-polygon – Thijser

cevap

2

bir PolyType.ptSubject (kodunuzdan eksik) olması gerekir ve bir PolyType.ptClip yürütme önce senin Clipper eklendi.

private void Form1_Paint(object sender, PaintEventArgs e) 
    { 
     clip = new List<List<IntPoint>>(); 
     clip.Add(pol2); 

     input = new List<List<IntPoint>>(); 
     input.Add(pol1); 

     output = new List<List<IntPoint>>(); 

     Clipper c = new Clipper(); 
     c.AddPaths(input, PolyType.ptSubject, true); 
     c.AddPaths(clip, PolyType.ptClip, true); 
     c.Execute(clipType, output); 

     DrawPolygon(output, e.Graphics, Pens.Red); 
    } 

XOR:

enter image description here

Birliği:

enter image description here

Kavşak aşağıda gösterildiği gibi Ayrıca, istediğiniz sonucu üretecektir ClipType seçmek gerekir:

enter image description here

Fark: pol1 - pol2

enter image description here

Fark: pol2 - pol1

enter image description here

+0

cevabına bağlı olacaktır. Sorun, daha girişli bir giriş formatı ile daha fazla ilgisi var? – Thijser

+0

Bence, addpath'lar onları otomatik olarak konu olarak özneler olarak ekleyecektir, ayrıca 2'den fazla (ve bazı durumlarda sadece 1 tane) çokgen var. – Thijser

-3

Eğer Mekansal veri türleri SQL Server 2008 yılında tanıtıldı içine bakmak olabilir başka bir şey geometrik şekillerin ele alınması.

https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeometry.stintersection.aspx

Coğrafya aynı URL ama SqlGeography yerine SqlGeometry

Sen kavşakları almak için .STIntersects() == 1 ve .STIntersection (AnotherShape) kullanabilir ile. Yukarıdaki gibi aynı sonuçları vermek için başka yöntemler de vardır.

Bunun yararı, bunu veritabanınıza eklerseniz, mekansal dizinleri daha hızlı hale getirmek için kullanabilirsiniz. kütüphane giriş delikleri içerip içermediğini dikkate alır Yürütme yöntemin PolyTree sürümü ve Clipper nesnenin çokgen biraz daha karmaşık birikmesi, bazı kombinasyonu ihtiyacı olduğu gibi

https://msdn.microsoft.com/en-us/library/bb934196.aspx

+0

Yararlı ama bu yazılım veritabanları ile ilgili bir şey içermiyor ve insanların bir veritabanına da sahip olmalarını zorlamak için iyi bir fikir olduğunu sanmıyorum. – Thijser

+0

Endişenizi anlıyorum, ancak EntityFramework ile çalışmaya benzer şekilde .NET çerçevesine (DbGeometry/DbGeography) dahil edilen sınıfları kullanabilir ve bunları el ile doldurabilirsiniz. Bu bir veritabanı veya her türlü veri erişimi gerektirmez. Sadece mekânsal veri türleri ile çalışmayı daha kolay hale getirmek için tasarlanmış sınıfların işlevselliğinden yararlanıyor. –

+0

Bu cevabın OP'nin sorduğu şeyle ilgisi yoktur. – Randy

1

görünüyor.

Delik, yalnızca bir dizi nokta olarak temsil edilen yeşil çokgen gibi görünmüyor, dış bir çokgen ve bir iç delik poligonu olan bir PolyTree olmalıdır.

+0

Bunu nasıl anlatabilirim? – Thijser

+0

Ayrıca giriş formatının bir örneğini ekledim. – Thijser