2013-02-26 117 views
1

我正在尝试将3D点绘制到2D表面上(我目前正在使用SDL.NET作为我的'游戏引擎')。表面尺寸为800x400像素,三维坐标的范围为-4000至4000.我的观点将始终是自顶向下的视图,并且不会有任何相机移动。有人可以提供一些原生的c#,伪代码或将三维空间中的坐标转换为二维曲面的简单解释吗?3d到2d点转换

同时林订货this book人们告诉我,这将解决很多我的数学缺点....希望:)

+0

是你的3D坐标所有-4000到+4000?你想在800x400网格上显示整个地图还是移动窗口? – 2013-02-26 01:31:43

+0

我刚刚通过将三维坐标转换为二维曲面,并希望分享我的方法,因为它与下面的答案有很大不同。我的数学技能不是最好的,所以我相信我的解决方案虽然简单,但可以帮助别人理解这种转换(使用10年级数学)。 – CramerTV 2013-10-02 00:28:47

回答

8

注: 这是文本的大墙,我完全呆滞了很多重要的东西 - 但这里我的本意只是一个概述...希望一些术语/概念,这里将带领你以更好地在网络上搜索适当的大块。

它帮助,如果你走你的路,通过“生活作为一个点”:

我们在这里,一个可爱的小的三维点:

var happyPoint = new Point(0, 0, 0); 

这里是它的哥们,在定义关于他的朋友:

var friendlyPoint = new Point(1, 0, 0); 

现在,让我们叫这两点我们的“模式” - 我们将使用术语“模型空间”谈点单一的三维结构(如房子,怪物等)。

模型不是生活在一个真空中,但是......它通常更容易将“模型空间”和“世界空间”分开,使模型调整变得更容易(否则,所有模型都需要处于相同的比例尺,具有相同的方向等等,再加上试图在3D建模程序中工作将是friggin不可能)

因此,我们将为我们的“模型”定义一个“世界变换” ,2分是一个跛脚模型,但它仍然是一个模型)。

什么是“世界变换”?简单地说:

  • 甲世界变换W = T X R X S,其中
  • T = 翻译 - 即,沿X滑动,Y或Z轴
  • R = 旋转 - 转动模型相对于轴线
  • S = 缩放 - 沿轴线
调整大小的模型(内保持所有的相对点)

我们将采取简单的在这里,只是我们的世界转变为身份矩阵 - 基本上,这意味着我们不希望它平移,旋转或缩放:

world = [ 
      1 0 0 0 
      0 1 0 0 
      0 0 1 0 
      0 0 0 1 
     ]; 

我强烈建议你刷一下你的矩阵数学,尤其是乘法和矢量 - >矩阵运算,它使用三维图形中的全部破坏时间。如果巧妙地跳过实际的矩阵乘法,我会告诉你,我们的“世界变换”和我们的模型点相乘再次结束于我们的模型点(尽管在这个有趣的新的四维矢量表示中,我不会在这里触及)。

所以我们已经得到了我们的观点,并且我们已经将它们定位在“空间”中......现在呢?

那么,我们从哪里看?这导致View TransformationsCamera Projection概念 - 基本上,它只是一个矩阵乘法 - 观察:

说,我们已经有了一个点X,在...哦,(4×2)左右:

| 
| 
| 
|  
| X 
| 
------------------------ 

从原点(0 0)的角度来看,X (4 2) - 但是说我们把相机放在右边?

| 
| 
| 
|  
| X   >-camera 
| 
------------------------ 

X相对于相机的“位置”是什么?可能与(0 9)或(9 0)更接近,取决于相机的“向上”和“向右”方向。这就是视图变换 - 将一组三维点映射到另一组三维点,从观察者的角度看它们是“正确的”。对于自上而下的固定摄像机,您的观察者将在天空中处于固定位置,并且所有模型都将相应地转换。

所以我们来画吧!

不幸的是,我们的屏幕不是3D(尚未),所以首先我们需要将这个点“投射”到2D表面上。投影是...那么,它基本上是一个映射,看起来像:

(x, y, z) => (x, y) 

可能的突起的数量是近了无限的:例如,我们可以只在XY坐标由Z转移:

func(x, y, z) => new point2d(x + z, y + z); 

通常情况下,你想这个投影模仿但看3D场景时,人的视网膜做投影,所以我们在视图投影的概念带来的。有几种不同的视图投影,如Orthographic,YawPitchRoll-definedPerspective/FOV-defined;其中每个都有几个关键的数据位,您需要正确构建投影。

基于视角/ FOV投影,例如,需要:

  • 你的“眼球”(即,屏幕)的位置
  • 如何更远的“眼球”是能够聚焦(“远剪裁平面”)
  • 您的角度视野(即伸出手臂,只是在周边视觉的边缘)
  • “透镜”的宽度与高度的比率“重新浏览(通常是您的屏幕分辨率)

一旦你得到了这些数字,你创造的东西称为“边界视锥”,这看起来有点像顶部的金字塔砍掉:

\-----------------/ 
\    /
    \   /
    \   /
    \  /
    \-------/ 

或前:

___________________ 
| _____________ | 
| |    | | 
| |    | | 
| |    | | 
| |    | | 
| |    | | 
| |_____________| | 
|___________________| 

我不会做矩阵计算在这里,因为这是所有在其他地方定义的 - 事实上,大多数图书馆都helper方法会产生相应的矩阵为你 - 但这里的大致工作原理是:

比方说,你快乐的小点就在于此视锥:

\-----------------/ 
\    /
    \ o<-pt  /
    \   /
    \  /
    \-------/ 

___________________ 
| _____________ | 
| |    | | 
| |    | | 
|o |    | | 
|^---- pt  | | 
| |    | | 
| |_____________| | 
|___________________| 

注意它的方式到一边,到目前为止,它是走出“近剪裁平面”矩形的 - 这将是什么样的,如果你“看着“金字塔的小端?

就像寻找到一个棱镜(或镜头),该点是“弯曲”进入查看:

___________________ 
| _____________ | 
| |    | | 
| |    | | 
|>>>o <- pt is | | 
| | shifted | | 
| |    | | 
| |_____________| | 
|___________________| 

换句话说,如果你有一个明亮的光背后圆台,其中你的点的阴影会被“投射”在近剪裁区域上吗? (小矩形),这是所有投影 - 一个点到另一个的映射,在这种情况下,除去Z分量和的方式,“有道理”我们的眼睛相应改变X和Y。

+0

哇!什么答案,非常感谢你,我真的对理论有了更好的理解现在。我将开始构建我的'转换器',并在今天晚些时候发布代码,以确定我是否做得对,欢呼m8! – 2013-02-27 15:21:49

+1

这值得赞赏! – Nissim 2016-08-10 16:18:58

2

您需要考虑到的观点。根据你的观点,情节点会有所不同。如果你想要一个正交角度(基本上没有角度),你会运行一个矩阵变换是这样的:

enter image description here

其中一个代表你的3D点和b代表你的2D点的结果。 矢量小号是任意缩放因子,并ç是任意偏移

这里是另一篇类似这样的一个很好的答案:

Basic render 3D perspective projection onto 2D screen with camera (without opengl)

这里一些更多信息

http://en.wikipedia.org/wiki/3D_projection