2014-07-25 40 views
-2

無數次我使用歐拉積分爲小玩具遊戲實現了物理模擬:按下箭頭鍵,它設置加速度,然後整合加速度並添加到速度,然後整合速度並添加到獲得最終職位的位置。我到處看到這一點。遊戲物理模擬:基於能量加速

但是當我想到動能時,我意識到它不是「現實」的。如果給出像汽車這樣的東西,發動機會產生功率(kW),而不是力量/加速度。隨着恆定的加速度,虛擬發動機的功率隨着速度的增加而增加。在我的情況下,這是一艘飛船,但我想嘗試在一個方向上施加恆定的力量,而不是持續加速。

我的評估是否正確,跟蹤能量比加速度更真實?如果是這樣,它實際上跟蹤能量矢量而不是速度矢量更有意義嗎?但之後我必須轉換爲速度來整合。所以我已經完成了一維仿真和它的工作,當然我可以使用E = 0.5 * m * v * v並且求解v。但是當使用向量時,我不能採用「平方根」的能量(矢量)。我可以找到方向相同的矢量,但幅度是原始的平方根,但是這是物理上正確的嗎?

我以爲肯定有人必須這樣做,但我搜索並搜索了網頁,沒有看到它。所以,也許我離開了基地。基本上,我想要做的是採取傳統的「向上箭頭和太空飛船以恆定加速度加速」並將其改變爲「按箭頭和飛船上升以恆定速率獲得動能」,但在2D案例,而不是1D案件(我已經有1D案件)。

更新:根據Exceptyon的接受的答案JavaScript代碼:

function sq(x) { 
    return x * x; 
} 

//Square cosine, preserving sign 
function cos2(x) { 
    var ret = Math.cos(x); 
    if (ret >= 0) { 
     return sq(ret); 
    } else { 
     return -sq(ret); 
    } 
} 

//Square sine, preserving sign 
function sin2(x) { 
    var ret = Math.sin(x); 
    if (ret >= 0) { 
     return sq(ret); 
    } else { 
     return -sq(ret); 
    } 
} 

function Ship() { 
    this.x = 20; //m 
    this.y = 40; //m 
    this.dx = 0; //m/s 
    this.dy = 0; //m/s 
    this.ex = 0; //J 
    this.ey = 0; //J 
    this.pangle = Math.PI/2; //pointing angle 

    this.mass = 1; //kg 
    this.power = 200; //W 

    this.update = function(dt) {/*...*/} //update x/y based on dx/dy 

    /** 
    * Direct translation of Exceptyon's equations, but preserving sign in cos^2, sin^2 and sqrt 
    * operations. 
    * @param dt delta time in seconds 
    */ 
    this.speedup2 = function(dt) { 
     this.ex += this.power * dt * cos2(this.pangle); 
     this.ey += this.power * dt * -sin2(this.pangle); 
     var signx = this.ex > 0 ? 1 : -1; 
     var signy = this.ey > 0 ? 1 : -1; 
     this.dx = Math.sqrt(2 * Math.abs(this.ex)/this.mass) * signx; 
     this.dy = Math.sqrt(2 * Math.abs(this.ey)/this.mass) * signy; 
    }; 

    /** 
    * Modified variation of Exception's post where I transform energy "vector" into velocity, that 
    * I believe is equivalent. 
    */ 
    this.speedup = function(dt) { 
     this.ex += Math.cos(this.pangle) * this.power * dt; 
     this.ey += -Math.sin(this.pangle) * this.power * dt; 
     var totalEnergy = Math.sqrt(this.ex * this.ex + this.ey * this.ey); 
     var speed = Math.sqrt(2 * totalEnergy/this.mass); 

     var ratio = speed/totalEnergy; 
     this.dx = this.ex * ratio; 
     this.dy = this.ey * ratio; 

     this.speed = Math.sqrt(this.dx * this.dx + this.dy * this.dy); 
    }; 
} 
+1

能源是一個標量。您需要處理矢量量,如力和加速度。你之前就有過。順便說一句 - 能量以速度的平方增加。恆定的加速度使能量呈指數級增長。 –

+0

我想你可能會混淆一些基本的物理概念。 「恆定能量」對加速沒有意義。例如一個完整的燃料箱具有恆定的能量,它只是坐在那裏。功率是應用能量的速率。谷歌爲此的第一次襲擊是http://hyperphysics.phy-astr.gsu.edu/hbase/work.html這可能會有所幫助。 –

+0

沒有能量的方向。也沒有哪一個更「現實」,因爲它們都是真實的,它們基本上都是以同樣的方式看待,但是具有不同的角度。在你的情況下,更「適合」的是矢量方法,這是一個/ V/S(此外,這篇文章沒有與編程無關) –

回答

1

你可以做,如果你願意,你只需要跟蹤沿x和y(和z動能的,如果你是移動在3D中)。

Ex = kinetic energy along x-axis 
Ey = kinetic energy along Y-axis 
//Etot = Ex + Ey 
//dt = 1/fps 

OFC如果你不喜歡笛卡兒Ex, Ey你可以繼續Etot, direction,它是完全等價的。轉換將是:

Ex = Etot * cos^2(direction) 
Ey = Etot * sin^2(direction) 

和反:在給定的框架

Etot = Ex + Ey 
direction = atan2(sqrt(Ey), sqrt(Ex)) 

你的引擎會給你力量* DT的能量,也就是

\delta{Ex} = Power*dt * cos^2(direction) 
\delta{Ey} = Power*dt * sin^2(direction) 

,並從那裏,你應該發現每一幀:

//Etot = E_x + E_y 
//vtot = sqrt(2*Etot/m) 
v_x = sqrt(2*Ex/m) // = vtot*cos(direction) 
v_y = sqrt(2*Ey/m) // = vtot*sin(direction) 
+0

因爲我有一個案例的工作,我的第一個方法是像你一樣分別嘗試x和y,但它沒有工作,也許我錯過了一個步驟? 1D案例:假設dt = 1秒,質量1kg,功率2kW。第一幀從停止點開始,2 kW * 1s = 2J。 sqrt(2 * 2J/1kg)= 2m/s。下一幀,現在能量是4J,速度是2.83米/秒。所以現在我們嘗試30度角的2D情況下,power_x = cos(30deg)* 2kW = 1.73kW,power_y = 1kW。 2秒後,Ex = 3.46J,Ey = 2J。 Etot然後是4J,如預期。 vx = sqrt(2 * 3.46J/1kg)= 2.63m/s,vy = 2m/s,vtot = 3.30,這不是預期的2.83m/s。 –

+0

我認爲vx_1的計算不正確,因爲您必須將能量和速度視爲標量。我發現了兩種等效的方法:一種是將能量作爲矢量,然後在轉換爲速度時,velocity = energy_vector/Etot * vtot。另一種方法是在前後計算速度,然後在推力方向上應用速度的變化(我不知道這是否簡化到您的公式來計算a,如果Ex被替換爲Etot)。我選擇了能量矢量法,因爲我認爲在歐拉積分下它更準確。 –

+0

我編輯過,我犯了一個錯誤,它是Etot = Ex + Ey,因爲v^2 = vx^2 + vy^2 – Exceptyon