我有问题或者好,我不知道如何将x,y,z值的3d点转换为2d点, 我必须绘制投影,其中我有点的x,y,z值,但我不知道如何将它们转换为2d,所以我可以将它们移动到我的轴上。
我一直在环顾wiki和google,但是我不太确定我应该使用哪种矩阵变换来获得想要的结果。
答案 0 :(得分:13)
让我们首先假设看着你的场景的相机以原点为中心,并查看-z
方向。
然后:
透视投影由下式给出:
x' = x/z
y' = y/z
正交投影由下式给出:
x' = x
y' = y
(即,只丢弃z分量)
现在您已应用上述步骤,您可能会获得(x',y') = (-28.4, +134.5)
点。您现在需要根据屏幕分辨率和相机“缩放系数”和宽高比来缩放和居中:例如,您可能希望乘以Zoom
并将screen_center
添加到{{1} }}和x
组件(注意:大多数图形渲染系统都指向y
方向,因此您可能需要交换y
组件的符号。您可能仍然会得到负坐标或坐标大于画布大小的像素。只是丢弃它们:这意味着它们不在您的视锥之内。
最后,如果您的相机不指向y
或未居中于原点,您可能想知道该怎么办。对于后者,它很简单:在执行任何其他操作之前,只需将相机坐标减去所有3D点的分量。对于相机旋转,它实际上也非常简单:您只需要在执行其他任何操作之前以相反的方式旋转您的相机。这只意味着您需要将所有3D坐标乘以相机旋转矩阵的转置。这一步背后的想法是,移动相机与反向移动点完全相同(并且旋转矩阵的反转是同一矩阵的转置)。
答案 1 :(得分:3)
我强烈建议使用现有的图形软件包,而不是尝试编写自己的库。我不知道你在使用什么语言,但OpenGL是一个开源图形引擎,可用于3D渲染,并具有跨语言可比性,因此它可能是一个开始的地方。
如果您坚持手动执行,this问题的答案中有非常好的示例代码。
答案 2 :(得分:3)
如果您打算以3维旋转形状,则只需要考虑相机角度。如果你对线性代数和三角学有深刻的理解,那么值得付出额外的努力,因为它使你的程序更加灵活,但如果你的数学不太多,我会推荐以下解决方案。
将3D图像投影到2D平面所需要做的就是创建和绘制方程式。
(x,y,z) -> (x',y')
您可以通过定义从3D点到2D点的三个映射来完成此操作。
(1,0,0) -> ( 1, 0)
(0,1,0) -> ( 0, 1)
(0,0,1) -> (-.7,-.7)
我使用(-.7, - 。7)进行z访问,因为该点距离原点大约1个单位,在x和y访问之间的中间位置。
获得这三个点后,您有足够的信息来计算任意点x,y,z。
(x,y,z) -> (1*x - .7*z, 1*y - .7*z)
在计算机图形学中,网格的原点不在屏幕的中心,而是在左上角。为了使用我们刚刚在程序中生成的公式,我们必须定义一个偏移量来将原点移动到屏幕的中心。我们将这个偏移点称为(Ox,Oy)。
使用偏移量,我们的等式变为以下。
(x,y,z) -> (Ox + 1*x - .7*z, Oy + 1*y - .7*z)
答案 3 :(得分:2)
我找到了将3D投影到等距 2D的方法。
我为等轴测视图提供了一个角度,当然还有像项目一样的3D点
Dim IsometricViewAngle As Integer = 30
Dim RowPoint As New Point3D(dx,dy,dz)
dx , dy 和 dz 是您的自定义值。 然后我必须计算X和Y增量和减量的 Delta 值,如
Dim XDelta = Math.Cos(IsometricViewAngle * Math.PI / 180)
Dim YDelta = Math.Sin(IsometricViewAngle * Math.PI / 180)
Dim ZDelta = 0.5
好的,现在我要将3D投影到2D点:
Dim X As Double = (RowPoint.X * XDelta) + (RowPoint.Y * YDelta)
Dim Y As Double = (RowPoint.X * XDelta) + (RowPoint.Z * ZDelta)
Dim ProjectedPoint As New Point(X,Y)
并且最终结果在RadDiagram中效果最佳。 此致/
答案 4 :(得分:2)
这适合我:(它在vb中)。 f_nodes是平面节点,a_nodes是关于alpha,beta和gamma的变换后的3d节点。 (x,y,z)是一个点。有更复杂的关于。
ca = Cos(alpha)
sa = Sin(alpha)
cb = Cos(beta)
sb = Sin(beta)
cg = Cos(gamma)
sg = Sin(gamma)
q(1) = cg * (cb * X - sb * (sa * Y + ca * z)) - sg * (ca * Y - sa * z)
q(2) = sg * (cb * X - sb * (sa * Y + ca * z)) + cg * (ca * Y - sa * z)
q(3) = sb * X + cb * (sa * Y + ca * z)
f_nodes(i, 1) = q(1)
f_nodes(i, 2) = q(2)
a_nodes(i, 1) = q(1)
a_nodes(i, 2) = q(2)
a_nodes(i, 3) = q(3)