如果在2D多边形内部有一个“球”,由4个线段组成,作为边界墙,你如何计算与不规则倾斜墙碰撞后球的角度?
如果墙壁是水平的,垂直的或者是45度角,我知道如何使球反弹。我也有我的代码设置来检测与墙壁的碰撞。
我已经阅读了关于点积和法线的内容,但我无法弄清楚如何在Java / Android中实现它们。我完全感到难过,觉得我现在已经10次在Google中查找了10页。我已经烧坏了试图解决这个问题,我希望有人可以提供帮助。
答案 0 :(得分:8)
提前道歉:我不知道正确的Android类型。我假设你有一个属性为'x'和'y'的矢量类型。
如果墙是水平的并且当前的速度是'矢量'那么它就像下面那样容易:
vector.y = -vector.y;
你会单独留下x组件。所以你需要做一些类似的事情,但更通用。
您可以通过替换线法线(垂直于线的矢量)的概念来对y轴进行硬编码(垂直于水平线)。
由于法线与线正交,因此可以通过将线旋转90度来找到。在2d中,通过将矢量(a,b)转换为(-b,a),可以将矢量(a,b)旋转90度。因此,如果你有一条从(x1,y1)到(x2,y2)的线,你可以得到正常的:
vectorAlongLine.x = x2 - x1;
vectorAlongLine.y = y2 - y1;
normal.x = -vectorAlongLine.y;
normal.y = vectorAlongLine.x;
您实际上并不关心原始行的长度(并且当您不希望它时它会影响计算),因此您希望使法线长度为1,而不管其当前长度如何。您可以通过将其除以当前长度来实现。所以,例如。
lengthOfNormal = Math.sqrt(normal.x*normal.x + normal.y*normal.y);
normal.x /= lengthOfNormal;
normal.y /= lengthOfNormal;
使用毕达哥拉斯定理得到长度。
对于水平线,在y轴上的翻转与(i)计算向量的范围沿y轴延伸的内容相同; (ii)减去该数量两次 - 一次使速度在该方向上为0,再次使其成为原始的负版本。也就是说,它与:
相同distanceAlongNormal = vector.y;
vector.y -= 2.0 * distanceAlongNormal;
在一般情况下使用的点积是工作向量沿法线延伸的距离。因此它与采用vector.y对水平线的作用相同。这是你可能需要一点点信仰的地方。它是点积的属性,您可以通过检查直角三角形来说服自己。但是现在,如果你有一条水平线,你最终会得到正常值(0,1)。由于点积为:
vector.x * normal.x + vector.y * normal.y
你要计算:
distanceAlongNormal = vector.x * 0.0 + vector.y * 1.0;
这与使用y组件显然是一样的。
计算出法线距离后,你实际上想要减去正常时间的两倍。这里唯一的额外步骤是乘以法线得到2d数量减去。那是因为你想要按正常顺序减去。因此,基于先前计算的正常代码的完整代码是:
distanceAlongNormal = vector.x * normal.x + vector.y * normal.y;
vector.x -= 2.0 * distanceAlongNormal * normal.x;
vector.y -= 2.0 * distanceAlongNormal * normal.y;
如果你没有使长度为1的正常,那么你需要除以这里的长度,因为点积会将distanceAlongNormal值缩放该量。
答案 1 :(得分:0)
这对你来说可能会派上用场 http://www.tonypa.pri.ee/vectors/tut07.html