Реализация обнаружения столкновений - PullRequest
0 голосов
/ 30 мая 2011

Я написал программу, которая будет имитировать мяч, сбрасываемый с 50-метрового здания. Я добавил в обнаружение столкновений, изменяя скорость в направлении y, когда мяч ударяется о землю (y <0), сохраняя горизонтальную скорость одинаковой, и умножая обе скорости на некоторое минимальное значение, так что в конечном итоге мяч достигнет остальное. </p>

 #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 нужно изменить, или из-за того, что я неправильно реализовал реакцию на столкновение.

Вот также некоторые примеры данных:

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

Picture of data plot

1 Ответ

1 голос
/ 30 мая 2011

, чтобы ничего не выводить, вы можете попробовать fflush(fp) в конце каждого цикла. и, насколько я вижу в вашем коде, ваш объект набирает некоторую скорость всякий раз, когда он достигает земли, вы должны изменить vy = -(vy + ay*deltaTime*(.00001)) на vy = -(vy - ay*deltaTime*(.00001)), чтобы исправить это. Вы также можете создать лучшую реализацию для столкновения, если вы вычисляете точное время столкновения всякий раз, когда y < 0, а затем перемещаете объект вниз, меняете скорость и перемещаете объект вверх до конца цикла, чтобы иметь более реалистичное столкновение.

мы знаем, что deltaY = 1/2 * ay * t ^ 2 + vy * t, поэтому мы можем вычислить t, используя формулу Фоллинга:

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 положительно, мы можем предположить, что правильный ответ -

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

теперь у нас есть tc - время столкновения. поэтому мы должны обратить вспять последние изменения в положении и скорости, затем просто шаг tc секунд, а затем обратный VY и шаг deltaTime - tc секунд, чтобы завершить этот кадр. поэтому внутри условия if было бы похоже (у меня просто могут быть некоторые проблемы с математикой, поэтому, если по какой-то случайности вы не получили ожидаемых результатов, просто перепроверьте все уравнения):

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...