日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计算机安全原理与实践_《计算机图形学原理及实践》学习笔记之第三章

發(fā)布時(shí)間:2024/9/19 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计算机安全原理与实践_《计算机图形学原理及实践》学习笔记之第三章 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

第三章 一個(gè)古老的繪制器

1525年,阿爾布雷·丟勒 制作了一幅木刻畫,展示了一種可以繪制任一形體透視圖的方法。
本章我們將開發(fā)一個(gè)軟件來模擬丟勒展示的方法。

  • 丟勒視角繪制算法的偽代碼
Input: a scene containing some objects, location of eye-point Output: a drawing of the objectsinitialize drawing to be blank foreach object oforeach visible point P of oOpen shutterPlace pointer at Pif string from P to eye-point touches boundary of frameDo nothingelseHold a pencil at point where string passes through frameHold string asideClose shutter to make pencil-mark on paperRelease string
  • 該算法有三個(gè)方面值得注意,這三個(gè)方面都體現(xiàn)在遍歷所有采樣點(diǎn)的循環(huán)種
    • 該循環(huán)面向的是 可見 采樣點(diǎn),因此,判定采樣點(diǎn)的可見性很重要(對(duì)于人類,一個(gè)點(diǎn)能不能看到,我們的大腦有清除的認(rèn)知,但對(duì)于計(jì)算機(jī),這是需要進(jìn)行判定的)
    • 可能存在無限數(shù)量的可見采樣點(diǎn)
    • 當(dāng)細(xì)線觸碰畫框而不是穿過畫框內(nèi)的空白區(qū)域該如何處理(即物體有一部分超出 顯示界面時(shí))
    • 對(duì)于 第二個(gè)問題,可用使用 逼近 繪制來解決,即選擇有限數(shù)量的采樣點(diǎn),使得在紙上的這些標(biāo)記能夠較好地呈現(xiàn)出物體的外形。關(guān)于這一部分本書后面會(huì)有大量的討論,具體討論在這里先咱暫時(shí)擱置。
    • 對(duì)于 第三個(gè)問題,剔除視域(眼睛或相機(jī)能看見的那一部分世界)外的采樣點(diǎn),這是圖形學(xué)中一個(gè)常見的操作,可以避免將繪制時(shí)間浪費(fèi)在 視域 之外。該操作成為 裁剪。這里我們會(huì)使用一個(gè)非常簡(jiǎn)單的點(diǎn)裁剪版本。
    • 對(duì)于 第一個(gè)問題,即 可見性問題。 根據(jù) 丟勒 所示方法,要確定采樣點(diǎn) P 是否可見,用戶只需要將指針定在 P 點(diǎn),然后觀察細(xì)線是沿著一條直線直達(dá)螺絲釘?shù)目籽?#xff0c;還是途中遇到魯特琴的某處或其它物體而產(chǎn)生了彎折。 即,從 魯特琴上一點(diǎn)出發(fā),向 螺絲釘孔眼(觀察者) 方向射出一道射線,如果射線能夠直達(dá)觀察者,途中沒有接觸其它點(diǎn),則說明 該出發(fā)點(diǎn)對(duì)于觀察者可見。 這里,我們暫時(shí)忽略可見性檢測(cè)。

  • 實(shí)現(xiàn)
    • 設(shè)墻上螺絲釘孔眼作為坐標(biāo)系原點(diǎn),記為E(作為"視點(diǎn)")。
    • 令繪畫的畫框,位于 z = 1 平面上,即觀察者到畫框平面的距離為 一個(gè)單位長(zhǎng)度
    • 記 畫框平面上距離孔眼最近的點(diǎn)為 T;其坐標(biāo)為 (0, 0, 1)
    • 令 y 軸豎直向上, x 軸沿水平方向
    • 平面畫框的范圍由角點(diǎn) ( x m i n y m i n , 1 ) (x_{min} y_{min}, 1)(xmin?ymin?,1)、( x m a x , y m a x , 1 ) (x_{max}, y_{max}, 1)(xmax?,ymax?,1) 定義。這里我們做簡(jiǎn)化處理,設(shè)畫框是一個(gè)正方形,即長(zhǎng)寬相等 x m a x ? x m i n = y m a x ? y m i n x_{max} - x_{min} = y_{max} - y_{min}xmax??xmin?=ymax??ymin?
    • 畫框中畫紙的左下角為記為 ( x m i n , y m i n ) (x_{min}, y_{min})(xmin?,ymin?), 右上角記為 ( x m a x , y m a x ) (x_{max}, y_{max})(xmax?,ymax?)
    • 設(shè)我們正在觀察物體上的點(diǎn) P(x, y, z)
    • 連接 PE 即丟勒模型中的細(xì)線,會(huì)穿過畫紙,設(shè)穿過的該點(diǎn)為 P ‘ = ( x ‘ , y ‘ , z ‘ ) P` = (x`, y`, z`)P‘=(x‘,y‘,z‘)
    • 可以得 z ‘ = 1 z` = 1z‘=1 ,因此 P ‘ P`P‘ 在畫紙上的坐標(biāo)為 ( x ‘ , y ‘ ) (x`, y`)(x‘,y‘)
    • 接下來就是計(jì)算這個(gè) x ‘ , y ‘ x`, y`x‘,y‘

    • 對(duì)于該問題,我們可以用相似三角形進(jìn)行求解。因?yàn)?z ‘ = 1 z` = 1z‘=1 這一條件,就很好求解了。

    • 得出:

frac{x`} {x} = frac{z`} {z}
frac{y`} {y} = frac{z`} {z}

    • 因 z` = 1 得:

x` = frac{x} {z}
y` = frac{y} {z}

    • 這樣即可得到 P` 的坐標(biāo)
    • 丟勒繪制算法的一個(gè)簡(jiǎn)單實(shí)現(xiàn)版本

Input: a scene cotaining some objects Output: a drawing of the objects initialize drawing to be blank foreach object o foreach visible point P = (x, y ,z) of o if(x_min <= (x/z) <= x_max and y_min <= (y/z) <= y_max) make a point on the drawing at location (x/z, y/z)

    • 為了和我們后面將采取的更一般性的方法一致。這里,我們默認(rèn) x軸正向是朝左的,現(xiàn)在我們要讓 x軸 反過來,即讓 x軸正向朝右,那么代碼中的結(jié)果 x 就要加個(gè) 負(fù)號(hào)

if(x_min <= (x/z) <= x_max and y_min <= (y/z) <= y_max) make a point on the drawing at location (-x/z, y/z)


  • 繪圖
  • 接下來繪制一個(gè)立方體,立方體有 8個(gè) 頂點(diǎn),給出它們的模型坐標(biāo)
索引坐標(biāo)
0
1
2
3
4
5
6
7
(-0.5, -0.5, -0.5)
(-0.5, 0.5, -0.5)
(0.5, 0.5, -0.5)
(0.5, -0.5, -0.5)
(-0.5, -0.5, 0.5)
(-0.5, 0.5, 0.51)
(0.5, 0.5, 0.5)
(0.5, -0.5, 0.5)
  • 需要注意的是,我們的視點(diǎn)是(0, 0, 0),那么這樣,這個(gè)立方體就包裹了視點(diǎn),因此,我們讓立方體在 z 軸方向移動(dòng)三個(gè)單位,即 立方體所有坐標(biāo)的 z += 3
  • 接下來 根據(jù) 丟勒的繪制算法,我們需要在立方體表面采樣大量的點(diǎn)來進(jìn)行繪制。但實(shí)際上這是不必要的。
    • 若 A、B 是一條邊的兩個(gè)端點(diǎn),我們將 A 和 B 映射到圖紙上的 A ‘ A`A‘ 和 B ‘ B`B‘ ,可以發(fā)現(xiàn) A 和 B 之間的點(diǎn),也都映射到了 A ‘ A`A‘ 和 B ‘ B`B‘ 的連線上。這一點(diǎn)是可以幾何證明出來的。
    • 而立方體屬于 線框模型,即可以用幾個(gè)頂點(diǎn) 和 頂點(diǎn)之間的連線得到的邊 來進(jìn)行描述。那么實(shí)際上,我們只需要繪制出 立方體的頂點(diǎn),然后進(jìn)行連線即可。
  • 需要注意的是,空間中的直線 其在平面上的投影 不一定為 直線,如果該直線穿過了 投影中心 (螺絲孔眼/觀察者),則其在平面上的投影是一個(gè)點(diǎn),我們認(rèn)為其是無意義的。
  • 現(xiàn)在給立方體模型添加一個(gè) 邊表,每條邊用兩端點(diǎn)的點(diǎn)的索引表示:
索引端點(diǎn)
0
1
2
3
4
5
6
7
8
9
10
11
(0, 1)
(1, 2)
(2, 3)
(3, 0)
(0, 4)
(1, 5)
(2, 6)
(3, 7)
(4, 5)
(5, 6)
(6, 7)
(7, 4)
  • 繪制線段時(shí)會(huì)面臨兩個(gè)選擇
    • 是逐條邊進(jìn)行迭代,對(duì)每一條邊,分別計(jì)算它們端點(diǎn)的投影位置,再將這兩個(gè)投影點(diǎn)連接在一起。
    • 還是先遍歷每一個(gè)頂點(diǎn),計(jì)算各頂點(diǎn)的投影點(diǎn),然后再基于計(jì)算得到的投影點(diǎn)逐邊進(jìn)行迭代。
    • 由于每個(gè)頂點(diǎn)由三條邊共享,對(duì)于第一個(gè)選擇 每個(gè)頂點(diǎn)需要計(jì)算 三次
    • 而第二個(gè)選擇則需要對(duì)數(shù)據(jù)進(jìn)行重復(fù)訪問
    • 這兩種選擇取決于任務(wù)是在 硬件上實(shí)現(xiàn) 還是 軟件上實(shí)現(xiàn),對(duì)此會(huì)在后面的章節(jié)進(jìn)行討論。 我們當(dāng)前選擇 第二個(gè)選擇。
  • 之后我們還要思考裁剪問題,在投影后,一條邊的一個(gè)端點(diǎn)可能會(huì)在圖紙內(nèi),而另一個(gè)則可能跑到圖紙外了。對(duì)于這種情況,這里我們暫時(shí)不作討論,我們現(xiàn)在認(rèn)為 畫框外的部分不會(huì)被繪制(對(duì)于 WPF 而言 確實(shí)是這樣)
  • 給出此時(shí)的偽代碼:
Input: a scene containing one object ob Output: a drawing of the objectsinitialize drawing to be blank; for (int i = 0; i < number of vertices in ob; i++) {Point3D P = vertices[i];pictureVertices[i] = Point(-P.x/P.z, P.y/P.z) } for(int i = 0; i < number of edges in ob; i++) {int i0 = edges[i][0];int i1 = edges[i][1];Draw a line segment from pictureVertices[10] to pictureVertices[i1]; }
  • 最后還需要注意程序所繪圖形顯示在 ”矩形窗口“ 之內(nèi),而窗口的坐標(biāo)從 ( x m i n , y m i n ) (x_{min}, y_{min})(xmin?,ymin?) 到 ( x m a x , y m a x ) (x_{max}, y_{max})(xmax?,ymax?)。
    • 我們可以去除這一坐標(biāo)區(qū)間的限制。而采用在圖形庫中常用的、在 x 和 y 兩個(gè)方向上均為 0~1 的區(qū)間??砂聪旅娴姆椒?對(duì) x 坐標(biāo)進(jìn)行轉(zhuǎn)換
      • 首先將 x 坐標(biāo) 減去 x m i n x_{min}xmin?,這樣新的坐標(biāo)將位于 0 ~ x m a x ? x m i n x_{max} - x_{min}xmax??xmin? 的范圍,再讓它除以 x m a x ? x m i n x_{max} - x_{min}xmax??xmin? 新的 x 坐標(biāo)就映射到 0~1 范圍了。

x_{new} = frac {x - x_{min}} {x_{max} - x_{min}}

      • y 坐標(biāo)同理
      • 但之前為了讓畫面右側(cè)方向?qū)?yīng)場(chǎng)景 x 坐標(biāo)增加方向,我們改變了 x 的符號(hào)。那么 x 重映射后其實(shí)是 -1 ~ 0 范圍,因此我們還要讓新的 x + 1
      • 這些位于 0~1 范圍的坐標(biāo)常稱為 標(biāo)準(zhǔn)化的設(shè)備坐標(biāo):它們給出了顯示設(shè)備從左到右、從上到下的取值范圍。
        • 對(duì)一個(gè)典型的顯示器而言,其豎直方向坐標(biāo)的取值范圍值常為 0~1,而水平方向坐標(biāo)的取值范圍則為 0~1.33
      • 這一標(biāo)準(zhǔn)化處理公式需要記住
  • 給出偽代碼:
Input: a scene containing one object ob Output: a drawing of the objectsinitialize drawing to be blank; for (int i = 0; i < number of vertices in ob; i++) {Point3D P = vertices[i];double x = P.x / P.z;double y = P.y / P,z;pictureVertices[i] = Point(1 - (x - x_min) / (x_max - x_min),(y - y_min) / (y_max - y_min)); } for(int i = 0; i < number of edges in ob; i++) {int i0 = edges[i][0];int i1 = edges[i][1];Draw a line segment from pictureVertices[10] to pictureVertices[i1]; }
  • 程序
    我們將使用一個(gè)簡(jiǎn)單的 WPF 程序來實(shí)現(xiàn)該算法。
public partial class MainWindow : Window{public MainWindow(){InitializeComponent();Canvas gp = this.FindName("Paper") as Canvas;double[,] vtable ={{-0.5, -0.5, 2.5 },{-0.5, 0.5, 2.5 },{0.5, 0.5, 2.5 },{0.5, -0.5, 2.5 },{-0.5, -0.5, 3.5 },{-0.5, 0.5, 3.5 },{0.5, 0.5, 3.5 },{0.5, -0.5, 3.5 }};int[,] etable ={{0, 1 },{1, 2 },{2, 3 },{3, 0 },{0, 4 },{1, 5 },{2, 6 },{3, 7 },{4, 5 },{5, 6 },{6, 7 },{7, 4 }};Point[] pictureVertices = new Point[vtable.Length];double x_min = -0.5;double xSpace = 1;double y_min = -0.5;double ySpace = 1;double scale = 100;for(int i = 0; i < vtable.GetLength(0); ++i){double x = vtable[i, 0];double y = vtable[i, 1];double z = vtable[i, 2];x /= z;y /= z;x = scale * (1 - (x - x_min) / xSpace);y = scale * (y - y_min) / ySpace;pictureVertices[i] = new Point(x, y);gp.Children.Add(new Dot(pictureVertices[i]));}for(int i = 0; i < etable.GetLength(0); ++i){int i0 = etable[i, 0];int i1 = etable[i, 1];gp.Children.Add(new Segment(pictureVertices[i0], pictureVertices[i1]));}}}
  • 書中給出的 C# 代碼還是為了讓讀者理解這一章討論的投射算法。里面的 Dot、Segament 需要自實(shí)現(xiàn),可以在 http://cgpp.net 即本書官網(wǎng)下載。


  • 局限性
  • 顯然我們這里的代碼非常簡(jiǎn)單,且無法應(yīng)用于更廣泛 和 更高級(jí)的場(chǎng)景中。
    • 例如如果立方體每個(gè)面有不同的顏色,這里我們只是把邊繪制了出來,無法繪制立方體面的顏色
    • 我們這里也沒有對(duì)光進(jìn)行模擬。我們能看到物體正是因?yàn)楣鈴奈矬w表面射入了我們的眼睛。
    • 我們對(duì)于模型數(shù)據(jù)的表示缺乏通用性。我們可以將建模數(shù)據(jù)存入一個(gè)可被程序讀取的文件,該文件具有規(guī)范的格式。例如該文件中存儲(chǔ)的 先是頂點(diǎn)的數(shù)目,跟著一個(gè)訂點(diǎn)表,然后是邊的數(shù)目 跟著一個(gè)邊表。

練習(xí)

假設(shè)在丟勒木刻畫中,不僅標(biāo)記了點(diǎn),還在點(diǎn)附近標(biāo)記了細(xì)線另一端砝碼距離地面的高度。該數(shù)字即為視點(diǎn)距離采樣點(diǎn)的距離。如果 魯特琴被帶走了,而又想在畫中畫一盞燈,且燈在魯特琴的前面,那么我們就可以根據(jù)之前標(biāo)記的距離,來把燈合成到原本的畫中。
這類似于 基于深度的畫面合成,其是 z-buffer 的許多應(yīng)用之一。
在每個(gè)采樣點(diǎn)處記錄的深度值類似于在 z-buufer 中存儲(chǔ)的值,盡管并非同一值。

可以使用點(diǎn)的索引來表示面,稱為 索引面集,我們用 ( P 0 , P 1 , P 2 , . . . ) (P_0, P_1, P_2, ...)(P0?,P1?,P2?,...) 來表示一個(gè)面。對(duì)于立方體而言,我們可以用 ( P 2 ? P 1 ) × ( P 1 ? P 0 ) (P_2- P_1) × (P_1 - P_0)(P2??P1?)×(P1??P0?) 來表示該面的法向量,請(qǐng)構(gòu)建立方體的 索引面集,使得每個(gè)面的法向量都朝外。

畫個(gè)三棱柱
我們只需要修改傳入的 點(diǎn)集 和 邊集 即可

總結(jié)

以上是生活随笔為你收集整理的计算机安全原理与实践_《计算机图形学原理及实践》学习笔记之第三章的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 免费看的一级片 | 黄色av网址大全 | 黄视频网站在线看 | 理论片琪琪午夜电影 | 麻豆三级视频 | 国产高潮流白浆喷水视频 | 日日夜夜狠狠爱 | 国产女主播一区二区 | 国产精品尤物视频 | 狠狠噜噜 | 亚洲欧美日韩国产成人精品影院 | 欧美第一视频 | 日日噜噜夜夜狠狠久久丁香五月 | aa一级片| 欧美激情久久久久久久 | 超碰666| 少妇人妻偷人精品无码视频 | 韩国av免费在线观看 | 国产性猛交xx乱 | 看黄免费网站 | 性欧美高清 | 成人a站 | 无码国产色欲xxxx视频 | 一本大道东京热无码 | 国产日韩欧美在线播放 | 一区二区在线精品 | 久久网站免费 | 欧美视频精品 | 91亚州| 久久精品无码毛片 | 亚洲精品小视频在线观看 | 日日干天天爽 | 亚洲视频99 | 国产一区二区三区四区五区 | 亚洲午夜精选 | 国产欧美日本 | 亚洲一区二区三区 | 天天上天天干 | 操操操爽爽爽 | 日韩中文字幕一区二区三区 | 波多野结衣家庭主妇 | 麻豆人妻少妇精品无码专区 | 欧美精品色视频 | 国产又黄又猛又粗 | 女性裸体视频网站 | 日本午夜精品理论片a级app发布 | 日日草视频| 一级做a爰片久久毛片 | 成年人在线观看视频网站 | xxxx视频在线观看 | 在线色站| 欧美成人一区二区三区四区 | 久久狠狠干 | 日韩精品久久久久久久电影99爱 | 国产精品久久久久久久妇 | 伊人在线视频 | 美国少妇在线观看免费 | 蜜桃视频在线观看污 | 国产激情文学 | 黄色大片毛片 | 欧美高清性xxxxhdvideosex | 婷婷开心激情 | 黄色高清视频 | 久久久精品在线观看 | 69久久夜色精品国产69 | 黄色日批 | 免费中文字幕视频 | 狠狠干女人| 亚洲精品国产乱伦 | 国产乱色 | 日韩成人中文字幕 | 国产+日韩+欧美 | 亚洲精品视频免费观看 | 亚洲欧洲精品在线 | 99在线精品观看 | 韩国久久久| 日韩中文字幕在线视频 | 欧美性视频网站 | av中文字幕亚洲 | 性激情视频 | 超爽视频| 五月花婷婷 | a爱视频 | 精品国产一区二区三区四区精华 | 双性懵懂美人被强制调教 | 国产又粗又深又猛又爽又在线观看 | 高h奶汁双性受1v1 | 噜噜噜久久 | 日本www高清视频 | 国产精品自产拍在线观看 | 日本裸体视频 | 4438全国最大成人网 | 无码人妻aⅴ一区二区三区有奶水 | 欧美激情三区 | 精品欧美一区二区三区久久久 | 99re视频在线观看 | 香港三级在线视频 | 乱色专区 | 毛片在线免费观看网站 |