[英]Rotate around a point other than origin?
這比編程更像是數學,但我怎樣才能改進這個旋轉矩陣來接受一個可以旋轉的點? 有軸,它指定旋轉的性質,但也有頂點圍繞軸旋轉的點。 我怎樣才能改進這個矩陣來接受一個職位? 它恰好是用 C 編寫的,但這不是很相關,因為我正在尋找邏輯。
matrix_float4x4 Rotate(const float Radians, const float X, const float Y, const float Z) {
const float
Sin = sinf(Radians),
Cos = cosf(Radians),
C = 1-Cos, SinX = Sin*X,
SinY = Sin*Y,
SinZ = Sin*Z,
CX = X*C,
CY = Y*C,
CZ = C*Z;
return (matrix_float4x4){
.columns = {
{Cos+(X*CX), (Y*CX)+SinZ, (Z*CX)-SinY, 0},
{(X*CY)-SinZ, Cos+(Y*CY), (Z*CY)+SinX, 0},
{(X*CZ)+SinY, (Y*CZ)-SinX, Cos+(Z*CZ), 0},
{0, 0, 0, 1}
}
};
}
問題是,你想改造物體還是世界? 換句話說,您可以旋轉對象並將其移動(平移)到特定位置,或者您可以圍繞特定點(軌道相機)旋轉世界。
正如'scg'所指出的:T * R != R * T
對象的變換公式為:T * C * R * -C(T:平移,C:中心,R:旋轉)
現在,涉及到很多操作。 如果您查看平移或旋轉矩陣,就會發現很多零。 您可以消除這些步驟:
例子:
typedef struct mat4_rec {
float
a11, a12, a13, a14,
a21, a22, a23, a24,
a31, a32, a33, a34,
a41, a42, a43, a44;
} mat4_t;
mat4_t* translate(mat4_t *m, float x, float y, float z)
{
m->a14 += m->a11 * x + m->a12 * y + m->a13 * z;
m->a24 += m->a21 * x + m->a22 * y + m->a23 * z;
m->a34 += m->a31 * x + m->a32 * y + m->a33 * z;
m->a44 += m->a41 * x + m->a42 * y + m->a43 * z;
return m;
}
轉換 4x4 矩陣 (M *= T)。 這些操作比完整的 4x4 乘法要少得多。
旋轉 (M *= R) 看起來像這樣:
mat4_t* rotate(mat4_t *m, float rad, float x, float y, float z)
{
float s = sinf(rad);
float c = cosf(rad);
float t = 1.0f - c;
float a11 = x * x * t + c;
float a12 = x * y * t - z * s;
float a13 = x * z * t + y * s;
float a21 = y * x * t + z * s;
float a22 = y * y * t + c;
float a23 = y * z * t - x * s;
float a31 = z * x * t - y * s;
float a32 = z * y * t + x * s;
float a33 = z * z * t + c;
float m11 = m->a11;
float m12 = m->a12;
float m13 = m->a13;
float m21 = m->a21;
float m22 = m->a22;
float m23 = m->a23;
float m31 = m->a31;
float m32 = m->a32;
float m33 = m->a33;
float m41 = m->a41;
float m42 = m->a42;
float m43 = m->a43;
m->a11 = m11 * a11 + m12 * a21 + m13 * a31;
m->a12 = m11 * a12 + m12 * a22 + m13 * a32;
m->a13 = m11 * a13 + m12 * a23 + m13 * a33;
m->a21 = m21 * a11 + m22 * a21 + m23 * a31;
m->a22 = m21 * a12 + m22 * a22 + m23 * a32;
m->a23 = m21 * a13 + m22 * a23 + m23 * a33;
m->a31 = m31 * a11 + m32 * a21 + m33 * a31;
m->a32 = m31 * a12 + m32 * a22 + m33 * a32;
m->a33 = m31 * a13 + m32 * a23 + m33 * a33;
m->a41 = m41 * a11 + m42 * a21 + m43 * a31;
m->a42 = m41 * a12 + m42 * a22 + m43 * a32;
m->a43 = m41 * a13 + m42 * a23 + m43 * a33;
return m;
}
實現轉換:T * C * R * -C
mat4_t m; // <- set to identiy or something else
// T - move position of object by one unit along the x axis
translate(&m, 1, 0, 0);
// C - move pivot point down along the y axis
translate(&m, 0, -1, 0);
// R - 180 degress around the z axis
rotate(&m, M_PI, 0, 0, 1);
// -C - restore pivot point
translate(&m, 0, 1, 0);
// multiply matrix by any vector (M * V)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.