12

三次元空間での錐台の境界点の計算方法を次々と描きました。まず、カメラのxyz座標と、x、y、z軸を中心とした回転の3つの値をそれぞれ含む2つのデータセットがあります。特定のビュー距離が与えられると、6つの平面のそれぞれの境界点を計算できるはずです。私はこれらの方程式を使用して、遠方平面の幅と高さを計算しています。

hfar = 2 * tan(45/2) * view_distance
wfar = hfar * ratio

hfarは遠方平面の高さ、wfarは幅、ratioはビューポートの幅を高さで割った比率です。私はそれを理解するために次の図を使用しています:

ここに画像の説明を入力してください

(?、?、?)で注釈が付けられたポイントを見つける必要があります。私は数日間これらの値を計算しようとしていますが、役に立ちません。どんな助けでもいただければ幸いです。

また、トピックに関する情報を提供するいくつかの素晴らしい情報源は、ここここにあります。

編集:私がホイップした別の画像は、x軸を見下ろすy軸を通る単一のスライスを示しています。上の画像と同じ情報が表示されますが、私の問題も示されています。遠方平面の各境界点の適切なz軸値を計算できません。

ここに画像の説明を入力してください

同じプロセスを示すために、x軸を介して同じカットを作成できますが、プレーヤーが上または下を向いている角度を使用することに注意してください。

4

2 に答える 2

7

近距離平面と遠距離平面の中心点を計算します。

    vec3 nearCenter = camPos - camForward * nearDistance;
    vec3 farCenter = camPos - camForward * farDistance;

近距離平面と遠距離平面の幅と高さを計算します。

    real nearHeight = 2 * tan(fovRadians/ 2) * nearDistance;
    real farHeight = 2 * tan(fovRadians / 2) * farDistance;
    real nearWidth = nearHeight * viewRatio;
    real farWidth = farHeight * viewRatio;

近い平面と遠い平面からコーナーポイントを計算します。

    vec3 farTopLeft = farCenter + camUp * (farHeight*0.5) - camRight * (farWidth*0.5);
    vec3 farTopRight = farCenter + camUp * (farHeight*0.5) + camRight * (farWidth*0.5);
    vec3 farBottomLeft = farCenter - camUp * (farHeight*0.5) - camRight * (farWidth*0.5);
    vec3 farBottomRight = farCenter - camUp * (farHeight*0.5) + camRight * (farWidth*0.5);

    vec3 nearTopLeft = nearCenter + camY * (nearHeight*0.5) - camX * (nearWidth*0.5);
    vec3 nearTopRight = nearCenter + camY * (nearHeight*0.5) + camX * (nearWidth*0.5);
    vec3 nearBottomLeft = nearCenter - camY * (nearHeight*0.5) - camX * (nearWidth*0.5);
    vec3 nearBottomRight = nearCenter - camY * (nearHeight*0.5) + camX * (nearWidth*0.5);

平面の任意の3つのコーナーから各平面を計算し、CWまたはCCWを巻き、内側を指します(座標系によって異なります)。

    vec3 p0, p1, p2;

    p0 = nearBottomLeft; p1 = farBottomLeft; p2 = farTopLeft;
    vec3 leftPlaneNormal = Normalize(Cross(p1-p0, p2-p1));
    vec3 leftPlaneOffset = Dot(leftPlaneNormal, p0);

    p0 = nearTopLeft; p1 = farTopLeft; p2 = farTopRight;
    vec3 topPlaneNormal = Normalize(Cross(p1-p0, p2-p1));
    vec3 topPlaneNormal = Dot(topPlaneNormal , p0);

    p0 = nearTopRight; p1 = farTopRight; p2 = farBottomRight;
    vec3 rightPlaneNormal = Normalize(Cross(p1-p0, p2-p1));
    vec3 rightPlaneNormal = Dot(rightPlaneNormal , p0);

    p0 = nearBottomRight; p1 = farBottomRight; p2 = farBottomLeft;
    vec3 bottomPlaneNormal = Normalize(Cross(p1-p0, p2-p1));
    vec3 bottomPlaneNormal = Dot(bottomPlaneNormal , p0);
于 2015-01-10T02:32:54.010 に答える
5

あなたが解決しようとしている一般的な問題は、オブジェクトを3Dで回転させる方法だと思います。私が理解していることから、あなたはカメラのベクトルの大きさを取得する方法を知っていますが、それらの向きは知りません。カメラの[up]、[side]、[view / lookAt]ベクトルに適用するx、y、z軸を中心に角度回転を定義します。

ここに画像の説明を入力してください

上の図は、up、side、lookAtベクトルの意味を示しています。下の写真に示すように、それらは錐台に関連しています。

ここに画像の説明を入力してください

軸と角度を指定して点を回転させるC++の大まかなコードを次に示します。

    Vec3 RotatedBy(Vec3 const &axisVec, double angleDegCCW)
    {
        if(!angleDegCCW)
        {   return Vec3(this->x,this->y,this->z);   }

        Vec3 rotatedVec;
        double angleRad = angleDegCCW*3.141592653589/180.0;
        rotatedVec = this->ScaledBy(cos(angleRad)) +
                     (axisVec.Cross(*this)).ScaledBy(sin(angleRad)) +
                     axisVec.ScaledBy(axisVec.Dot(*this)).ScaledBy(1-cos(angleRad));

        return rotatedVec;
    }

上に回転したビューとサイドベクトルを取得したら、遠方の平面のコーナーを見つけることができます。

于 2012-12-02T04:07:20.617 に答える