2011-05-29 48 views
0

我寫了一個程序,將模擬從50米大樓拋出的球。 我加入碰撞檢測時,通過顛倒y方向的速度,當球擊中地面時(y < 0),保持水平速度相同,並將兩個速度乘以某個最小值,這樣球就會最終到達休息。執行碰撞檢測

#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循環中的條件需要改變,或者我沒有正確實現碰撞響應。

這裏也是一些示例數據:

斧:0 AY:-9.8 X:0​​ Y:50 VX:8.66 VY:5

Picture of data plot

+0

多麼錯誤是你的代碼生成輸出數據? – Ali1S232 2011-05-29 21:33:30

+0

我的數據情節由什麼組成 – kachilous 2011-05-29 21:35:30

+0

你什麼意思什麼都沒有?你可以發表一個例子嗎? – flow 2011-05-30 20:32:11

回答

1

不outputing任何你可以試試fflush(fp)在每個週期結束時。並且就我看到的代碼而言,只要碰到地面,您的對象就會獲得更高的速度,您必須將vy = -(vy + ay*deltaTime*(.00001))更改爲vy = -(vy - ay*deltaTime*(.00001))才能更正它。如果計算每次碰撞時的確切碰撞時間y < 0,然後移動物體,改變速度並在剩餘的週期內移動物體以產生更逼真的碰撞,您還可以創建更好的碰撞實現。

我們知道移動deltaY = 1/2 * AY * T^2 + VY * T,所以我們可以使用folling公式計算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) 

並且由於噸必須爲正並且知道AY是negetive和py是積極的,我們可以假設正確的答案是

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

現在我們有tc這是碰撞時間。所以我們必須扭轉位置和速度的最後變化,然後僅步進時間tc秒,然後顛倒vy並且步驟​​秒來完成該幀。所以裏面的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); 
} 
+0

將vy改爲vy = - (vy - ay * deltaTime *(。00001))似乎並不奏效。如果我想要實現更逼真的碰撞,我怎麼能找到確切的碰撞時間? – kachilous 2011-05-29 21:42:47

+0

不寫入輸出是因爲你的程序從未真正離開while,所以調用fclose neve並且輸出不是真正寫入文件(它只是創建一個緩存,寫什麼它的性能問題只是使用fflush來修復),並且改變是爲了更正你的公式,我現在正在編輯我的答案,以添加所需的所有公式,以便更好地模擬。 – Ali1S232 2011-05-29 21:47:30

+0

不應該用公式來計算tc是deltaY =(1/2)ay * t^2 + vy * t代替deltaY = ay * t^2 + vy * t – kachilous 2011-05-29 22:27:28