在box2d 中如何控制body 自然的旋轉到乙個指定角度?
這個問題在許多遊戲中控制角度時都會遇到,但是在box2d中,你必須考慮到如果轉動中與其他body碰撞等物理因素。
能夠想到的解決方案有三種:
1 在update方法裡不斷更改body的角度,使他接近於要設定的角度。
b2vec2 clickedpoint;//很明顯,第一種方法並不適合在物理引擎中使用,因為不斷設定body的角度會打亂box2d中的**效果。設定點的向量
float bodyangle = body->getangle();//
取得物體自身的弧度
b2vec2 totarget = clickedpoint - body->getposition();//
計算角度差
float desiredangle = atanf( -totarget.x, totarget.y );//
計算設定的弧度
float totalrotation = desiredangle - bodyangle;//
計算需要旋轉的弧度
while ( totalrotation < -180 * degtorad ) totalrotation += 360 * degtorad;//
調整設定角度到-180到180度之間
while ( totalrotation > 180 * degtorad ) totalrotation -= 360 *degtorad;
float change = 1 * degtorad; //
每次間隔允許最大旋轉角度
float newangle = bodyangle + min( change, max(-change, totalrotation));
body->settransform( body->getposition(), newangle );
2 在update方法裡不斷給body施加乙個能使body轉到設定角度的力矩。
剛開始肯定會想到這樣做:
float totalrotation = desiredangle -bodyangle;
while
( totalrotation < -180 * degtorad ) totalrotation += 360 *degtorad;
while ( totalrotation > 180 * degtorad ) totalrotation -= 360 *degtorad;
但是執行看看?你會發現乙個問題,物體始終受到乙個朝向設定點角度方向的力矩,直到物體轉到這個角度,乍看好像沒問題,但是實際上,物體在到達設定角度時角速度並不是零,所以物體將繼續轉過這個角度,並受到乙個反向的力矩,然後到達設定角度後又一次超過設定角度,這樣永遠迴圈擺動,卻永遠到達不了設定角度。
總結了下原因沒有考慮到自身本身的角速度影響。
真的非常難解釋的非常清楚,可能我也理解的不太夠吧,直接給出解決方案。
方法是假設一定時間間隔dt內body不受任何轉矩,計算出dt間隔後的body角度,用來替換現在的body角度:
float dt = 1.0f / 60.0f
;float nextangle = bodyangle + body->getangularvelocity() *dt;
float totalrotation = desiredangle -nextangle;
while ( totalrotation < -180 * degtorad ) totalrotation += 360 *degtorad;
while ( totalrotation > 180 * degtorad ) totalrotation -= 360 *degtorad;
float desiredangularvelocity = totalrotation /dt;
float torque = body->getinertia() * desiredangularvelocity /dt;
但是這樣還不是最好的方法,body仍然需要來回晃動數個來回才能最終停下來。
3 在update方法裡不斷給body施加乙個能使body轉到設定角度的慣性衝量。
最終的解決方案是通過施加乙個衝量,和上面的方法相似:
float dt = 1.0f / 60.0f
;float nextangle = bodyangle + body->getangularvelocity() *dt;
float totalrotation = desiredangle -nextangle;
while ( totalrotation < -180 * degtorad ) totalrotation += 360 *degtorad;
while ( totalrotation > 180 * degtorad ) totalrotation -= 360 *degtorad;
float desiredangularvelocity = totalrotation /dt;
float impulse = body->getinertia() * desiredangularvelocity;//
disregard time factor
此外,如果你想在旋轉過程中設定乙個最大旋轉速度,可以新增乙個change值
float dt = 1.0f / 60.0f
;float nextangle = bodyangle + body->getangularvelocity() *dt;
float totalrotation = desiredangle -nextangle;
while ( totalrotation < -180 * degtorad ) totalrotation += 360 *degtorad;
while ( totalrotation > 180 * degtorad ) totalrotation -= 360 *degtorad;
float desiredangularvelocity = totalrotation /dt;
float change = 1 * degtorad; //
allow 1 degree rotation per time step
desiredangularvelocity = min( change, max(-change, desiredangularvelocity));
float impulse = body->getinertia() * desiredangularvelocity;//
disregard time factor
至此,基本完美的解決了這個問題,並且可以通過調整dt的值,可以實現不同精度的旋轉body到指定角度,通過調整change的值,改變旋轉的最大速度。
對應的,此方法還可以實現控制body自然的加速到乙個指定速度,我將在下次詳細講下方法。
BOX2D 自然的移動到乙個指定速度
接著上次的文章 在很多box2d遊戲中同樣會遇到這樣乙個問題 如何使乙個body自然的按照乙個指定速度移動?方法同上次所說的有三種 1 直接設定body的線速度 這是最直接的方法,但是同樣的,並不是在box2d中最好的方法 b2body body the body you want to conro...
body自然的按照乙個指定速度移動
在很多box2d遊戲中同樣會遇到這樣乙個問題 如何使乙個body自然的按照乙個指定速度移動?方法同上次所說的有三種 1 直接設定body的線速度 這是最直接的方法,但是同樣的,並不是在box2d中最好的方法 b2body body the body you want to conroll b2vec...
d3d實現乙個旋轉的三菱椎
include d3d9.h include d3dx9math.h pragma comment lib,d3d9.lib pragma comment lib,d3dx9.lib pragma comment lib,winmm.lib lpdirect3d9 g pd3d null direc...