我正在进行路径规划,车辆应该沿着通过杂乱环境的路径行驶。我的算法非常宽容,因此我只需要一个布尔答案来解决以下问题:这条线是否在多边形内(多边形是一个障碍物)。 当然,应避免任何多边形和线的交叉。 我在网上做了我的研究,但我只找到那些(以吨计)的东西: wrong cases,valid for points only,more points。
我的算法通过连接两个点来生成路径,然后在生成时检查这些点不在多边形内部。
逐点检查不是精确的,因为我不会冒任何碰撞的风险。多边形和直线的相交线是我的第一个猜测,但由于每条(无限)线与另一条线相交(平行线除外),我必须检查交点是否在所有其他边之外。这对我来说似乎很慢,问题是,有更好的方法还是这是一个“好”的解决方案? [或者我如何相互检查有限长度的线段?]
在好的评论之后,它归结为:我需要一种快速的方法来检查线段 - 段交叉点。 (我知道边界框,我会先做那个。)
如果重要的话,我正在使用C ++。
答案 0 :(得分:0)
我认为它是2D。
大纲(快速/肮脏的解决方案)。
对于凸多边形:
对于每个边缘:
2.1计算它外部的正常指向(在2d中将边缘矢量旋转90度,这是微不足道的normal = vector2(-edgeVector.y, edgeVector.x))
,但是你的边缘应该按顺序排列才能工作(顺时针或逆时针)
2.2。使用2d版本的平面方程,确定线段的起点/终点是否位于边缘的“外部”。如果dotProduct(point - edgeStart, edgeNormal) > 0
,则点在“外部”。
2.3。如果BOTH点在外面,则终止循环并报告没有冲突。
2.4。如果两个点都在平面下方,则移动到下一个平面/边缘。
2.5。否则,使用插值(endPos - startPos)* startDistance/(endDistance- startDistance)
计算截距点,其中开始/结束距离计算为distance = dotProduct(point - edgeStart, edgeNormal)
2.6。确定点是否位于边缘(0 <= dotProduct (intersectionPoint - edgeStart, edgeEnd - edgeStart) <= dotProduct(edgeEnd - edgeStart, edgeEnd - edgeStart)
)。如果它位于边缘,则发生碰撞。终止循环并报告冲突。
2.7。完成循环后,如果两个起点/终点都在所有边缘的“下方”平面上,则报告碰撞。
2.8。报告没有碰撞。
对于凹多边形。
(可选)您可以先计算凸包并检查碰撞。如果凸包不与线段碰撞,则不会发生碰撞。
选取多边形外部的任意点,并(使用2.3..2.4步骤进行边缘/边缘碰撞)计算它相交的多边形边数。如果该数字不能被2整除((edgeCount % 2) != 0
),则返回报告冲突(线段位于多边形内)。不要忽略这一步。
使用边缘/边缘碰撞(在2.2..2.3中概述)确定它是否与任何边相交。如果是,报告冲突。
报告没有碰撞。
要优化大/复杂多边形上的碰撞查询,请使用空间分区算法(如bsp树,octtrees)或sweep and prune方法。
这是边缘/多边形交叉的快速轮廓(可能偶尔会有拼写错误)。
可能存在更快的方法并可在网上获得。