1

注: これは Processing IDE にあります

私は球状の軌道を下に向けようとしていますが、ほぼ達成しています。これは私がこれまでに持っているものです:

float cameraTheta, cameraPhi, cameraRadius; //camera position in spherical coordinates
float camx, camy, camz;

void setup() {
  size(500, 500, P3D);
  background(255);
  cameraRadius = 200.0f;
  cameraTheta = 2.80;
  cameraPhi = 2.0;
  recomputeOrientation();
}


void draw() {
  background(255);
  lights();
  mouseMotion();
  camera(camx, camy, camz, 0, 0, 0, 0, -1, 0);
  sphereDetail(10);
  sphere(25);
}

void mouseMotion()
{
  if (mousePressed) {
    cameraTheta += (mouseX - pmouseX)*0.05;
    cameraPhi   += (mouseY - pmouseY)*0.05;
  }
  recomputeOrientation();     //update camera (x,y,z) based on (radius,theta,phi)
}

void recomputeOrientation()
{
  camx = cameraRadius * sin(cameraTheta)*sin(cameraPhi);
  camz = cameraRadius * -cos(cameraTheta)*sin(cameraPhi);
  camy = cameraRadius * -cos(cameraPhi);
  redraw();
}

x回転はうまく機能しますが、y回転は上から下にタンブルし、マウスYが変化すると何度も何度も元に戻ります。必要なのは、マウスが動く限り一方向にタンブルし続けることですマウスが下に移動すると、上下に逆方向に移動します。誰でもこれを理解するのを手伝ってもらえますか?

4

1 に答える 1

1

この問題は、カメラのアップ ベクトルに関係しています。カメラを持って球体の極にどんどん近づけていくとしたら、極を通り過ぎるときはどのようにカメラを持ちますか? カメラ関数のupY引数により、処理は何をすべきかを知っています。

現在のコードでは、upYは常に -1 です。つまり、カメラが自身の向きを変えるとき、常にベクトル<0, -1, 0>をupの参照として使用します。これを変更して、球の極に達すると上下が反転するようにする必要があります。

boolean flip = false;
...
void draw() {
    ...
    camera(camx, camy, camz, 0, 0, 0, 0, flip ? 1.0 : -1.0, 0);
    ...
}

void mouseMotion()
{
    if (mousePressed) {
        cameraTheta += (mouseX - pmouseX) * 0.05;

        if (cameraTheta < 0) cameraTheta += 2 * PI;
        else if (cameraTheta >= 2 * PI) cameraTheta -= 2 * PI;

        if (flip)
            cameraPhi += (mouseY - pmouseY) * 0.05;
        else
            cameraPhi -= (mouseY - pmouseY) * 0.05;

        if (cameraPhi >= PI) {
            cameraPhi = PI - 0.01;
            cameraTheta += PI;
            flip = !flip;
        }
        else if (cameraPhi <= 0) {
            cameraPhi = 0.01;
            cameraTheta -= PI;
            flip = !flip;
        }
    }

    recomputeOrientation();
}

特筆すべきこと:

  1. cameraThetaを [0, 2 * PI) の範囲に、cameraPhiを [0.01, PI - 0.01)の範囲に保つコードを追加しました。数学的には、cameraPhiは [0, PI) の範囲内にある必要がありますが、これにより極でちらつきが発生します。この背後にある計算については、こちらを確認してください。
  2. フリップが true の場合、 cameraPhiは逆にインクリメントされます。
于 2011-12-05T22:10:39.247 に答える