Meine Quaternion -Mathematik ist ein bisschen verrostet und ich versuche herauszufinden, welche der folgenden Implementierungen korrekter sind ... < /p>
Hier sehen Sie Microsofts Version von Transforming ein Vektor von einem Quaternion: https://referencesource.microsoft.com/# ... or3.cs,347
Hier ist der Code und es wurde eindeutig optimiert:
public static Vector3 Transform(Vector3 value, Quaternion rotation)
{
float x2 = rotation.X + rotation.X;
float y2 = rotation.Y + rotation.Y;
float z2 = rotation.Z + rotation.Z;
float wx2 = rotation.W * x2;
float wy2 = rotation.W * y2;
float wz2 = rotation.W * z2;
float xx2 = rotation.X * x2;
float xy2 = rotation.X * y2;
float xz2 = rotation.X * z2;
float yy2 = rotation.Y * y2;
float yz2 = rotation.Y * z2;
float zz2 = rotation.Z * z2;
return new Vector3(
value.X * (1.0f - yy2 - zz2) + value.Y * (xy2 - wz2) + value.Z * (xz2 + wy2),
value.X * (xy2 + wz2) + value.Y * (1.0f - xx2 - zz2) + value.Z * (yz2 - wx2),
value.X * (xz2 - wy2) + value.Y * (yz2 + wx2) + value.Z * (1.0f - xx2 - yy2));
}
< /code>
Dies liefert jedoch unterschiedliche Ergebnisse für meine eigene (weniger optimierte) Implementierung: < /p>
public static Vector3 Transform(this Vector3 value, Quaternion rotation)
{
var q = new Quaternion(value.X, value.Y, value.Z, 0.0f);
var res = rotation.Conjugate() * q * rotation;
return new Vector3(res.X, res.Y, res.Z);
}
public static Quaternion operator *(Quaternion value1, Quaternion value2)
{
// 9 muls, 27 adds
var tmp_00 = (value1.Z - value1.Y) * (value2.Y - value2.Z);
var tmp_01 = (value1.W + value1.X) * (value2.W + value2.X);
var tmp_02 = (value1.W - value1.X) * (value2.Y + value2.Z);
var tmp_03 = (value1.Y + value1.Z) * (value2.W - value2.X);
var tmp_04 = (value1.Z - value1.X) * (value2.X - value2.Y);
var tmp_05 = (value1.Z + value1.X) * (value2.X + value2.Y);
var tmp_06 = (value1.W + value1.Y) * (value2.W - value2.Z);
var tmp_07 = (value1.W - value1.Y) * (value2.W + value2.Z);
var tmp_08 = tmp_05 + tmp_06 + tmp_07;
var tmp_09 = (tmp_04 + tmp_08) * 0.5f;
return new Quaternion(
tmp_01 + tmp_09 - tmp_08,
tmp_02 + tmp_09 - tmp_07,
tmp_03 + tmp_09 - tmp_06,
tmp_00 + tmp_09 - tmp_05
);
}
< /code>
Da diese nicht die gleichen Ergebnisse liefern, muss einer von ihnen falsch sein, aber welches ist es und warum? < /p>
Meine eigene Implementierung scheint In den Fällen zu arbeiten, in denen ich versuche, es zu verwenden, und die MS -Implementierung scheint kaputt zu sein, aber ich wäre überrascht, wenn es tatsächlich falsch wäre, da ich denke>
Quaternionvektorrotation ⇐ C#
Ein Treffpunkt für C#-Programmierer
1740323759
Anonymous
Meine Quaternion -Mathematik ist ein bisschen verrostet und ich versuche herauszufinden, welche der folgenden Implementierungen korrekter sind ... < /p>
Hier sehen Sie Microsofts Version von Transforming ein Vektor von einem Quaternion: https://referencesource.microsoft.com/#system.numerics/system/numerics/vector3.cs,347
Hier ist der Code und es wurde eindeutig optimiert:
public static Vector3 Transform(Vector3 value, Quaternion rotation)
{
float x2 = rotation.X + rotation.X;
float y2 = rotation.Y + rotation.Y;
float z2 = rotation.Z + rotation.Z;
float wx2 = rotation.W * x2;
float wy2 = rotation.W * y2;
float wz2 = rotation.W * z2;
float xx2 = rotation.X * x2;
float xy2 = rotation.X * y2;
float xz2 = rotation.X * z2;
float yy2 = rotation.Y * y2;
float yz2 = rotation.Y * z2;
float zz2 = rotation.Z * z2;
return new Vector3(
value.X * (1.0f - yy2 - zz2) + value.Y * (xy2 - wz2) + value.Z * (xz2 + wy2),
value.X * (xy2 + wz2) + value.Y * (1.0f - xx2 - zz2) + value.Z * (yz2 - wx2),
value.X * (xz2 - wy2) + value.Y * (yz2 + wx2) + value.Z * (1.0f - xx2 - yy2));
}
< /code>
Dies liefert jedoch unterschiedliche Ergebnisse für meine eigene (weniger optimierte) Implementierung: < /p>
public static Vector3 Transform(this Vector3 value, Quaternion rotation)
{
var q = new Quaternion(value.X, value.Y, value.Z, 0.0f);
var res = rotation.Conjugate() * q * rotation;
return new Vector3(res.X, res.Y, res.Z);
}
public static Quaternion operator *(Quaternion value1, Quaternion value2)
{
// 9 muls, 27 adds
var tmp_00 = (value1.Z - value1.Y) * (value2.Y - value2.Z);
var tmp_01 = (value1.W + value1.X) * (value2.W + value2.X);
var tmp_02 = (value1.W - value1.X) * (value2.Y + value2.Z);
var tmp_03 = (value1.Y + value1.Z) * (value2.W - value2.X);
var tmp_04 = (value1.Z - value1.X) * (value2.X - value2.Y);
var tmp_05 = (value1.Z + value1.X) * (value2.X + value2.Y);
var tmp_06 = (value1.W + value1.Y) * (value2.W - value2.Z);
var tmp_07 = (value1.W - value1.Y) * (value2.W + value2.Z);
var tmp_08 = tmp_05 + tmp_06 + tmp_07;
var tmp_09 = (tmp_04 + tmp_08) * 0.5f;
return new Quaternion(
tmp_01 + tmp_09 - tmp_08,
tmp_02 + tmp_09 - tmp_07,
tmp_03 + tmp_09 - tmp_06,
tmp_00 + tmp_09 - tmp_05
);
}
< /code>
Da diese nicht die gleichen Ergebnisse liefern, muss einer von ihnen falsch sein, aber welches ist es und warum? < /p>
Meine eigene Implementierung scheint In den Fällen zu arbeiten, in denen ich versuche, es zu verwenden, und die MS -Implementierung scheint kaputt zu sein, aber ich wäre überrascht, wenn es tatsächlich falsch wäre, da ich denke>