实施碰撞检测 [英] Implementing Collision Detection

查看:102
本文介绍了实施碰撞检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个程序,该程序将模拟从50米高的建筑物上抛出的球. 我添加了碰撞检测功能,方法是当球撞击地面时反转y方向上的速度(y <0),保持水平速度不变,并将两个速度乘以某个最小值,以便最终使球达到休息.

I wrote a program that will simulate a ball being thrown off a 50 meter building. I added in collision detection by reversing the velocity in the y direction when the ball hits the ground (y < 0), keeping the horizontal velocity the same, and multiplying both velocities by some min value, so that the ball will ultimately come to a rest.

 #include<stdio.h>
 #include<math.h>
 #include <stdlib.h>

 int main() {

     FILE *fp; 
     FILE *fr;

     float ax = 0, ay = 0, x = 0, y = 0, vx = 0, vy = 0;
     float time = 0, deltaTime = .001; 

     float min = -.00000000001; 
     int numBounces = 0;

     fr = fopen("input_data.txt", "rt"); 

     fp = fopen( "output_data.txt", "w" ); 

     if(fr == NULL){ printf("File not found");} 

     if(fp == NULL){ printf("File not found");} 

     fscanf(fr, "ax: %f ay: %f x: %f y: %f vx: %f vy: %f\n", &ax, &ay, &x, &y, &vx, &vy); 

     while (vx > min && vy > min) {

          time = time + deltaTime;
          vx = vx + ax*deltaTime;
          vy = vy + ay*deltaTime;
          x = x + vx*deltaTime + (.5*ax*deltaTime*deltaTime);
          y = y + vy*deltaTime + (.5*ay*deltaTime*deltaTime);  

          fprintf(fp, "%f\t%f\t%f\t%f\t%f\t%f\t%f\t\n", ax, ay, x, y, vx, vy, time);

     //Collision occurs; implement collision response
          if(y < 0) {
               vx = vx + ax*deltaTime*(.00001);
               vy = -(vy + ay*deltaTime*(.00001));
               numBounces++;

               fprintf(fp, "%f\t%f\t%f\t%f\t%f\t%f\t%f\t\n", ax, ay, x, y, vx, vy, time);
      }
 }

fclose(fp); 
fclose(fr); 

system ("PAUSE"); 
return 0;

 }

我没有获得生成正确数据图所需的正确值. 可能是因为我的while循环条件需要更改,或者我没有正确实现碰撞响应.

I am not getting the correct values needed to produce a correct graph of the data. It could be because my conditions in the while loop need to be changed, or that I did not implement collision response correctly.

还有一些示例数据:

ax:0 ay:-9.8 x:0 y:50 vx:8.66 vy:5

ax: 0 ay: -9.8 x: 0 y: 50 vx: 8.66 vy: 5

推荐答案

对于不输出任何内容,您可以在每个循环结束时尝试fflush(fp).据我在您的代码中看到的那样,只要它碰到地面,您的对象就会获得更高的速度,您必须将vy = -(vy + ay*deltaTime*(.00001))更改为vy = -(vy - ay*deltaTime*(.00001))才能对其进行更正.如果您只要计算y < 0的确切碰撞时间,然后在下一个循环的其余时间中向下移动对象,更改速度并向上移动对象,以产生更真实的碰撞,则还可以为碰撞创建更好的实现方式.

for not outputing anything you can try fflush(fp) at the end of each cycle. and as far as I can see in your code your object gets some more speed whenever it hits the ground you have to change vy = -(vy + ay*deltaTime*(.00001)) to vy = -(vy - ay*deltaTime*(.00001)) to correct it. you can also create a better implementation for collision if you calculate the exact time of collision whenever y < 0 and then move object down, change speeds, and move object up for the rest of cycle to have more realistic collision.

我们知道deltaY = 1/2 * ay * t ^ 2 + vy * t,因此我们可以使用以下公式计算t:

we know that deltaY = 1/2*ay*t^2 + vy*t so we can compute t using the folling formula :

assuming py is the current height of object(it's distance to ground)
=> -py = 0.5 * ay* t * t + vy * t
=> 0 = 0.5 * ay * t * t+ vy * t + py
=> t = (-vy +- sqrt(vy*vy - 2 * ay * py)) / (2 * ay)

并且由于t必须为正,并且知道ay是负数且py是正,所以我们可以假定当前答案是

and since t has to be positive and knowing that ay is negetive and py is positive, we can assume the currect answer is

=> tc = (sqrt(vy*vy - 2 * ay * py) - vy) / 2 / ay

现在我们有碰撞发生的时间tc.因此,我们必须反转位置和速度的最后变化,然后反转步长tc秒,然后反转vy和步长deltaTime - tc秒以完成该帧.因此,在if条件下,就像(我可能在做数学运算时会遇到一些问题,因此,如果有机会您未获得预期的结果,请仔细检查所有方程式):

now we have tc which is time of collision. so we have to reverse the last changes in position and speed, then just step time tc seconds and then reverse vy and step deltaTime - tc seconds to complete that frame. so inside the if condition would be like (I just may have some problems doing the math, so if by any chance you didn't get expected results jsut doublecheck all equations):

if (y < 0) {
    float tc = (sqrt(vy*vy - 2 *ay * y)) / 2 / ay;
    x = x - vx*deltaTime - (.5*ax*deltaTime*deltaTime);
    y = y - vy*deltaTime - (.5*ay*deltaTime*deltaTime);
    vx = vx - ax * deltaTime;
    vy = vy - ay * deltaTime;
    vx = vx + ax * tc;
    vy = vy + ay * tc;
    x = x + vx*tc + (.5*ax*tc*tc);
    y = y + vy*tc + (.5*ay*tc*tc);
    vy = -(vy - ay*deltaTime*(.00001));
    // you can also change above line and simply write 
    // vy = vy * -0.99;
    // that will also create friction as you want it to be there
    vx = vx + ax * (deltaTime - tc);
    vy = vy + ay * (deltaTime - tc);
    x = x + vx* (deltaTime - tc) + (.5*ax* (deltaTime - tc)* (deltaTime - tc));
    y = y + vy* (deltaTime - tc) + (.5*ay* (deltaTime - tc)* (deltaTime - tc));
    numBounces++;

    fprintf(fp, "%f\t%f\t%f\t%f\t%f\t%f\t%f\t\n", ax, ay, x, y, vx, vy, time);
}

这篇关于实施碰撞检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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