现在你已经知道如何来移动物体了,现实世界中,移动的对象迟早是要碰到什么东东的。举个例子,如果移动的对象就是你本人,并且你很幸运的话,你碰到的东西很软,比如床,但是有时候你可能碰到坚硬的东西,砖头墙,水泥板,关闭的门,以及这个世界上的其他的一些等待你或者其他运动的物体去碰撞的坚硬物体。所以,疼痛的一个好处就是让人们知道什么东西可以去碰撞。
我们知道对象的移动向量,我们也知道墙壁所构成的向量。我们要求得 是否,何时,何地,物体会和墙壁碰撞。换句话说就是:“2个向量在哪里相交?”
首先,让我们看看什么时候2个向量不想交。向量平行的时候不相交。并且平行向量的单位向量是相等的(方向可以不相同,它们可以使反向的):
(v1.dx==v2.dx and v1.dy==v2.dy) or (v1.dx==-v2.dx and v1.dy==-v2.dy)
如果它们不平行,那么相交时迟早的事情。绿线是移动向量,红线是墙壁,蓝线在它们的起点之间:

交点的坐标可以这样计算:
v3={vx:v2.p0.x-v1.p0.x, vy:v2.p0.y-v1.p0.y};
var t=perP(v3, v2)/perP(v1, v2);
ip={};
ip.x=v1.p0.x+v1.vx*t;
ip.y=v1.p0.y+v1.vy*t;
function perP(va, vb){
pp = va.vx*vb.vy - va.vy*vb.vx;
return pp;
}
首先,我们计算出在它们起点之间的向量v3。上面的函数是用来计算2个向量的垂直点乘(perp dot product)【as4game注:垂直点乘这个概念,在中文的数学教科书我是没发现过的。参考网址】。
垂直点乘和点乘非常相似,不同的是用v1的法线取代v1。点乘是:
dp = v1.vx*v2.vx + v1.vy*v2.vy;
v1的法线是:
v.rx = -v.vy; v.ry = v.vx;
然后我们用v1的法线代替v1:
pp = -v1.vy*v2.vx + v1.vx*v2.vy;
这就是垂直点乘了。
当两个垂直点乘的比例正好为1,那么交点就正好在移动向量的终点上。当为0-1之间的值时,那么交点就在v1上,当为负数交点就在向量的起点之前,当为大于1的数,交点就在向量的终点之后。
当然如果你想找到在另外一个向量上的交点,你也需要为v2计算t值:
v3={vx:v1.p0.x-v2.p0.x, vy:v1.p0.y-v2.p0.y};
var t=perP(v3, v1)/perP(v2, v1);
在下面的例子中,你可以尝试拖动那些点,然后观察向量的交点:
如果你对求交点的实际算法感兴趣,可以在这里查看。
你可以下载fla源文件。

Post a Comment