投影 - 将3d转换为2d

时间:2013-04-05 21:42:56

标签: math graph matrix projection

我有问题或者好,我不知道如何将x,y,z值的3d点转换为2d点, 我必须绘制投影,其中我有点的x,y,z值,但我不知道如何将它们转换为2d,所以我可以将它们移动到我的轴上。

enter image description here

我一直在环顾wiki和google,但是我不太确定我应该使用哪种矩阵变换来获得想要的结果。

5 个答案:

答案 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)