Chinaunix首页 | 论坛 | 博客
  • 博客访问: 143043
  • 博文数量: 30
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 300
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-07 10:53
文章分类

全部博文(30)

文章存档

2009年(1)

2008年(29)

我的朋友

分类:

2008-04-14 09:00:23

一些有规则性的立体图形,可以使用几个简单的变量,并透过运算来产生立体图形的所有顶点,正多面体正是这么样的图形,只有一个变数就可以定出所有的座标点。

如果将正多面体装入一个刚好可以容纳它的球体中,则正多面体的每一个顶点都会位于球壳上,且每个棱边长是相等的。正多面体又称“柏拉图多面体”,因为希腊哲学家柏拉图发现,在三维空间中,最多就只有五种正多面体:正四面体、正六面体、正八面体、正十二面体与正二十面体。

如何使用一个变数来指定正多面体的所有顶点呢?先将正多面体的中心置于原点,然后将其中一个顶点置于Y轴上,也就是(0, r, 0),其中从中心至顶点的距离,也就是可以容纳正多面体的球半径,将由Y轴上顶点延伸出来的錂线取出与錂线相接的顶点,再由这些顶点求出对称原点的另一端顶点,如此就可以求出所有的顶点。

正四面体、正六面体、正十二面体单一顶点延伸出来的錂线有三条,而正八面体有四条,正二十面体有五条。


正四面体
有一正四面体其中心在原点,如下所示:


由顶点(0, r, 0)所延伸出来的錂线有三条,为了计算方便,将两个顶点置于同一XY平面上,所以錂线所接的各顶点经计算后如下所示:

由于正四面体只有四个顶点,所以此时所有的顶点已被订出,正四面体每个面的顶点数为三,配合顶点索引阵列,可以使用以下的程式来订出所有的面:

double sq2 = Math.sqrt(2.0), sq3 = Math.sqrt(3.0);
Vt[0] = new Point3D(0, r, 0);
Vt[1] = new Point3D(0, -r/3, r*2*sq2/3);
Vt[2] = new Point3D(r*sq2/sq3, -r/3, -r*sq2/3);
Vt[3] = new Point3D(-r*sq2/sq3, -r/3, -r*sq2/3);
 
int[][] ord = {{0, 1, 2}, {0, 2, 3}, {0, 3, 1}, {1, 3, 2}};

正六面体
有一正六面体其中心在原点,如下所示:

由顶点(0, r, 0)所延伸出来的錂线有三条,为了计算方便,将两个顶点置于同一XY平面上,所以錂线所接的各顶点经计算后如下所示:


其它未定出的顶点皆以原点对称于这四个顶点,对称于原点其实就是将(x, y, z)都乘上负号,假设有个方法是minus()是进行这项工作,则其它顶点的计算及面的索引阵列如下所示,其中NVt表示顶点数,对正六面体而言是8:

double sq2 = Math.sqrt(2.0), sq3 = Math.sqrt(3.0);
Vt[0] = new Point3D(0, r, 0);
Vt[1] = new Point3D(0, r/3, r*2*sq2/3);
Vt[2] = new Point3D(r*sq2/sq3, r/3, -r*sq2/3);
Vt[3] = new Point3D(-r*sq2/sq3, r/3, -r*sq2/3);
 
for(int i = 0; i < NVt; i++)
    Vt[NVt/2+i] = minus(Vt[i]);

int[][] ord = {{0, 1, 7, 2}, {0, 2, 5, 3}, {0, 3, 6, 1},
               {4, 6, 3, 5}, {4, 7, 1, 6}, {4, 5, 2, 7}};

正八面体
依以上同样的道理,可以定出正八面体的一组基本顶点,不过正八面体的中心的三个顶点可以调整至XYZ三轴上,如下所示:


正八面体的顶点配置方式与顶点索引阵列,提供以下的程式作参考,其中NVt?表示顶点数,对正八面体而言是6:

