Answers:
29/09/2012-23:20
我在这里创建了一个git仓库:https : //github.com/ArthurWulfWhite/Bezier-Distance/
欢迎您从此处以zip格式下载源文件。它还包括一个可以使用FlashDevelop进行编译的演示。要使用该演示,请在Flash Develop中打开项目,然后单击“测试项目”。在运行演示时,单击LMB随机分配新的Bezier曲线和新的Circle。
祝好运!
zip链接很难看到-只需使用Ctrl + F并键入zip。该资源代表了数周的研究和编程,希望您喜欢。
如果计划将贝塞尔曲线递归地划分为多个段并检查与它们的碰撞,我建议制作一个100,100的阵列(网格)并将每个段放置在四个最近的正方形中,因此您只需要检查与4 / 10,000的碰撞细分每帧。
我确实认为,无论是作为程序员还是作为游戏创造者,您都将从box2d中受益,因为制作“简单的”物理引擎时存在许多隐藏的小障碍,使运动看起来有些坎and,流动性也比以前少。
旧答案:纯粹的方法。
通过检查圆心和曲线上最接近点之间的距离,您实际上可以查看圆是否与贝塞尔曲线发生碰撞。
距离方程(一般)
解释:
贝塞尔公式:
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
可以总结为(含一些代数)-为了可读性,我将省略。(x,y)(它们仍然是点,而不是一个数字)
q(t) = (start -2 * cont + end) t^2 + (-2 * start + 2 * control) + start
距点(x,y)的距离为:
sqrt ((q(t).x - point.x)^2 + (q(t).y - point.y)^2)
要在贝塞尔曲线上找到最接近球的点,您需要导出并找到导数等于零(根)的所有点。它是三次的多项式,因此您可以使用封闭式,但是由于计算机浮点表示的分数的精度可能不够,因此可能不可靠。最好使用牛顿或类似性质的东西。
您需要找到其根的导数是:
假设:a =开始b =控制c =结束d =圆心
棘手的部分是将这一点相乘,您必须使用点积。
如果您愿意,我有相应的代码,可以在这里以函数的形式共享它,该函数可以简单地返回一个布尔值(如果有无碰撞和碰撞角度)。在像这样的碰撞引擎的幼稚实现中可能会出现一些问题,例如,快速移动的球可能会卡在两条曲线之间。
我建议暂时不要使用它,只需将x轴和y轴的系数求和并相加即可。
使用您可以选择的任何可靠方法,例如Newton来找到根,检查从贝塞尔曲线的根点到0 <= t <= 1到圆心的距离,并检查贝塞尔曲线两端的距离(开始和结束)到圆心,以最接近的那个为准,它会告诉您是否发生碰撞。
如果半径小于最小距离,则发生碰撞。
该角度大约是圆心和贝塞尔曲线上最接近点之间的角度。
话虽这么说,如果您真的想用碰撞物理学来制作游戏,我建议您迭代贝塞尔曲线
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
将每个片段递归地划分到中间,直到足够小(可以说10像素或更小),然后从盒子中大致构建贝塞尔曲线,并将Box2d用于物理上,因为编写所有这些碰撞检测代码可能被证明是很棒的时间消耗并不能改善游戏玩法。过去,Box2d的使用已在无数项目中得到证明。
为此,我将:
将贝塞尔曲线折成几条线段并存储。
将所有这些线段放在整个曲线的轴对齐边界框中。
碰撞检测 :
1)检查球体是否在主边界框内。如果没有,则没有碰撞。
2)否则,检查上面计算出的任何单个线段是否与球体发生碰撞。请参阅Wikipedia中的线-球相交的文章。
编辑:如果需要高精度并希望获得良好的性能,则还可以为整个曲线创建一个主边界框,然后将曲线细分为两段(例如:[0.0 - 0.5]
和[0.5 - 1.0]
)。创建为他们每个人的bouding框,然后再细分每个段的两段(从而使[0 - 0.25]
,[0.25 - 0.5]
和[0.5 - 0.75]
,[0.75 - 1.0]
)。继续这样,直到达到足够的精度。最后,您将有一个binary tree
边界框,在根部有主曲线边界框,在叶子处有线段。在树中搜索将为您O(log n)
提供O(n)
(而不是(其中n
=曲线的线段数))
线与贝塞尔曲线之间的交点是通过对曲线进行细分而在数学上实现的。这意味着依赖于曲线的凸包属性,并以类似“分割等距”的方式将其分成具有不同控制多边形的较小弧。
本文涵盖了这一点:http : //students.cs.byu.edu/~tom/557/text/cic.pdf。
最棒的是,该算法可与任何直线配合使用,您只需对曲线应用刚性变换,即可将目标直线视为与Ox轴平行。
同样,将贝塞尔曲线弧细分为两个子弧时,可以检查每个这样的贝塞尔曲线弧的圆和多边形。圆应与圆弧的控制多边形相交,以便进行曲线到圆测试。