gpt4 book ai didi

c# - System.Numerics 的矩阵乘法值完全错误

转载 作者:太空宇宙 更新时间:2023-11-03 12:33:19 25 4
gpt4 key购买 nike

即使 System.Numerics.Vectors可通过 NuGet 获得的库有自己的 View 和投影矩阵函数,我想自己实现它,只使用向量和矩阵结构。

不幸的是,当我将目标向量与(正确的) View 矩阵相乘时,我已经得到了一个完全错误的结果。我使用的是右手坐标系和以下说明

var cameraVector4 = new Vector4(0, 4, 2, 1);
var focusVector4 = new Vector4(0, 0, 0, 1);
var vMatrix4 = LookAt(cameraVector4, focusVector4, new Vector4(0, 1.0f, 0, 0));
var targetVector4 = new Vector4(1, 0, -1, 1);
var targetViewVector4 = Vector4.Transform(targetVector4, vMatrix4);

具有以下功能

private static Matrix4x4 LookAt(Vector4 cameraVector4, Vector4 focusVector4, Vector4 upVector4) {
if (cameraVector4 == focusVector4) return Matrix4x4.Identity;
var z = Vector4.Normalize(cameraVector4 - focusVector4);
var x = Vector4.Normalize(upVector4.Cross(z));
var y = Vector4.Normalize(z.Cross(x));

return new Matrix4x4(
x.X, x.Y, x.Z, -Vector4.Dot(x, cameraVector4),
y.X, y.Y, y.Z, -Vector4.Dot(y, cameraVector4),
z.X, z.Y, z.Z, -Vector4.Dot(z, cameraVector4),
0, 0, 0, 1);
}

public static class Vector4Extensions {
public static Vector4 Cross(this Vector4 self, Vector4 vector4) {
return new Vector4(
self.Y * vector4.Z - self.Z * vector4.Y,
self.Z * vector4.X - self.X * vector4.Z,
self.X * vector4.Y - self.Y * vector4.X,
0);
}
}

在我上面的示例中,预期的 View 矩阵是

vMatrix4确实具有相同的值(value)。乘法 vMatrix4targetVector4然而应该产生<1, 0.894427, -4.91935, 1>但 Visual Studio 报告 <1, -0.8944272, -0.4472136, 5.472136> .

我的问题是,库是否在计算结果时遇到数值问题,我是否遇到数据类型不匹配或者我是否使用了 Vector4.Transform错误地期望它返回 ViewMatrix * TargetVector .


编辑

当使用下面的自定义扩展方法时

public static Vector4 ApplyMatrix(this Vector4 self, Matrix4x4 matrix) {
return new Vector4(
matrix.M11 * self.X + matrix.M12 * self.Y + matrix.M13 * self.Z + matrix.M14 * self.W,
matrix.M21 * self.X + matrix.M22 * self.Y + matrix.M23 * self.Z + matrix.M24 * self.W,
matrix.M31 * self.X + matrix.M32 * self.Y + matrix.M33 * self.Z + matrix.M34 * self.W,
matrix.M41 * self.X + matrix.M42 * self.Y + matrix.M43 * self.Z + matrix.M44 * self.W
);
}

电话targetVector4.ApplyMatrix(targetVector4)产生正确的结果。这意味着内部 Vector4.Transform似乎在做一些真正出乎意料的事情。

最佳答案

我使用 dotPeek 反编译了 System.Numerics 库并偶然发现了这个:

public static Vector4 Transform(Vector4 vector, Matrix4x4 matrix) {
return
new Vector4(
(float)
(vector.X * (double) matrix.M11 +
vector.Y * (double) matrix.M21 +
vector.Z * (double) matrix.M31 +
vector.W * (double) matrix.M41),
(float)
(vector.X * (double) matrix.M12 +
vector.Y * (double) matrix.M22 +
vector.Z * (double) matrix.M32 +
vector.W * (double) matrix.M42),
(float)
(vector.X * (double) matrix.M13 +
vector.Y * (double) matrix.M23 +
vector.Z * (double) matrix.M33 +
vector.W * (double) matrix.M43),
(float)
(vector.X * (double) matrix.M14 +
vector.Y * (double) matrix.M24 +
vector.Z * (double) matrix.M34 +
vector.W * (double) matrix.M44));
}

此方法意味着库将向量解释为行向量并从右侧乘以矩阵,而不是将矩阵乘以列向量左侧的“通常”方式。要解决此问题,您有两种选择:

  • 编写一个自定义方法,按照您需要的顺序将向量与矩阵相乘。
  • 在应用转换之前转置矩阵,这可能会产生轻微的开销。

关于c# - System.Numerics 的矩阵乘法值完全错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41933843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com