2015-11-30 29 views
7

我想写一段代码给出一个多边形列表(定义为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); 

现在这两个在一起很容易合并的多边形但是他们有点overzelous任何多边形开放空间被忽略并且开放区域被简单地组合成单个多边形,意思是这样的: Sheer horror as a two polygons that are not touching are merged into a single square devoid of any meaning or life

发生。现在这显然是错误的,因为这两个多边形彼此不接触。两种方法都会出现相同的结果。结果将与输入相同。任何想法如何解决这个问题?溶剂不需要使用削波器库(我没有与它结合),但我确实需要一些使用由点列表定义的多边形的东西输入是一个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 
为例

这个描述的输入是一个有洞的正方形。

+0

有人甚至知道如何最好地描述这个问题?多边形中的多边形被合并?不允许飞地? – Thijser

+0

我想我可能已经找到了溶剂,但这将取决于答案https://stackoverflow.com/questions/34263601/algoritm-for-translating-list-of-wallsections-into-coherent-polygon – Thijser

回答

2

在执行之前,需要将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:

enter image description here

联盟:

enter image description here

路口:

enter image description here

差异:pol1 - pol2

enter image description here

差异:pol2 - pol1

enter image description here

+0

我认为问题有更多的不正确的输入格式呢? – Thijser

+0

我认为加入路径会自动添加它们作为主题,因为那里还有更多的2(在某些情况下只有1)多边形。 – Thijser

-3

另一件事你可以看看是空间数据类型在SQL Server 2008中,当介绍处理几何形状。

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

+0

很有用,但是这个软件不包含与数据库相关的任何东西,我不认为强制人们也安装数据库是一个好主意。 – Thijser

+0

我理解你的担忧,但与使用EntityFramework类似,可以使用.NET框架(DbGeometry/DbGeography)中包含的类并手动填充它们。这不需要数据库甚至任何类型的数据访问。它只是利用类的内置功能,这些类设计用于更轻松地处理空间数据类型。 –

+0

这个答案与OP要求的内容无关。 – Randy

1

它看起来像库需要的Execute方法的PolyTree版本,并在帆船对象的多边形的一些更复杂的堆积,考虑到输入是否包含孔的某种组合。

它看起来并不像带洞的绿色多边形只是一个点阵列,它应该是一个具有外部多边形和内部多边形的PolyTree。

+0

任何想法我会怎么做? – Thijser

+0

我也添加了一个输入格式的例子。 – Thijser