首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >合并接触多边形会产生错误的结果

合并接触多边形会产生错误的结果
EN

Stack Overflow用户
提问于 2015-11-30 22:05:35
回答 3查看 564关注 0票数 7

我正在尝试写一段代码,给出一个多边形列表(定义为IntPoints列表),检查它们中是否有任何一个接触,如果是,将它们合并到一个多边形中。为了做到这一点,我已经尝试了以下两种方法:

代码语言:javascript
复制
List<List<IntPoint>> output=new List<List<IntPoint>>();
output = Clipper.SimplifyPolygons(input,PolyFillType.pftPositive);

代码语言:javascript
复制
Clipper c = new Clipper();
c.AddPaths(input, PolyType.ptClip, true);
c.Execute(ClipType.ctUnion, output);

现在,这两种方法都可以很容易地将多边形合并在一起,但是它们有点夸张,因为任何多边形的开放空间都被忽略了,开放的区域只是简单地组合成一个多边形,这意味着类似这样的事情:

时有发生。这显然是错误的,因为这两个多边形没有互相接触。这两种方法都会产生相同的结果。结果将与输入相同。你知道怎么解决这个问题吗?解决方案不一定要使用裁剪器库(我并不依赖它),但我确实需要一些使用由点列表定义的多边形的东西,Intpoint是一个List>,其中Intpoint只是一个包含x和y的结构。

编辑我注意到,当其他面的内部没有面时,也会出现此问题,因此解决方案始终是“填充”的编辑编辑:以下也是输入可能是什么样子的示例

代码语言:javascript
复制
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

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

EN

回答 3

Stack Overflow用户

发布于 2015-12-08 02:17:53

在执行之前,需要在Clipper中添加一个PolyType.ptSubject(代码中缺少)和一个PolyType.ptClip。此外,您还需要选择将产生您想要的结果的ClipType,如下所示:

代码语言:javascript
复制
    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

票数 3
EN

Stack Overflow用户

发布于 2015-12-14 11:10:40

看起来这个库需要一些PolyTree版本的Execute方法的组合,以及一些更复杂的在Clipper对象中构建多边形的组合,以考虑输入是否包含洞。

它看起来不像是带有洞的绿色多边形被表示为一个点数组,它应该是一个带有外部多边形和内部孔多边形的PolyTree。

票数 1
EN

Stack Overflow用户

发布于 2015-12-09 04:47:55

您可以研究的另一件事是SQL Server2008中在处理几何形状时引入的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

票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34000482

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档