Vt[0] = new Point3D(0, r, 0);
Vt[1] = new Point3D(0, 0, r);
Vt[2] = new Point3D(r, 0, 0);
 
for(int i = 0; i < NVt; i++)
    Vt[NVt/2+i] = minus(Vt[i]);
 
int[][] ord = {{0, 1, 2}, {0, 2, 4}, {0, 4, 5}, {0, 5, 1},
               {3, 5, 4}, {3, 1, 5}, {3, 2, 1}, {3, 4, 2}};

正十二面体
下图为正十二面体的图形:


正十二面体的对称顶点有十对,顶点配置与顶点索引阵列如下所示,其中NVt表示顶点数,对正十二面体而言是20:

double sq3=Math.sqrt(3.0),sq5=Math.sqrt(5.0);
 Vt[0] = new PointD3(0,r,0);
 Vt[1] = new PointD3(0,r*sq5/3,r*2/3);
 Vt[2] = new PointD3(r*sq3/3,r*sq5/3,-r/3);
 Vt[3] = new PointD3(-r*sq3/3,r*sq5/3,-r/3);
 Vt[4] = new PointD3(r*sq3/3,r/3,r*sq5/3);
 Vt[5] = new PointD3(r*t1*sq3/3,r/3,r*t2*t2/3);
 Vt[6] = new PointD3(r*t2*sq3/3,r/3,-r*t1*t1/3);
 Vt[7] = new PointD3(-r*t2*sq3/3,r/3,-r*t1*t1/3);
 Vt[8] = new PointD3(-r*t1*sq3/3,r/3,r*t2*t2/3);
 Vt[9] = new PointD3(-r*sq3/3,r/3,r*sq5/3);
 for(int i = 0; i < NVt/2; i++)
    Vt[NVt/2+i] = minus(Vt[i]);
 
 int[][]ord =
         {{ 0, 1, 4, 5, 2},{ 0, 2, 6, 7, 3},{ 0, 3, 8, 9, 1},
         { 1, 9,16,17, 4},{ 2, 5,18,19, 6},{ 3, 7,14,15, 8},
         {10,12,15,14,11},{10,13,17,16,12},{10,11,19,18,13},
         {11,14, 7, 6,19},{12,16, 9, 8,15},{13,18, 5, 4,17}};

正二十面体
下图为正二十面体的图形:


正二十面体的对称顶点有六对,顶点配置与顶点索引阵列如下所示,其中NVt表示顶点数,对正二十面体而言是12:

double sq5=Math.sqrt(5.0);
 double t1 = (sq5+1)/2, t2 = (sq5-1)/2;
 Vt[0] = new PointD3(0,r,0);
 Vt[1] = new PointD3(0,r/sq5,r*2/sq5);
 Vt[2] = new PointD3(r*Math.sqrt(t1/sq5),r/sq5,r*t2/sq5);
 Vt[3] = new PointD3(r*Math.sqrt(t2/sq5),r/sq5,-r*t1/sq5);
 Vt[4] = new PointD3(-r*Math.sqrt(t2/sq5),r/sq5,-r*t1/sq5);
 Vt[5] = new PointD3(-r*Math.sqrt(t1/sq5),r/sq5,r*t2/sq5);
 for(int i = 0; i<NVt/2; i++)
    Vt[NVt/2+i] = minus(Vt[i]);
 
 int[][]ord =
          {{0, 1,2},{0, 2,3},{0, 3,4},{ 0, 4, 5},{ 0,5, 1},
           {1,10,2},{2,11,3},{3, 7,4},{ 4, 8, 5},{ 5,9, 1},
           {6, 8,7},{6, 9,8},{6,10,9},{ 6,11,10},{ 6,7,11},
           {7, 8,4},{8, 9,5},{9,10,1},{10,11, 2},{11,7, 3}};

由以上,只要一个变数r,就可以订出所有的正多面体顶点,当然所牺牲的就是一些运算时间了。

阅读(1418) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~