2013-02-26 244 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