簡體   English   中英

合並觸摸多邊形給出錯誤的結果

[英]Merging touching polygons giving wrong result

我正在嘗試編寫一段代碼,給出一個多邊形列表(定義為IntPoints列表列表)檢查是否有任何觸摸,如果是,則將它們合並為一個多邊形。 為了做到這一點,我已經嘗試了以下兩種方法:

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

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

現在這兩個都很容易將多邊形合並在一起,但是它們有點過於粗糙,因為忽略了任何多邊形開放空間,並且開放區域簡單地組合成一個多邊形,這意味着像這樣: 作為一個沒有觸及的兩個多邊形的純粹恐怖被合並成一個沒有任何意義或生命的方形

發生。 現在這顯然是錯誤的,因為這兩個多邊形不相互接觸。 兩種方法都會出現相同的結果。 結果與輸入相同。 知道如何解決這個問題嗎? sollution不必使用限幅器庫(我沒有與它結合)但我確實需要一些使用由點列表定義的多邊形的輸入是List>其中Intpoint只是一個包含x的結構和y。

編輯我注意到當另一個多邊形內沒有多邊形時也會出現這個問題,所以解決方案總是“填充”編輯編輯:這里也是一個輸入可能是什么樣的例子

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

這個描述的輸入是一個正方形,其中有一個孔。

需要有PolyType.ptSubject (代碼中缺少)和PolyType.ptClip在執行之前添加到Clipper 您還需要選擇將產生所需結果的ClipType ,如下所示:

    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:

在此輸入圖像描述

聯盟:

在此輸入圖像描述

路口:

在此輸入圖像描述

差異: pol1 - pol2

在此輸入圖像描述

差異: pol2 - pol1

在此輸入圖像描述

看起來這個庫需要一些Execute方法的PolyTree版本的組合,以及Clipper對象中一些更復雜的多邊形構建,它考慮了輸入是否包含空洞。

它看起來不像帶有孔的綠色多邊形只是一個點數組,它應該是一個具有外多邊形和內孔多邊形的PolyTree。

您可以研究的另一件事是在處理幾何形狀時SQL Server 2008中引入的Spatial數據類型。

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

地理位置是相同的URL,但使用sqlgeography而不是sqlgeometry

您可以使用.STIntersects()== 1和.STIntersection(AnotherShape)來檢索交叉點。 還有其他方法可以提供與上面相同的結果。

這樣做的好處是,如果將其與數據庫結合使用,則可以利用空間索引使其更快。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM