使用角度进行弹性2D球碰撞 [英] elastic 2d ball collision using angles

查看:60
本文介绍了使用角度进行弹性2D球碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是的,这里有几个线程,但是使用角度的线程并不多,我真的想通过这种方式找出答案,我现在停留在为圆设置新的速度角.我一直在看: http://www.hoomanr.com/Demos/Elastic2/作为参考,但我现在被困住了.

Yes theres a few threads on this, but not many using angles and I'm really trying to figure it out this way, I'm now stuck on setting the new velocity angles for the circles. I have been looking at: http://www.hoomanr.com/Demos/Elastic2/ as a reference to it, but I'm stuck now.

有人可以阐明吗?

cx/cy/cx2/cy2 =球1和2的中心x/yvx/vy/vx2/vy2 =球1和2的x/y速度

cx/cy/cx2/cy2 = center x/y for balls 1 and 2. vx/vy/vx2/vy2 = velocities for x/y for balls 1 and 2

function checkCollision() {
var dx = cx2 - cx;  //distance between x
var dy = cy2 - cy;  // distance between y
var distance = Math.sqrt(dx * dx + dy * dy);

var ang = Math.atan2(cy - cy2, cx - cx2);

// was displaying these in a div to check
var d1 = Math.atan2(vx, vy); //ball 1 direction
var d2 = Math.atan2(vx2, vy2); //ball 2 direction

// this is where I am stuck, and i've worked out this is completely wrong now
// how do i set up the new velocities for 
var newvx = vx * Math.cos(d1 - ang);
var newvy = vy * Math.sin(d1 - ang);
var newvx2 = vx2 * Math.cos(d2 - ang); 
var newvy2 = vy2 * Math.sin(d2 - ang);


if (distance <= (radius1 + radius2)) {
    //Set new velocity angles here at collision..
}

这里有一个Codepen链接:

Heres a codepen link:

http://codepen.io/anon/pen/MwbMxX

推荐答案

一些说明:

•如评论中所述,仅使用弧度(不要再使用* 180/PI).
•atan2将y作为第一参数,将x作为第二参数.

• As mentioned in the comments, use only radians (no more *180/PI).
• atan2 takes y as first param, x as second param.

var d1 = Math.atan2(vy, vx); //ball 1 direction in angles
var d2 = Math.atan2(vy2, vx2); //ball 2 direction in angles

•要旋转向量,请先计算其范数,然后仅以新角度进行投影:

• to rotate a vector, compute first its norm, then only project it with the new angle :

var v1 = Math.sqrt(vx*vx+vy*vy);
var v2 = Math.sqrt(vx2*vx2+vy2*vy2);

var newvx = v1 * Math.cos(d1 - ang);
var newvy = v1 * Math.sin(d1 - ang);
var newvx2 = v2 * Math.cos(d2 - ang); 
var newvy2 = v2 * Math.sin(d2 - ang);

•您正在检测碰撞时,已经发生了碰撞,因此两个圆都重叠了,但是您解决了碰撞,这意味着圆在下一次迭代中可能仍然重叠,从而导致了新的碰撞,并且采取了新的方向,...未解决,等等.->>解决碰撞后,您需要确保两个圆圈不再碰撞.

• You are detecting the collision when it already happened, so both circles overlap, but you do NOT solve the collision, meaning the circles might still overlap on next iteration, leading to a new collision and a new direction taken, ... not solved, etc.. -->> You need to ensure both circles are not colliding any more after you solved the collision.

•最后一个问题,但不是一个小问题,是如何计算角度.抱歉,您再也没有时间了,但是对您和我们来说,建立一个(几个)方案来显示您如何计算角度将是有帮助的.

• Last issue, but not a small one, is how you compute the angle. No more time for you sorry, but it would be helpful both for you and us to build one (several) scheme showing how you compute the angles.

在这里更新了(但不起作用)codepen:

Updated (but not working) codepen here :

http://codepen.io/anon/pen/eNgmaY

祝你好运.

您在codepen.io/anon/pen/oXZvoe上的代码简化为:

Your code at codepen.io/anon/pen/oXZvoe simplify to this :

 var  angle = Math.atan2(dy, dx),
      spread = minDistance - distance,
      ax = spread * Math.cos(angle),
      ay = spread * Math.sin(angle);

    vx -= ax;
    vy -= ay;
    vx2 += ax;
    vy2 += ay;

您正在从速度中减去两个圆之间的间隙.由于以后您将速度添加到位置,所以将进行空间分离(=>不再发生碰撞).
我想了解vx- = ax的含义,我们必须记住牛顿:v = a * t,其中a是加速度,因此基本上执行vx = -ax意味着施加以两个中心之间的方向为方向的力,并且两个圆的碰撞(扩散)强度.该数量显然是相当随机的,因此,您看到的数值不稳定:有时效果很小,有时效果很大.

You are substracting the gap between both circles from the speed. Since later you add the speed to the position, that will do the spatial separation (=> no more collision).
I think to understand what vx-=ax means, we have to remember newton : v = a*t, where a is the acceleration, so basically doing vx=-ax means applying a force having the direction between both centers as direction, and the amount by which both circle collided (spread) as intensity. That amount is obviously quite random, hence the numerical instability that you see : sometimes a small effect, sometimes a big one.

在这里查找恒定的打孔版本:

look here for a constant punch version :

http://codepen.io/anon/pen/WvpjeK

var angle = Math.atan2(dy, dx),
  spread = minDistance - distance,
  ax = spread * Math.cos(angle),
  ay = spread * Math.sin(angle);

// solve collision (separation)
cx -= ax;
cy -= ay;

// give a punch to the speed
var punch = 2;

vx -= punch*Math.cos(angle);
vy -= punch*Math.sin(angle);
vx2 += punch*Math.cos(angle);
vy2 += punch*Math.sin(angle);

这篇关于使用角度进行弹性2D球碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