2017-11-11 13 views
3

私はマウスの動きでカメラのビューを変更しようとしています。カメラが原点の周りをシーンの下を進むことなく円弧状に動かしたいと思っています。ドームのような眺め。Arcballカメラのズーム

以下は、目の座標を取得し、この半アーチボールのビューを作成するのに問題なく機能します。私はシーンの下で見ることができないように条件をハードコードしました。この状態の結果、シーンの下に行くのではなく、カメラが中央にズームインします。私はカメラがこの「ズーム」をするのを妨げる方法について私の心を包み込むことはできません。私がドームビューの最下部に着くと、私は左または右に移動することができます。距離は一定です。どんな指導?

void onMotion(int x, int y) { 
    camX = distance * -sinf(x*(M_PI/180)) * cosf((y)*(M_PI/180)); 
    camY = distance * -sinf((y)*(M_PI/180)); 
    camZ = -distance * cosf((x)*(M_PI/180)) * cosf((y)*(M_PI/180)); 
    if (camY < 4) 
     camY = 4; 
    glutPostRedisplay(); 
} 
+0

距離がまったく変わっていますか?または、そうでない場合、あなたの視野は変化していますか?ズーム効果が発生する可能性もあります。 – user1118321

+0

@ user1118321、距離は静的ではありません。 FOVが変化しているかどうかをどうすれば確認できますか? – rafvasq

+1

視野は投影行列によって制御されます。それが変化していると、ズーム効果が生じる可能性があります。 – user1118321

答えて

2

これは、距離が固定されていないためです。camY < 4.カメラがあなたの球の南極に近づいたときを考えます。 y座標は4に設定されますが、xとzはまだ軸の近くにあります。

camY変数を設定するだけでなく、新しいy座標ですべてを再計算する必要があります。 camYを4に設定してから、camXcamZを新しい方向に適切な距離に戻すことができます。このようなもの:

if (camY < 4) 
{ 
    camY = 4; 
    // Normalize the new vector 
    mag = sqrt(camX * camX + camY * camY + camZ * camZ); 
    camX /= mag; 
    camY /= mag; 
    camZ /= mag; 

    // Now push it out to distance 
    camX *= distance; 
    camY *= distance; 
    camZ *= distance; 
} 
2

あなたは結果の座標が、入力角度制約する必要はありません。したがって

4 <= distance * -sin(y) 
-4/distance >= sin(y) 
//Assuming y is always between -PI/2 and PI/2 
arc sin(-4/distance) >= y 

を、冒頭で次のようにします。その後、

double yAngle = y * M_PI/180; 
double yThreshold = std::asin(-4.0/distance); 
if(yAngle > yThreshold) 
    yAngle = yThreshold; 

、代わりにyAngleを使用y

Btwでは、マウス座標からアングルまでのマッピングがちょっと変わっているようです。上記の式の仮定が成立するかどうかはわかりません。したがって、コードを変更する必要があります。さらに良い方法は、角度を計算する方法を調整することです。おそらくウィンドウサイズが考慮されるべきです。

関連する問題