javascript - Javascript:球体碰撞和产生的脉冲
问题描述
我是一个相当新的程序员,但我正在尝试在不使用任何库的情况下创建自己的物理引擎。这是一款星际迷你高尔夫游戏。
根据行星的密度和位置,我已经使重力工作正常,并且我的碰撞检测工作正常,但是当它们碰撞时该怎么办是我无法解决的。
行星不会移动,但使用 Javascript 来进行计算结果速度所需的三角函数是非常困难的。
这是我的物理代码,使用 requestAnimationFrame 执行:
var a = [0, 0];
// p is in the format [x, y, radius, density]
planets.forEach(function (p) {
var d = Math.sqrt((p[0] - ball.coor[0]) ** 2 + (p[1] - ball.coor[1]) ** 2);
var m = p[3] * 4 / 3 * Math.PI * p[2] ** 3;
var f = G * m / d ** 2;
var angle = Math.atan2(p[1] - ball.coor[1], p[0] - ball.coor[0]);
a[0] += f * Math.cos(angle);
a[1] += f * Math.sin(angle);
if (d < p[2] + ball.radius) {
var impulse = [0, 0];
// What to do here?
// This is the closest I got:
var velocitya = Math.atan(b.v[1] / b.v[0]);
var trianglea = Math.abs(velocitya - angle);
var currV = Math.sqrt(b.v[0] ** 2 + b.v[1] ** 2);
var newV = currV * bounciness;
var newa = (Math.PI / 2 - trianglea) * 2 + velocitya;
b.v[0] = newV * Math.cos(newa);
b.v[1] = newV * Math.sin(newa);
// Somehow I just can't get it right.
// It's the JavaScript, not the math concepts.
}
});
ball.v[0] += a[0];
ball.v[1] += a[1];
ball.coor[0] += ball.v[0];
ball.coor[1] += ball.v[1];
ball
只是高尔夫球的对象。
我尝试了各种方法,但我无法让碰撞正常工作。似乎使用方向和角度让我感到悲伤。我做了很多研究,但我发现没有任何东西似乎可以正确解决我的问题。
所以这是我的问题:如何使用 vanilla JavaScript 计算脉冲?
注意:行星不会移动,弹性应该是一个变量。
解决方案
好的,我认为这行得通。
鉴于:
- 行星位置为 {x,y}
- 球位置为 {x,y}
- 球速度为 {dx,dy}
我认为步骤如下:
- 计算 x 轴与行星和球的中心之间的线之间的角度。
- 将速度矢量顺时针旋转该角度,换句话说,将其旋转负角度。现在我们有了速度矢量,就像行星和球在 x 轴上对齐时一样。
- 现在,要从地球上“反弹”,我们只需要反转速度的 x 分量。
- 通过角度逆时针旋转新速度。
它似乎工作。为清楚起见,我们假设b
(ball)、p
(planet) 和v
(velocity) 是具有x
和y
成员的对象。
function impact(b, p, v) {
let a = b.x == p.x
? Math.PI / 2
: Math.atan((b.y - p.y) / (b.x - p.x));
v = rotate(v, -a);
v.x = -v.x;
return rotate(v, a);
}
function rotate(p, a) {
return {
x: p.x * Math.cos(a) - p.y * Math.sin(a),
y: p.y * Math.cos(a) + p.x * Math.sin(a)
);
}
您必须做一些工作才能使用数组等将其转换为您的样式。
如果你想让球慢一点,你也可以想办法做到这一点;最简单的方法是将向量的 x 和 y 分量缩小某个因子。
推荐阅读
- mysql - LoadError:加载“mysql2”Active Record 适配器时出错 [rails 5.2.3]
- java - 隐藏/显示带有凹槽的状态栏
- quantile - 如何阅读或解释以下零假设?
- sql - 什么是
字符串以及如何过滤它? - opengl-es - OpenGL ES 3.0 矩阵/数组步幅
- jenkins - Jenkins主从错误:主机密钥验证失败
- c# - 如何将文件 image.tif 加载到图片框中?
- swift - Swift 4 Firebase .childAdded 不检索最新记录
- c++ - 由于花费大量时间,代码未执行
- kubernetes - Cephfs:动态配置不起作用