圆与圆的碰撞问题

发布于 2024-08-13 16:04:47 字数 2308 浏览 2 评论 0原文

我在圆-圆碰撞检测方面遇到问题。我使用了以下算法,

func collision(id,other.id)
{

 var vaP1,vaP2,dis,va1,vb1,va2,vb2,vp1,vp2,dx,dy,dt;


 if (id!=other.id)

    {
        dx=other.x-x;
        dy=other.y-y;
        dis=sqrt(sqr(dx)+sqr(dy));

        if dis<=radius+other.radius
        {
            //normalize
            dx/=dis;
            dy/=dis;

            //calculate the component of velocity in the direction
            vp1=hspeed*dx+vspeed*dy;
            vp2=other.hspeed*dx+other.vspeed*dy;

            if (vp1-vp2)!=0
            {
                dt=(radius+other.radius-dis)/(vp1-vp2);

                //move the balls back so they just touch
                x-=hspeed*dt;
                y-=vspeed*dt;
                other.x-=other.hspeed*dt;
                other.y-=other.vspeed*dt;

                //projection of the velocities in these axes
                va1=(hspeed*dx+vspeed*dy); 
                vb1=(vspeed*dx-hspeed*dy);
                va2=(other.hspeed*dx+other.vspeed*dy); 
                vb2=(other.vspeed*dx-other.hspeed*dy);

                //new velocities in these axes. take into account the mass of each ball.
                vaP1=(va1+bounce*(va2-va1))/(1+mass/other.mass);
                vaP2=(va2+other.bounce*(va1-va2))/(1+other.mass/mass);

                hspeed=vaP1*dx-vb1*dy; 
                vspeed=vaP1*dy+vb1*dx;
                other.hspeed=vaP2*dx-vb2*dy;  
                other.vspeed=vaP2*dy+vb2*dx;

                //we moved the balls back in time, so we need to move them forward
                x+=hspeed*dt;
                y+=vspeed*dt;
                other.x+=other.hspeed*dt;
                other.y+=other.vspeed*dt;
            }
        }
    }

x=ball 1 x-position

y=ball 1 y-position

other.x= ball 2 x position

other.y=ball 2 y position

当我有 40 x 40 像素的球图像且球中心为 (20,20) 意味着图像仅包含球时,该算法效果很好。但是问题出现了当图像尺寸为 80 x 80 且球中心位置为 (60,60) 时,表示球位于半径为 20 的右下角。 在这种情况下,会发生多次碰撞,意味着无法分离球的部分

x+=hspeed*dt;

y+=vspeed*dt;

other.x+=other.hspeed*dt;

other.y+=other.vspeed*dt;

/速度不会根据碰撞而改变。 我已经改变了 x 的值,即图像 40,40 的中心到 60,60 球的中心添加 20。但结果是相同的。任何人都可以告诉我问题是什么。我认为算法是正确的,因为它有效在所有其他情况下都很好,很多人都使用这个算法。问题是将位置从图像中心更改为球中心。我应该对此做什么校正???或任何想法。如果有人想帮助请给我电子邮件地址,以便我可以发送我的完整项目。

I have a problem with circle-circle collision detection.I used the following algorithm

func collision(id,other.id)
{

 var vaP1,vaP2,dis,va1,vb1,va2,vb2,vp1,vp2,dx,dy,dt;


 if (id!=other.id)

    {
        dx=other.x-x;
        dy=other.y-y;
        dis=sqrt(sqr(dx)+sqr(dy));

        if dis<=radius+other.radius
        {
            //normalize
            dx/=dis;
            dy/=dis;

            //calculate the component of velocity in the direction
            vp1=hspeed*dx+vspeed*dy;
            vp2=other.hspeed*dx+other.vspeed*dy;

            if (vp1-vp2)!=0
            {
                dt=(radius+other.radius-dis)/(vp1-vp2);

                //move the balls back so they just touch
                x-=hspeed*dt;
                y-=vspeed*dt;
                other.x-=other.hspeed*dt;
                other.y-=other.vspeed*dt;

                //projection of the velocities in these axes
                va1=(hspeed*dx+vspeed*dy); 
                vb1=(vspeed*dx-hspeed*dy);
                va2=(other.hspeed*dx+other.vspeed*dy); 
                vb2=(other.vspeed*dx-other.hspeed*dy);

                //new velocities in these axes. take into account the mass of each ball.
                vaP1=(va1+bounce*(va2-va1))/(1+mass/other.mass);
                vaP2=(va2+other.bounce*(va1-va2))/(1+other.mass/mass);

                hspeed=vaP1*dx-vb1*dy; 
                vspeed=vaP1*dy+vb1*dx;
                other.hspeed=vaP2*dx-vb2*dy;  
                other.vspeed=vaP2*dy+vb2*dx;

                //we moved the balls back in time, so we need to move them forward
                x+=hspeed*dt;
                y+=vspeed*dt;
                other.x+=other.hspeed*dt;
                other.y+=other.vspeed*dt;
            }
        }
    }

x=ball 1 x-position

y=ball 1 y-position

other.x= ball 2 x position

other.y=ball 2 y position

this algorithm works well when i have a ball image of 40 x 40 pixel and ball center is (20,20) means image consists only ball.But the problem arises when image size is 80 x 80.and ball center position is (60,60),means ball is lower right corner with radius 20.
in this case there are multiple collision occur,means the portion

x+=hspeed*dt;

y+=vspeed*dt;

other.x+=other.hspeed*dt;

other.y+=other.vspeed*dt;

unable to seperate the ball /velocity does not change according to collision.
I have changed the value of x which is the center of image 40,40 to 60,60 center of ball adding 20.but the result is same .Can any one tell me what is the problem.I think algorithm is correct because it works nicely in all other case and lots of people used this algorithm.problem is changing position from image center to ball center.what correction should i do for this??? or any idea.if someone want to help plz give me e-mail address so that i can send my full project.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

飘落散花 2024-08-20 16:04:47

我没有足够的精神力量来消化你的整个问题,但这是我关于如何解决你的问题的 2 美分

1)检测与另一个圆碰撞的最简单方法是检查它们的距离是否小于组合的半径界。 (我的数学可能是错误的,所以如果我错了请纠正我)

Circle c1,c2;
float distance = DISTANCE(c1.center,c2.center);
if(distance < c1.radius + c2.radius)
{
  // collision .. BOOOOOOM
}

2)尝试使用准确的数据类型。尽量不要在不检查溢出、下溢和小数点的情况下将浮点数转换为整数。更好的是,只使用 float 。

