0

OpenGLでマウスの水平方向の動きを検出しようとしているので、検出されたらglutPostRedisplay()を実行します。問題は、マウスの垂直方向の動きでもシーンが再描画されることです。

これは登録されたコールバックのコードです(mouse_inixとmouse_iniyはグローバル(double)変数であることに注意してください):

void mouse(int button, int state, int x, int y)
{
    if (state == GLUT_DOWN)  {
            mouse_inix = (double)x;
            mouse_iniy = (double)y;
    }
}

void motion(int x, int y)
{

    if (((double)x) != mouse_inix) {
            angle += 20.0;
            glutPostRedisplay();
    } 
}
4

1 に答える 1

0

本気ですか?投稿したコードからは、マウスの垂直移動が glutPostRedisplay() 呼び出しをトリガーするようには見えません。

しかし、ここでは「マウスの水平移動」を非常に狭く定義しました。マウスを上下に動かすと、ほぼ確実に数ピクセルの水平方向の動きが得られます。マウスがすべてのピクセルで動かないようにするために、マウスの周りにデッド ゾーンを配置することもできます。何かのようなもの:

void motion(int x, int y)
{
    if ((abs(x - (int)mouse_inix) > 10) {
        angle += 20.0;
        glutPostRedisplay();
    } 
}

それがここで起こっていることの1つです。もう 1 つは「double」の使用です。glut はマウスの座標を int として返すので、それに固執する方がよいでしょう。"(double)x != mouse_inix" を比較しようとすると、double の精度の問題により、ほぼ確実に true になります。通常、浮動小数点数を使用して正確に等しいか等しくないかを比較したくはありません。デッド ゾーンを使用するとその問題は解消されますが、それでも、必要がないのにダブルに変換する必要はありません。

「20」が度数なのかラジアンなのかはわかりませんが、どちらにしてもかなりびくびくした動きになる可能性があります. 移動のサイズをマウスの移動のサイズにスケーリングすることを検討してください。

void motion(int x, int y)
{
    int deltaX = (abs(x - (int)mouse_inix);
    if (deltaX > 10) {
        angle += (double)deltaX;  // or "deltaX/scaleFactor" to make it move more/less
        glutPostRedisplay();
    } 
}

それでも一方向にしか回転しません。「deltaX」の記号を使用すると、マウスの動かし方によって両方向に回転させることができます。

于 2012-11-08T19:56:51.433 に答える