Ok,
我有一个射弹,其位置定义为:
a.x = initialX + initialDX * time;
a.y = initialY + initialDY * time + 0.5 * gravtiy * time^2;
我希望能够预测该射弹将与我的环境中的哪些障碍物发生碰撞。我打算检查距离A曲线上距离该点最近的点P.
我想在这一点上A曲线的切线将垂直于向量AP,并且曲线的切线在A只是速度V此时的射弹。
AP dot V = 0
ap.x = initialX + initialDX * time - p.x;
ap.y = initialY + initialDY * time + gravity * time^2 - p.y;
v.x = initialDX;
v.y = initialDY + gravity * time;
=>
AP dot V =
( 0.5 * gravity^2 ) * t^3 +
( 1.5 * gravity * initialDY ) * t^2 +
( initialDX^2 + initialDY^2 + gravity * ( initialY - p.y ) ) * t +
( initialDX * ( initialX - p.x ) + initialDY * ( initialY - p.y ) )
从这里我可以看出这是一个三次函数。我花了一些时间在网上研究,发现有一个通用方程似乎适用于某些值来寻找根。
这是我试图实施的过程。http://www.sosmath.com/algebra/factor/fac11/fac11.html http://www.sosmath.com/algebra/factor/fac11/fac11.html
a = 0.5 * gravity^2;
b = 1.5 * gravity * initialDY;
c = initialDX^2 + initialDY^2 + gravity * ( initialY - p.y );
d = initialDX * ( initialX - p.x ) + initialDY * ( initialY - p.y );
A = ( c - ( b * b ) / ( 3 * a ) ) / a;
B = -( d + ( 2 * b * b * b ) / ( 27 * a * a ) - ( b * c ) / ( 3 * a ) ) / a;
workingC = -Math.pow( A, 3 ) / 27;
u = ( -B + Math.sqrt( B * B - 4 * workingC ) ) / 2; // Quadratic formula
s = Math.pow( u + B, 1 / 3 );
t = Math.pow( u, 1 / 3 );
y = s - t;
x = y - b / ( 3 * a );
当我将 x 插回到曲线的原始方程中时,这应该给我A。这似乎对于某些值来说效果很好,但是当 p.y 高于某个值时,我没有正数可以在二次方程中取平方根。
我对数学没有足够的了解,无法理解为什么会发生这种情况,或者我可以采取什么措施来解决这个问题。
对此的任何帮助将不胜感激。
UPDATE:
我已经调整了我的算法来处理复杂的根,但是我仍然遇到麻烦。
如果判别式为负,我现在要做的就是:
a = 0.5 * gravity^2;
b = 1.5 * gravity * initialDY;
c = initialDX^2 + initialDY^2 + gravity * ( initialY - p.y );
d = initialDX * ( initialX - p.x ) + initialDY * ( initialY - p.y );
A = ( c - ( b * b ) / ( 3 * a ) ) / a;
B = -( d + ( 2 * b * b * b ) / ( 27 * a * a ) - ( b * c ) / ( 3 * a ) ) / a;
workingC = -Math.pow( A, 3 ) / 27;
discriminant = B * B - 4 * workingC;
then if discriminant < 0;
uc = new ComplexNumber( -B / 2, Math.sqrt( -discriminant ) / 2 );
tc = uc.cubeRoot( );
uc.a += B;
sc = uc.cubeRoot( );
yc = sc - tc;
yc.a -= b / ( 3 * a );
x = -d / ( yc.a * yc.a + yc.b * yc.b );
由于某种原因,这仍然没有给我预期的结果。这里有什么明显错误的地方吗?