3) 写日志并跟踪您的值。看看是否有任何明显的数学错误。

4)将代码分解为最简单的部分。尝试删除所有速度计算以获得最简单的运动来帮助您进行调试。

I didnt have the mental power to digest your entire question, but here is my 2 cents on how to solve your problem

1) The simplest way to detect a circle collision with another is to check if their distance is less than the radius of the combined circles. (i might be wrong with the math, so correct me if i am wrong)

Circle c1,c2;
float distance = DISTANCE(c1.center,c2.center);
if(distance < c1.radius + c2.radius)
{
  // collision .. BOOOOOOM
}

2) Try to use accurate data types. Try not to convert floats to integers without checking overflow, underflow and decimal points. Better still, just use floats .

3) Write a log and trace through your values. See if there are any obvious maths errors .

4) Break down your code to its simplest portion. Try to remove all that velocity computation to get the simplest movements to help you debug.

孤星 2024-08-20 16:04:47

我不会给你你正在寻找的答案,我不确定其他人会给你答案。为获得答案而必须破译的代码量可能不足以保证获得奖励。我的建议是失去算法中的耦合。上面的函数做了太多的工作。

理想情况下,您的碰撞检测将仅集中于碰撞而不是球的前进。类似于下面所示的功能,如果您仍然遇到问题,其他开发人员可以更轻松地为您提供帮助。

function(firstCircleCenterX, firstCircleCenterY, secondCircleCenterX, secondCircleCenterY, firstCircleRadius, secondCircleRadius)
{
    ...this code should concentrate on logic to determine collision
    ...use pythagoran theory to find distance between the two centers
    ...if the distance between the two centers is less than ((2*firstCircleRadius)+(2*secondCircleRadius) then you have a collision

    ...return true or false depending on collision
}

I will not give you the answer that you are looking for and I am not sure someone else will. The amount of code that must be decyphered to get you the answer may not warrant the reward. What I would recommend is to losen the coupling in your algorithm. The function above is doing way too much work.

Ideally you would have a collision detection that concentrated only on the collision and not on advancing the balls. Something like function shown below and that would allow other developers to help you more easily if you still had a problem.

function(firstCircleCenterX, firstCircleCenterY, secondCircleCenterX, secondCircleCenterY, firstCircleRadius, secondCircleRadius)
{
    ...this code should concentrate on logic to determine collision
    ...use pythagoran theory to find distance between the two centers
    ...if the distance between the two centers is less than ((2*firstCircleRadius)+(2*secondCircleRadius) then you have a collision

    ...return true or false depending on collision
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文