Um einen anderen Punkt als den Ursprung drehen?
Dies ist mehr Mathe-Y als Programmieren-Y, aber wie kann ich diese Rotationsmatrix verbessern, um einen Punkt zu akzeptieren, um den herum gedreht werden kann? Es gibt die Achse, die die Art der Drehung angibt, aber auch den Punkt, an dem die Scheitelpunkte um die Achse gedreht werden. Wie kann ich diese Matrix verbessern, um eine Position anzunehmen? Es ist zufällig in C geschrieben, aber das ist nicht sehr relevant, weil ich nach der Logik suche.
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}
}
};
}
Die Frage ist, wollen Sie das Objekt oder die Welt verändern? Mit anderen Worten, Sie können das Objekt drehen und an eine bestimmte Position verschieben (translatieren) oder Sie können die Welt um einen bestimmten Punkt drehen (Orbit-Kamera).
Wie von 'scg' gezeigt: T * R != R * T
Eine Transformationsformel für das Objekt wäre: T * C * R * -C (T: Translate, C: Center, R: Rotation)
Jetzt sind viele Operationen im Spiel. Betrachtet man eine Translations- oder Rotationsmatrix, so gibt es viele Nullen. Sie können diese Schritte eliminieren:
Beispiel:
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;
}
Um eine 4x4-Matrix zu übersetzen (M *= T). Dies sind viel weniger Operationen als eine vollständige 4x4-Multiplikation.
Rotation (M *= R) würde so aussehen:
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;
}
Um die Transformation zu implementieren: 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)