BOX2D 自然的旋轉到乙個指定角度

2021-07-11 22:05:01 字數 3405 閱讀 4472

在box2d 中如何控制body 自然的旋轉到乙個指定角度?

這個問題在許多遊戲中控制角度時都會遇到,但是在box2d中,你必須考慮到如果轉動中與其他body碰撞等物理因素。

能夠想到的解決方案有三種:

1 在update方法裡不斷更改body的角度,使他接近於要設定的角度。 

b2vec2 clickedpoint;//

設定點的向量

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 );

很明顯,第一種方法並不適合在物理引擎中使用,因為不斷設定body的角度會打亂box2d中的**效果。

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...