資訊內(nèi)容
用Scratch做一個(gè)3D引擎
同學(xué)們應(yīng)該都接觸過(guò)3D游戲和3D動(dòng)畫(huà),那些栩栩如生的畫(huà)面,大家知不知道其實(shí)它們并不是照片,而是通過(guò)編程讓計(jì)算機(jī)實(shí)時(shí)畫(huà)(計(jì)算)出來(lái)的呢?今天我們就來(lái)學(xué)習(xí)3D動(dòng)畫(huà)的基本原理,以及用scratch實(shí)現(xiàn)3D動(dòng)畫(huà)的方法。

3D是英文3-Dimension,是三維的意思的。Dimension就是維度。3D就是指長(zhǎng)、寬、高三個(gè)維度,或者說(shuō)由x、y、z三個(gè)坐標(biāo)軸構(gòu)成的一種空間表示方法。它們構(gòu)成了一個(gè)和我們現(xiàn)實(shí)生活一樣的立體空間。
在計(jì)算機(jī)科學(xué)家的努力下,現(xiàn)代計(jì)算機(jī)3D技術(shù)已經(jīng)可以達(dá)到以假亂真的效果,基本上可以純粹通過(guò)計(jì)算來(lái)精確重現(xiàn)現(xiàn)實(shí)世界或者人們想象中的場(chǎng)景,其精確性、真實(shí)性和無(wú)限可操作性,使得3D技術(shù)可以廣泛應(yīng)用于醫(yī)學(xué)、教育、軍事、娛樂(lè)等領(lǐng)域。

大家知道電視機(jī)、電腦顯示器、手機(jī)屏幕等實(shí)際上是2D(二維)的平面,它只有長(zhǎng)和寬(只有x軸和y軸,沒(méi)有z軸)。要在2D平面上顯示出3D立體效果,就需要“3D引擎”,將立體物體的形狀、光線、運(yùn)動(dòng)等抽象成數(shù)學(xué)的表現(xiàn)形式,再通過(guò)計(jì)算輸出2D圖像,建立一個(gè)個(gè)真實(shí)的電腦世界。
Scratch沒(méi)有自帶的3D引擎。但是只要知道了3D動(dòng)畫(huà)背后的原理,我們可以自己制作一個(gè)3D引擎出來(lái)。這就是我們一直強(qiáng)調(diào)的編程的好玩和強(qiáng)大之處:只要你學(xué)習(xí)、掌握了事物背后的原理,我們就有辦法通過(guò)編程把它模擬出來(lái)。
1.????坐標(biāo)
接觸過(guò)scratch的同學(xué)對(duì)于2D坐標(biāo)已經(jīng)非常熟悉:一個(gè)物體的x坐標(biāo)代表它在屏幕左右方向的位置,y坐標(biāo)代表它在上下方向的位置。Scratch規(guī)定了舞臺(tái)的坐標(biāo)范圍分別是:x坐標(biāo)范圍在-240到240,y坐標(biāo)范圍在-180到180。?

3D坐標(biāo)系增加了一個(gè)z軸,其實(shí)就是2D坐標(biāo)在縱深方向的擴(kuò)展。如下圖所示,紅色直線代表x、y、z軸,黑色點(diǎn)的坐標(biāo)(x,y,z)代表了它在三維立體空間中的位置。

在scratch的2D舞臺(tái)上畫(huà)一個(gè)四邊形,我們需要知道四個(gè)頂點(diǎn)的坐標(biāo),然后把它們連線就可以畫(huà)出來(lái)。同樣道理,如果要在3D空間中畫(huà)出一個(gè)物體,一個(gè)方法是知道它的所有頂點(diǎn)的坐標(biāo),然后把頂點(diǎn)用直線連起來(lái)。比如下面這個(gè)立方體,把它的8個(gè)頂點(diǎn)連起來(lái)就能畫(huà)出來(lái)。

事實(shí)上,最復(fù)雜的3D圖案和最真實(shí)的3D動(dòng)畫(huà),背后都是通過(guò)這種方法畫(huà)出來(lái)。當(dāng)然畫(huà)面細(xì)節(jié)越豐富,背后的數(shù)學(xué)模型越復(fù)雜,也需要越多的計(jì)算機(jī)資源(CPU、內(nèi)存、顯卡)。作為入門介紹,本文只用最基本的3D圖形作為例子。
比如下面這個(gè)八面體,它有6個(gè)頂點(diǎn),上半部分和下半部分分別有四個(gè)三角形。它是最簡(jiǎn)單的可以一筆畫(huà)出來(lái)的多面體(上面的立方體就不能一筆畫(huà)出來(lái),而八面體可以,同學(xué)們可以思考一下為什么),比如依次連接點(diǎn)1-6-2-5-3-6-4-5-1-2-3-4-1就可以不重復(fù)任一條邊把它畫(huà)出來(lái)。
簡(jiǎn)單來(lái)說(shuō),只要我們知道了八面體的6個(gè)頂點(diǎn)的3D坐標(biāo),我們就能一筆過(guò)把它畫(huà)出來(lái)。

