如何判断两个折线是否相交

4

我有一个问题,想找出两个折线是否相交。

主要目标是将最后的X和Y与另一个折线进行比较,并找出它是否与之碰撞,即相交。

由于移动X和Y导致数据存在间隙,所以大多数时候我无法在其他折线中找到X和Y。

我认为应该比较可视化树或其他内容,而不是数据本身,但我不知道如何实现。

<Canvas x:Name="LayoutRoot" Background="Black" Margin="2">
    <Polyline x:Name="player3line" Stroke="GreenYellow" StrokeThickness="4" Points="146,106 141,106 136,105 131,105 126,105 121,106 116,108 112,110 108,113 104,115 100,118 96,120 92,123 88,126 84,129 80,132 77,136 74,140 72,144 69,148 67,152 64,156 " />
    <Polyline x:Name="player4line" Stroke="Cyan" StrokeThickness="4" Points="85,113 89,116 93,119 97,121 102,123 107,124" />
</Canvas>

有没有一种简单的方法来检查这两个是否相交?

你能展示一下你正在使用的代码来从它们两个中获取x和y吗? - StephenT
目前我还没有任何代码,我只有添加X和Y坐标的代码。我的想法是每次想要将X和Y坐标添加到集合中时都检查是否相交。问题是我缺少一些X和Y坐标,比如这里:“85,113 89,116”,而且我在这个集合中找不到86,114的相交点。 - Rumplin
你的评论有点令人困惑... 你是怎么错过数字的?你已经输入了它们。它们必须被存储在某个地方。 - StephenT
我缺少数字,因为我画了一条特定长度的线。如果我为每个像素绘制一条线,移动速度将非常慢。 - Rumplin
2个回答

2

由于我所知道的Silverlight中没有神奇的硬件/软件碰撞测试,因此任何碰撞测试都必须在数据上进行。

对于两个折线段的情况,您需要检查每条线段与另一个线段(或简化版本���其中一个或两个)的每条线段是否相交。

您可以首先检查边界矩形碰撞(每个多边形的最小和最大x、y位置组成一个边界矩形),如果它们有重叠,那么您需要检查每个单独的线段是否相交。

据我所知,这种类型的碰撞测试没有捷径。只有一些技巧可以加速检查。

此链接提供了高级示例,但周围还有更多面向游戏的解决方案。


更多面向游戏的解决方案?是什么类型的?我目前处于开发初期,所以可以毫无问题地转换到其他解决方案。 - Rumplin
我以前曾经解决过这个问题,所以我会看看能否找到代码,但是我在谷歌上搜索“C#快速线段相交”时找到了这个链接,只用了2分钟:http://thirdpartyninjas.com/blog/2008/10/07/line-segment-intersection/ - iCollect.it Ltd
还在SO上找到了这个带有C#代码的内容:https://dev59.com/O3E95IYBdhLWcg3wkeuq - iCollect.it Ltd

1

我想应该搜索我的点周围的所有坐标,因为笔画粗细为4。

所以我想我需要检查从X-2到X+2和从Y-2到Y+2。

于是我这样做了,令人惊讶的是它现在可以工作,我承认它不完美,但它很简单,目前我没有看到任何使用此方法导致CPU飙升的情况:

  private bool CheckCollision(Point centerPoint)
    {
        bool functionReturnValue = false;

        //wall collision
        if (centerPoint.X - 1 < 0
            || centerPoint.X + 1 > (int)LayoutRoot.ActualWidth
            || centerPoint.Y - 1 < 0
            || centerPoint.Y + 1 > (int)LayoutRoot.ActualHeight)
        {
            functionReturnValue = true;
        }

        //player collision
        if (!functionReturnValue)
        {
            foreach (var player in playerList) //all players are in this list
            {
                for (int i = Convert.ToInt32(centerPoint.X - 2); i < centerPoint.X + 2; i++)
                {
                    for (int j = Convert.ToInt32(centerPoint.Y - 2); j < centerPoint.Y + 2; j++)
                    {
                        var point = new Point() { X = i, Y = j };
                        if (player.CoordinatePoints.Contains(point))
                        {
                            functionReturnValue = true;
                            goto END;
                        }
                    }
                }
            }
        }
        goto END;

     END:
        return functionReturnValue;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接