vetexarray.htm

来自「电脑图学(Computer Graphics)是资料结构、演算法与数学的应用」· HTM 代码 · 共 151 行

HTM
151
字号
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>






  
  
  
  
  
  
  <link rel="stylesheet" href="css/stdlayout.css" type="text/css">






  
  
  
  
  
  
  <link rel="stylesheet" href="css/print.css" type="text/css">






  
  
  
  
  
  
  <meta content="text/html; charset=gb2312" http-equiv="content-type">






  
  
  
  
  
  
  <title>顶点索引阵列</title>
</head>


<body>






<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>






<h1><a href="ComputerGraphics.htm">Computer Graphics: 顶点索引阵列</a></h1>






无论是2D或是3D绘制,顶点的使用是一个重要的课题,顶点的使用与座标息息相关,这也就是为何之前一直在谈论座标系统的原因。<br>
<br>
顶点的记录方式有许多种,不同的绘图目的应搭配不同的顶点资料结构,这边介绍最简单的几个立体物件顶点记录方式。<br>
<br>
假设有一个正立方体,其中心位于原点,则可以如下图先定出顶点的座标: <br>






<img style="width: 394px; height: 232px;" alt="" src="images/vetexArray-1.jpg"><br>






<br>







纸上作业与程式规划所不同的是,如何使用这些顶点来绘制一个立方体,基本上必须以四个顶点为一个单位,使用绘制多边型的函式来绘制一个四边形,然后以较方
便的方式选择四个顶点,通常会使用回圈,但为了能使用回圈,顶点资料结构必须有可重复索引的性质,在这边介绍两种规划方式。<br>
<br>
其中一个规划方式是使用6*4=24个元素的阵列,每个面使用掉四个顶点,如下图所示: <br>






<span class="postbody"></span><img style="width: 542px; height: 404px;" alt="" src="images/vetexArray-2.jpg"><br>
<br>
如此就可以使用回圈取出顶点资讯,这个方法的好处是简单,但由于顶点会有重复,因而会耗用大量的记忆体,对于复杂图形并不适用。<br>
<br>
可以使用顶点索引来解决顶点重复的问题,首先必须先将顶点编号,如下图所示: <br>
<img style="width: 240px; height: 190px;" alt="" src="images/vetexArray-3.jpg"><br>
<br>
通常为了具有判别法向量的作用,顶点编号时使用右手定则,以逆时针的顺序来编号同一个面的顶点;顶点编号完毕后,使用一个顶点索引阵列来记录每个面所使用到的顶点编号,如下所示:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int v_ord[][] = {{0, 1, 2, 3}, {0, 7, 6, 1}, {4, 5, 6, 7},</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{2, 5, 4, 3}, {0, 3, 4, 7}, {1, 6, 5, 2}};</span><br>
</div>
&nbsp;<br>
<br>
使用索引阵列的好处是减少记忆体使用量,虽然额外使用了一个索引阵列,但对于顶点越多时,记忆体的减少使用会更显著,但缺点就是必须额外耗用一些运算是处理顶点资讯。<br>
<br>
下面是使用顶点索引阵列来绘制正立方体的Java Applet程式,您可以参考我们是如何处理顶点资讯的:<br>
<ul>
  <li> Vetex.java</li>
</ul>
<pre>import java.awt.*;<br>import java.applet.*;<br>import java.awt.event.*;<br> <br>class Point3D {<br>   public int x, y, z;<br> <br>   public Point3D() {<br>      x = y = z = 0;<br>   }<br> <br>   public Point3D(int x, int y, int z) {<br>      this.x = x;<br>      this.y = y;<br>      this.z = z;<br>   }<br>}<br> <br>public class Vetex extends Applet {<br>    public void paint(Graphics g) {<br>    final int r = 100;<br> <br>    // 索引array<br>    int v_ord[][] = <br>          {{0, 1, 2, 3}, {0, 7, 6, 1}, {4, 5, 6, 7},<br>           {2, 5, 4, 3}, {0, 3, 4, 7}, {1, 6, 5, 2}};<br> <br>    // 立方体顶点<br>    Point3D[] vetex = <br>            {new Point3D(r, r, r), new Point3D(r, -r, r),<br>             new Point3D(r, -r, -r), new Point3D(r, r, -r),<br>             new Point3D(-r, r, -r), new Point3D(-r, -r, -r),<br>             new Point3D(-r, -r, r), new Point3D(-r, r, r)};<br> <br>    Point3D[] tp = new Point3D[4];<br> <br>    // 视窗中心<br>    final int orgX = (int)getSize().width / 2,<br>              orgY = (int)getSize().height / 2;<br>    final double rd = Math.PI / 180;<br>    double ax, ay;<br> <br>    int[] px = new int[4],<br>          py = new int[4];<br> <br>        int i, j, k;<br>  <br>        // 旋转以斜角绘制图形<br>        ax = 30 * rd;<br>        ay = -30 * rd;<br> <br>        setBackground(Color.black);<br>        g.setColor(Color.yellow);<br> <br>        for(i = 0; i &lt; 6; i++) {<br>            for(j = 0; j &lt; 4; j++) {<br>                // 利用索引array取出正确的顶点<br>                tp[j] = vetex[v_ord[i][j]];<br> <br>                // 旋转以斜角绘制图形<br>                px[j] = (int) (tp[j].x*Math.cos(ay) <br>                               + tp[j].z*Math.sin(ay));<br>                py[j] = (int) (tp[j].y*Math.cos(ax) <br>                               - (-tp[j].x*Math.sin(ay)<br>                     + tp[j].z*Math.cos(ay)) * Math.sin(ax));<br>                px[j] = px[j] + orgX;<br>                py[j] = -py[j] + orgY;<br>            }<br>            g.drawPolyline(px, py, 4);<br>        }<br>    }<br>}</pre>
<br>
如果您使用3D函式库时,通常可以自行选择使用哪一种顶点记录方式,而且包装成物件之后,您也无须亲自处理索引的细节。<br>
<br>
<img style="width: 600px; height: 453px;" alt="" src="images/vetexArray-4.jpg"><br>
<br>






</body>
</html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?