2.????投射
計(jì)算機(jī)屏幕是一個(gè)2D的平面,我們通過(guò)屏幕看到的3D物體,實(shí)際上是它根據(jù)透視原理在屏幕上的一個(gè)2D投射。
下圖說(shuō)明了這個(gè)原理:視點(diǎn)代表了觀察者(眼睛或者攝像頭)的位置。藍(lán)色是一個(gè)3D物體,紅色平面代表了屏幕。綠色部分就是3D物體在屏幕上的投射。在屏幕上顯示一個(gè)3D物體,其實(shí)是顯示它在2D平面上的投射(綠色部分)。?

根據(jù)上圖可以知道,我們?cè)谄聊簧峡吹降囊粋€(gè)3D物體的大小和形狀,其實(shí)跟以下幾個(gè)因素有關(guān):
-
3D物體的實(shí)際位置
-
視點(diǎn)的位置
-
屏幕的位置
那3D空間某一個(gè)點(diǎn)投射在某個(gè)2D屏幕上的坐標(biāo)是怎么計(jì)算的呢?請(qǐng)看下圖:

上圖中P代表3D空間中的一個(gè)點(diǎn),設(shè)它的位置坐標(biāo)值是x,y,z。現(xiàn)在要計(jì)算的是它在紅色的代表屏幕的平面上的投射點(diǎn)P’的坐標(biāo)值。其中O點(diǎn)代表視點(diǎn)。
兩次強(qiáng)調(diào),3D點(diǎn)的投射除了和它本身的坐標(biāo)有關(guān)之外,還和視點(diǎn)位置、投射屏幕位置有關(guān)。這三個(gè)因素是互相影響的。忽略了任何一個(gè)因素都不能得出投射點(diǎn)坐標(biāo)!
上圖中綠色平面代表P經(jīng)過(guò)的、和紅色屏幕平面平行的一個(gè)平面。線段OAB和紅色以及綠色平面都垂直。為了方便計(jì)算,我們讓紅色平面與x軸和y軸組成的平面平行。這樣,線段OAB和z軸平行(并垂直于紅色及綠色平面);線段BC以及AC’與x軸平行;線段PC以及P’C’與y軸平行。
因?yàn)锽C與AC’平行、PC與P’C’平行。根據(jù)相似三角形的特點(diǎn),我們很容易知道:
OA /OB = AC’ / BC = P’C’ / PC
所以,如果知道:
-
P點(diǎn)坐標(biāo)x,y,z
-
O點(diǎn)坐標(biāo)ox,oy,oz
-
紅色平面的z坐標(biāo)值pz
則:
OA = pz – oz
OB = z – oz
BC = x – ox
PC = y - oy
則P在紅色屏幕平面投射點(diǎn)P’的x、y軸坐標(biāo)值為:
-
P’的x坐標(biāo) =
ox + AC’ =
ox + [(pz – oz) * (x - ox)/(z - oz)] -
P’的y坐標(biāo) =
oy + P’C’ =
oy + [(pz - oz) * (y - oy)/(z - oz)]
接下來(lái)我們就用這個(gè)結(jié)論在scratch里畫(huà)出一個(gè)3D的八面體來(lái)。
Scratch的2D舞臺(tái)就是上面圖中的紅色屏幕,我們要做的就是把3D物體在2D屏幕上的投射畫(huà)出來(lái)。所以在畫(huà)(編程)之前我們先要在自己心中有一個(gè)3D坐標(biāo),視點(diǎn)的位置、屏幕的位置、物體的位置我們都要先想清楚。

八面體有6個(gè)頂點(diǎn),如下圖依次連接點(diǎn)1-6-2-5-3-6-4-5-1-2-3-4-1就可以一筆過(guò)畫(huà)出它來(lái):

-????? 首先我們用三個(gè)數(shù)組分別保存八面體6個(gè)頂點(diǎn)的x坐標(biāo)、y坐標(biāo)和z坐標(biāo):

-????? 定義視點(diǎn)及投射屏幕平面的位置(前面說(shuō)過(guò),為了方便計(jì)算,我們讓投射平面與x軸和y軸組成的平面平行,所以投射面只有一個(gè)z值)

-????? 根據(jù)前面3D到2D屏幕的投射公式,自定義一個(gè)積木用來(lái)投射轉(zhuǎn)換:

-????? 接下來(lái)就依次投射1-6-2-5-3-6-4-5-1-2-3-4-1點(diǎn),用畫(huà)筆畫(huà)出連接各點(diǎn)的軌跡。

執(zhí)行“投射八面體“積木就可以畫(huà)出下面的形狀:

3.????移動(dòng)
?
物體移動(dòng)只需要改變它所有頂點(diǎn)的x,y,z值,然后再重新投射一次就可以了。實(shí)現(xiàn)程序如下:

注意這里物體的移動(dòng)是在原3D空間的移動(dòng),所以物體在x軸方向或y軸方向移動(dòng)后,在屏幕上的投射會(huì)產(chǎn)生一定的旋轉(zhuǎn)效果。視點(diǎn)離投射平面越近,這種旋轉(zhuǎn)效果越明顯。
物體在z軸方向的移動(dòng)會(huì)產(chǎn)生物體大小變化的視覺(jué)效果:物體遠(yuǎn)離視點(diǎn)時(shí)物體投射縮小,接近視點(diǎn)時(shí)物體投射增大。原理如下圖所示:
?

