J'ai essayé d'obtenir une rotation de matrice autour d'un axe arbitraire, je pense que je suis proche mais j'ai un bug. Je suis relativement nouveau dans les rotations 3D et j'ai une compréhension de base de ce qui se passe.Rotation de matrice autour d'un axe arbitraire Bug
public static Matrix4D Rotate(Vector3D u, Vector3D v)
{
double angle = Acos(u.Dot(v));
Vector3D axis = u.Cross(v);
double c = Cos(angle);
double s = Sin(angle);
double t = 1 - c;
return new Matrix4D(new double [,]
{
{ c + Pow(axis.X, 2) * t, axis.X * axis.Y * t -axis.Z * s, axis.X * axis.Z * t + axis.Y * s, 0 },
{ axis.Y * axis.X * t + axis.Z * s, c + Pow(axis.Y, 2) * t, axis.Y * axis.Z * t - axis.X * s, 0 },
{ axis.Z * axis.X * t - axis.Y * s, axis.Z * axis.Y * t + axis.X * s, c + Pow(axis.Z, 2) * t, 0 },
{ 0, 0, 0, 1 }
});
}
Le code ci-dessus est l'algorithme pour la rotation de la matrice. Lorsque je teste l'algorithme avec des vecteurs unitaires, je reçois ce qui suit:
Matrix4D rotationMatrix = Matrix4D.Rotate(new Vector3D(1, 0, 0), new Vector3D(0, 0, 1));
Vector4D vectorToRotate = new Vector4D(1,0,0,0);
Vector4D result = rotationMatrix * vectorToRotate;
//Result
X = 0.0000000000000000612;
Y = 0;
Z = 1;
Length = 1;
Avec une rotation de 90 degrés, je trouve que cela fonctionne presque parfaitement. Maintenant, regardons un 45 degrés de rotation:
Matrix4D rotationMatrix = Matrix4D.Rotate(new Vector3D(1, 0, 0), new Vector3D(1, 0, 1).Normalize());
Vector4D vectorToRotate = new Vector4D(1,0,0,0);
Vector4D result = rotationMatrix * vectorToRotate;
//Result
X = .70710678118654746;
Y = 0;
Z = .5;
Length = 0.8660254037844386;
Quand nous prenons, nous constatons que nous avons une rotation au lieu d'une rotation de 45 degrés degrés 35,28 le atan (0,5/0,707). En outre, la longueur du vecteur passe de 1 à 0,866. Est-ce que quelqu'un a des conseils sur ce que je fais mal?
Permettez-moi d'ajouter que d'obtenir l'angle en utilisant 'ACOS (u.Dot (v))' est pas très bon parce que si les deux vecteurs sont presque perpendiculaires les résultats sont instables . Utilisez 'Atan2 ((u.Cross (v)). Magnitude, u.Dot (v))' à la place. – ja72