|
無論是2D或是3D繪製,頂點的使用是一個重要的課題,頂點的使用與座標息息相關,這也就是為何之前一直在談論座標系統的原因。
頂點的記錄方式有許多種,不同的繪圖目的應搭配不同的頂點資料結構,這邊介紹最簡單的幾個立體物件頂點記錄方式。
假設有一個正立方體,其中心位於原點,則可以如下圖先定出頂點的座標:

紙上作業與程式規劃所不同的是,如何使用這些頂點來繪製一個立方體,基本上必須以四個頂點為一個單位,使用繪製多邊型的函式來繪製一個四邊形,然後以較方
便的方式選擇四個頂點,通常會使用迴圈,但為了能使用迴圈,頂點資料結構必須有可重複索引的性質,在這邊介紹兩種規劃方式。
其中一個規劃方式是使用6*4=24個元素的陣列,每個面使用掉四個頂點,如下圖所示:

如此就可以使用迴圈取出頂點資訊,這個方法的好處是簡單,但由於頂點會有重複,因而會耗用大量的記憶體,對於複雜圖形並不適用。
可以使用頂點索引來解決頂點重複的問題,首先必須先將頂點編號,如下圖所示:

通常為了具有判別法向量的作用,頂點編號時使用右手定則,以逆時針的順序來編號同一個面的頂點;頂點編號完畢後,使用一個頂點索引陣列來記錄每個面所使用到的頂點編號,如下所示:
int v_ord[][] = {{0, 1, 2, 3}, {0, 7, 6, 1}, {4, 5, 6, 7},
{2, 5, 4, 3}, {0, 3, 4, 7}, {1, 6, 5, 2}};
使用索引陣列的好處是減少記憶體使用量,雖然額外使用了一個索引陣列,但對於頂點越多時,記憶體的減少使用會更顯著,但缺點就是必須額外耗用一些運算是處理頂點資訊。
下面是使用頂點索引陣列來繪製正立方體的Java Applet程式,您可以參考我們是如何處理頂點資訊的:
import java.awt.*; import java.applet.*; import java.awt.event.*; class Point3D { public int x, y, z; public Point3D() { x = y = z = 0; } public Point3D(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } } public class Vetex extends Applet { public void paint(Graphics g) { final int r = 100; // 索引array int v_ord[][] = {{0, 1, 2, 3}, {0, 7, 6, 1}, {4, 5, 6, 7}, {2, 5, 4, 3}, {0, 3, 4, 7}, {1, 6, 5, 2}}; // 立方體頂點 Point3D[] vetex = {new Point3D(r, r, r), new Point3D(r, -r, r), new Point3D(r, -r, -r), new Point3D(r, r, -r), new Point3D(-r, r, -r), new Point3D(-r, -r, -r), new Point3D(-r, -r, r), new Point3D(-r, r, r)}; Point3D[] tp = new Point3D[4]; // 視窗中心 final int orgX = (int)getSize().width / 2, orgY = (int)getSize().height / 2; final double rd = Math.PI / 180; double ax, ay; int[] px = new int[4], py = new int[4]; int i, j, k; // 旋轉以斜角繪製圖形 ax = 30 * rd; ay = -30 * rd; setBackground(Color.black); g.setColor(Color.yellow); for(i = 0; i < 6; i++) { for(j = 0; j < 4; j++) { // 利用索引array取出正確的頂點 tp[j] = vetex[v_ord[i][j]]; // 旋轉以斜角繪製圖形 px[j] = (int) (tp[j].x*Math.cos(ay) + tp[j].z*Math.sin(ay)); py[j] = (int) (tp[j].y*Math.cos(ax) - (-tp[j].x*Math.sin(ay) + tp[j].z*Math.cos(ay)) * Math.sin(ax)); px[j] = px[j] + orgX; py[j] = -py[j] + orgY; } g.drawPolyline(px, py, 4); } } }
如果您使用3D函式庫時,通常可以自行選擇使用哪一種頂點記錄方式,而且包裝成物件之後,您也無須親自處理索引的細節。
 |