移動(dòng)的效果如下:

4.????旋轉(zhuǎn)
物體旋轉(zhuǎn)涉及到三角函數(shù)的知識(shí)。推導(dǎo)過(guò)程需要一定的篇幅。我們只需要記住簡(jiǎn)單的結(jié)論來(lái)應(yīng)用就可以了。
旋轉(zhuǎn)可以分為三種:沿x軸的旋轉(zhuǎn)、沿y軸的旋轉(zhuǎn)和沿z軸的旋轉(zhuǎn)。
-????? 沿x軸旋轉(zhuǎn)時(shí),物體的x坐標(biāo)不變,y坐標(biāo)和z坐標(biāo)的變換規(guī)律是(A為旋轉(zhuǎn)角度):
新的y坐標(biāo) = y * cos A + z * sin A
新的z坐標(biāo) = z * cos A - y * sin A
-????? 沿y軸旋轉(zhuǎn)時(shí),物體的y坐標(biāo)不變,x坐標(biāo)和z坐標(biāo)的變換規(guī)律是(A為旋轉(zhuǎn)角度):
新的x坐標(biāo) = x * cos A - z * sin A
新的z坐標(biāo) = x * sin A + z * sin A
-????? 沿z軸旋轉(zhuǎn)時(shí),物體的z坐標(biāo)不變,x坐標(biāo)和y坐標(biāo)的變換規(guī)律是(A為旋轉(zhuǎn)角度):
新的x坐標(biāo) = x * cos A - y * sin A
新的y坐標(biāo) = x * sin A + y * cos A
下圖顯示了沿z軸旋轉(zhuǎn)時(shí)的變換情況。有興趣的同學(xué)可以自己推導(dǎo)出坐標(biāo)的變換規(guī)律。

注意上面說(shuō)的坐標(biāo)變化都是物體原3D坐標(biāo)的變化,而不是投射在2D平面上的投射坐標(biāo)的變化。換言之,旋轉(zhuǎn)改變物體坐標(biāo)后,還要重新計(jì)算投射坐標(biāo)。
旋轉(zhuǎn)的實(shí)現(xiàn)方法:


效果如下:

本文原程序可以在這個(gè)鏈接找到:
https://scratch.mit.edu/projects/282534568/
再給大家分享一個(gè)3D煙花動(dòng)畫(huà),主要也是運(yùn)用了本文介紹的方法制作的3D效果。具體的制作方法有時(shí)間再給大家分享。
https://scratch.mit.edu/projects/282581016/
5.????結(jié)語(yǔ)
今天我們學(xué)習(xí)了基本的3D引擎制作方法。當(dāng)然這是最最基本的3D知識(shí),大家看到,即使是最基本的3D原理,已經(jīng)用到不少的幾何和三角函數(shù)知識(shí)。對(duì)有志于研究最新3D技術(shù)的同學(xué),比如3D游戲、VR(Virtual Reality虛擬現(xiàn)實(shí))、AR(Augmented Reality增強(qiáng)現(xiàn)實(shí))、3D打印等等,請(qǐng)進(jìn)一步打好數(shù)學(xué)和編程基礎(chǔ)。
事實(shí)上3D等圖形顯示技術(shù)屬于一門叫做計(jì)算機(jī)圖形學(xué)的學(xué)科。計(jì)算機(jī)圖形學(xué)可以幫助人腦從圖形圖像的角度理解事物本質(zhì)。在科學(xué)、娛樂(lè)、藝術(shù)、設(shè)計(jì)等領(lǐng)域,計(jì)算機(jī)圖形學(xué)都起著重要的基礎(chǔ)作用。期待有志于此的千里馬學(xué)員以后能創(chuàng)造出一個(gè)又一個(gè)的視覺(jué)奇跡。

聲明:本文章由網(wǎng)友投稿作為教育分享用途,如有侵權(quán)原作者可通過(guò)郵件及時(shí)和我們聯(lián)系刪除
- 上一篇
Scratch第三十一講:自動(dòng)走迷宮
想了解編程技巧,就請(qǐng)點(diǎn)擊上面藍(lán)字:跟我學(xué)Scratch編程,關(guān)注CC哥 前一段時(shí)間大家在討論如何如何自動(dòng)走迷宮的小程序,CC哥也抽時(shí)間做了一個(gè),當(dāng)然細(xì)節(jié)不是很完善,但是可以學(xué)習(xí)一下思路。
- 下一篇
Scratch3.0少兒編程案例:小貓出題
一、案例簡(jiǎn)介 ????小貓正在學(xué)習(xí)加法,他從一個(gè)列表中找到了被加數(shù),在另一個(gè)列表中找到了加 數(shù),于是他把兩個(gè)數(shù)說(shuō)出來(lái),給小伙伴們出了一道加法題。?我們今天就來(lái)用scratch 3.0制作少兒編程案例:小貓出題。讓小貓能夠自動(dòng)出加法數(shù)學(xué)題。
