如何可靠地找出两条贝塞尔曲线是否相交?通过"可靠"我的意思是测试将回答"是"只有当曲线相交时," no"只有当他们不相交时我不需要知道交叉点的参数是什么。我也想在实现中使用浮点数。
我在这里找到了几个使用曲线的答案。测试的边界框:这不是我之后的事情,因为这样的测试可能会报告交叉,即使曲线不相交。
到目前为止,我发现的最接近的是"边界楔形" Sederberg和Meyers,但它只有#34;区分最多一个和两个或多个交叉点,而我想知道是否存在最多零和一个或多个交叉点。
答案 0 :(得分:2)
我假设立方贝塞尔曲线。
使用浮点计算报告交叉点的最可靠方法可能是查找它们,并结合错误分析。
当涉及浮点计算时,主要问题是计算结果w.r.t不一致。拓扑结构。不幸的是,如果你需要在合理的时间内计算计算几何中的任何东西,这是不可避免的。
因此,不是强调交叉计算的正确算法,而是选择一个简单的算法并实施错误分析可能是解决方案。
我会尝试实现一个有效的细分算法,如bezier-clipping(或二次剪裁的变体 - Nicholas North's Geo-clip),并运行错误分析来计算严格的误差范围,这样我们就不会“错过”交叉点。
详细说明,这些基于细分的算法中的浮点(双精度)错误的主源是:
我使用了De Casteljau算法的运行误差范围 - explained here以及Geo-clip算法。它快速而强大。 (B.t.w.如果你想使多项式/贝塞尔算法更加稳健,这些论文一般来说是一个很好的读法)
假设您知道bezier clipping algorithm的基础知识,一般的想法是扩展混合贝塞尔曲线(在第一篇论文链接中)和胖线适当地使用每个剪辑的错误界限。
其他一些不相关的想法:
您可能会遇到一些案例:
答案 1 :(得分:0)
从头脑中的想法。 映射它们,使它们位于同一个域中,以便您可以减去它们。然后做一个根发现。根查找有很多很多数值方法。
答案 2 :(得分:0)
如果您需要查看两条曲线是否与视觉相交,比如游戏中的实时屏幕图形或其他内容,那么最简单的方法是到目前为止 ,就是简单地比较它们的像素。
获取两条曲线的bbox和像素查找表(LUT),检查是否存在bbox重叠:没有重叠?完成。没有交集。交叠?使用快速分拣机对LUT进行排序,然后运行比较。你找到一场比赛的那一刻,你就完成了。有重叠,你不关心在哪里。
如果你必须为很多曲线做这件事:使用一个为你做这个的库,不要浪费你自己实现它的时间,你不会那么高效(对于大型集合,如oct-树和扫描线检查变得更有效率)
但是,如果你需要知道是否存在绝对的,数学上精确的重叠,比如说正确的设计工作,那么你就不能偷工减料:实际上是真实的交叉点检测算法找到所有可能的交叉点。实时与此设置无关,您可以花费更多的周期来运行正确的检测算法。
答案 3 :(得分:0)
假设为三次贝塞尔曲线,交点是9次多项式的实根。在一个区间内存在这样的根(对于无限长的曲线,从负到正无穷大,或者对于典型的分段三次贝塞尔曲线,从0到1)可以使用Sturm sequence进行鲁棒检查。这只有在我们允许将其中一条曲线扩展到无穷大时才有效。该算法没有循环,只使用基本的算术运算(加,减和乘,而除法应该是可以避免的)。
为了获得最大的稳健性,您可以使用任意精度数学。由于步数是恒定的,因此所有临时结果中的最大可能位数都是有界的。这样,无论输入的病理程度如何(例如曲线几乎不接触),您的算法将始终返回正确的结果。
可能首先使用普通浮点数,并检测潜在的病态情况(当添加/减去先前的中间结果时,中间结果变为零)。
从Bezier控制点获取多项式项的公式确实值得一看,但幸运的是,你不必将它们解决, 他们是right here on Github。
2004年有一个帖子,comp.graphics.algorithms
keySet(V mappedValue)
上有更多详情。
如果您正在处理二次贝塞尔曲线,则多项式将仅为4度。