視点とカメラの注視対象との位置関係の設定

視点とカメラの注視対象との、位置関係を設定する方法を解説します。

DeviceインスタンスのTransform.Viewプロパティ (ビュー トランスフォーム行列) に、LookAtLHメソッドで作成した行列を設定します。

public static Matrix LookAtLH(
    Vector3 cameraPosition, // 視点の位置
    Vector3 cameraTarget,   // 目標の位置
    Vector3 cameraUpVector  // 上方を示すベクトル
);
Matrix.LookAtLH(Vector3,Vector3,Vector3) | MSDN

計算式

このメソッドは、

zaxis = normal( cameraTarget - cameraPosition )
xaxis = normal( cross( cameraUpVector, zaxis ) )
yaxis = cross( zaxis, xaxis )

のような演算を行います。演算結果の行列は、

xaxis.x yaxis.x zaxis.x 0
xaxis.y yaxis.y zaxis.y 0
xaxis.z yaxis.z zaxis.z 0
-dot(xaxis, cameraPosition) -dot(yaxis, cameraPosition) -dot(zaxis, cameraPosition) 1

であり、コードで表すと

Vector3 zaxis = Vector3.Normalize( cameraTarget - cameraPosition );
Vector3 xaxis = Vector3.Normalize( Vector3.Cross( cameraUpVector, zaxis ) );
Vector3 yaxis = Vector3.Cross( zaxis, xaxis );

Matrix matrix = new Matrix();

matrix.M11 = xaxis.X;
matrix.M12 = yaxis.X;
matrix.M13 = zaxis.X;
matrix.M14 = 0.0f;

matrix.M21 = xaxis.Y;
matrix.M22 = yaxis.Y;
matrix.M23 = zaxis.Y;
matrix.M24 = 0.0f;

matrix.M31 = xaxis.Z;
matrix.M32 = yaxis.Z;
matrix.M33 = zaxis.Z;
matrix.M34 = 0.0f;

matrix.M41 = -Vector3.Dot( xaxis, cameraPosition );
matrix.M42 = -Vector3.Dot( yaxis, cameraPosition );
matrix.M43 = -Vector3.Dot( zaxis, cameraPosition );
matrix.M44 = 1.0f;

となり、これは

Matrix matrix = Matrix.LookAtLH( cameraPosition, cameraTarget, cameraUpVector );

と同じ結果を返します。

極座標系 (polar coordinate system)

動径をr、天頂角をθ、方位角をφとするとき、極座標系 (r,θ,φ) と直行座標系 (x,y,z) との間には、

の関係があります。よって極座標系から視点の位置は、

float radiusVector; // 動径
float zenithAngle;  // 天頂角 [deg]
float azimuthAngle; // 方位角 [deg]

float radius = radiusVector;
float theta = Geometry.DegreeToRadian( zenithAngle );
float phi = Geometry.DegreeToRadian( azimuthAngle );

// 視点の位置
Vector3 cameraPosition = new Vector3(
    ( float )( radius * Math.Sin( theta ) * Math.Cos( phi ) ),
    ( float )( radius * Math.Sin( theta ) * Math.Sin( phi ) ),
    ( float )( radius * Math.Cos( theta ) )
    );

のようにして求められます。