.Net Matrix3D Transform() 究竟做了什么/为什么我得到“-无限”?
What exactly does a .Net Matrix3D Transform() do / why am I getting "- infinity"?
我正在尝试对某些 3D 点进行透视变换。 (如果有帮助,我正在尝试应用 here 中描述的算法)。但基本上,我有一个具有以下值的 Matrix3D:
HasInverse = true
IsAffine = false
IsIdentity = false
M11 = 1.000000000000000
M12 = 0.0
M13 = 0.0
M14 = 0.0
M21 = 0.0
M22 = 1.000000000000000
M23 = 0.0
M24 = 0.0
M31 = 0.0
M32 = 0.0
M33 = -1.0101010101010102
M34 = 0.0
M44 = 0.0
OffsetX = 100
OffsetY = -1.0101010101010102
OffsetZ = 0.0
当我使用此矩阵将变换应用到点 310,120,0 时。 . .
Point3D p = new Point3D(310, 120, 0);
Point3D pointResult = new Point3D();
pointResult = (Point3D)TheMatrix.Transform(p);
... 我得到 (Infinity, Infinity, -Infinity) 结果。 究竟 transform() 方法做了什么,为什么我会得到那个结果? MSDN 只是说了那个方法。 . .
Transforms the specified Point3D by the Matrix3D and returns the
result.
遍历源代码有点痛苦,但这是我可以收集到的... Transform
在内部调用一个名为 MultiplyPoint
的方法(下面显示的两个源方法),它生成一个变量 w
, x, y, z 与对应值的乘积之和,_m11, _m21, _m31。这些变量是在称为 NormalizedAffineInvert
的方法中乘以倒数和转置的结果。我不会 post 所有的源代码,但是 here's the link。
我所能想象的就是 w
不知何故最终等于 0。因为你说 IsAffine = false
,你输入除法逻辑并除以零因此导致 Infinity
。请注意,调用 public 方法 Invert()
将在内部调用 NormalizedAffineInvert
。你有调用过这个方法吗?
#region Transformation Services
/// <summary>
/// Transforms the given Point3D by this matrix, projecting the
/// result back into the W=1 plane.
/// </summary>
/// <param name="point">Point to transform.
/// <returns>Transformed point.</returns>
public Point3D Transform(Point3D point)
{
MultiplyPoint(ref point);
return point;
}
乘点:
internal void MultiplyPoint(ref Point3D point)
{
if (IsDistinguishedIdentity)
return;
double x = point.X;
double y = point.Y;
double z = point.Z;
point.X = x*_m11 + y*_m21 + z*_m31 + _offsetX;
point.Y = x*_m12 + y*_m22 + z*_m32 + _offsetY;
point.Z = x*_m13 + y*_m23 + z*_m33 + _offsetZ;
if (!IsAffine)
{
double w = x*_m14 + y*_m24 + z*_m34 + _m44;
point.X /= w;
point.Y /= w;
point.Z /= w;
}
}
首先通过附加 1:
将您的 Point3D
转换为齐次坐标中的向量
p_h = (310, 120, 0, 1)
然后,将转换应用为乘法:
p_h* = p_h * M
= (410, 119, 0, 0)
然后,执行 w 剪辑(这是透视变换所必需的)。 w 剪辑将向量除以其 w 分量(最后一个维度)。由于这是零,你会得到一个无限的结果。
问题是矩阵'M44
。将其设置为 1,你应该没问题。至少,矩阵的最后一列应该包含一些值。如果它们都为零,你将永远得到无限的结果。
我正在尝试对某些 3D 点进行透视变换。 (如果有帮助,我正在尝试应用 here 中描述的算法)。但基本上,我有一个具有以下值的 Matrix3D:
HasInverse = true
IsAffine = false
IsIdentity = false
M11 = 1.000000000000000
M12 = 0.0
M13 = 0.0
M14 = 0.0
M21 = 0.0
M22 = 1.000000000000000
M23 = 0.0
M24 = 0.0
M31 = 0.0
M32 = 0.0
M33 = -1.0101010101010102
M34 = 0.0
M44 = 0.0
OffsetX = 100
OffsetY = -1.0101010101010102
OffsetZ = 0.0
当我使用此矩阵将变换应用到点 310,120,0 时。 . .
Point3D p = new Point3D(310, 120, 0);
Point3D pointResult = new Point3D();
pointResult = (Point3D)TheMatrix.Transform(p);
... 我得到 (Infinity, Infinity, -Infinity) 结果。 究竟 transform() 方法做了什么,为什么我会得到那个结果? MSDN 只是说了那个方法。 . .
Transforms the specified Point3D by the Matrix3D and returns the result.
遍历源代码有点痛苦,但这是我可以收集到的... Transform
在内部调用一个名为 MultiplyPoint
的方法(下面显示的两个源方法),它生成一个变量 w
, x, y, z 与对应值的乘积之和,_m11, _m21, _m31。这些变量是在称为 NormalizedAffineInvert
的方法中乘以倒数和转置的结果。我不会 post 所有的源代码,但是 here's the link。
我所能想象的就是 w
不知何故最终等于 0。因为你说 IsAffine = false
,你输入除法逻辑并除以零因此导致 Infinity
。请注意,调用 public 方法 Invert()
将在内部调用 NormalizedAffineInvert
。你有调用过这个方法吗?
#region Transformation Services
/// <summary>
/// Transforms the given Point3D by this matrix, projecting the
/// result back into the W=1 plane.
/// </summary>
/// <param name="point">Point to transform.
/// <returns>Transformed point.</returns>
public Point3D Transform(Point3D point)
{
MultiplyPoint(ref point);
return point;
}
乘点:
internal void MultiplyPoint(ref Point3D point)
{
if (IsDistinguishedIdentity)
return;
double x = point.X;
double y = point.Y;
double z = point.Z;
point.X = x*_m11 + y*_m21 + z*_m31 + _offsetX;
point.Y = x*_m12 + y*_m22 + z*_m32 + _offsetY;
point.Z = x*_m13 + y*_m23 + z*_m33 + _offsetZ;
if (!IsAffine)
{
double w = x*_m14 + y*_m24 + z*_m34 + _m44;
point.X /= w;
point.Y /= w;
point.Z /= w;
}
}
首先通过附加 1:
将您的Point3D
转换为齐次坐标中的向量
p_h = (310, 120, 0, 1)
然后,将转换应用为乘法:
p_h* = p_h * M
= (410, 119, 0, 0)
然后,执行 w 剪辑(这是透视变换所必需的)。 w 剪辑将向量除以其 w 分量(最后一个维度)。由于这是零,你会得到一个无限的结果。
问题是矩阵'M44
。将其设置为 1,你应该没问题。至少,矩阵的最后一列应该包含一些值。如果它们都为零,你将永远得到无限的结果。