随笔 - 32  文章 - 94  trackbacks - 0
<2009年8月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
303112345

常用链接

留言簿(8)

随笔分类

随笔档案

好友连接

搜索

  •  

最新评论

阅读排行榜

评论排行榜

以前还在学校时,有过强烈的目睹高维物体的愿望,也想自己实现一个4维立方体试试,于是先在网络上到处找n维立方体有关的展示视频,在youtobe上发现了不少,一看就是一整天,结果第二天有别的事情,干别的事去了,当时连规律都没有找,想法就此结束。

今天突然又有了兴致,于是决定好好分析一番。


从最基本开始,点,我们容易推出,0维到n维,超立方体的点数是2的n次方。

另外还容易推出:每增加一维,就会诞生新的空间概念,例如,0维只有点的空间概念,1维诞生了线,2维诞生了面,3维诞生了体,4维诞生了4维体.......
并且新空间概念的定义都是由上一个概念往新的维度拉伸产生的。

而比较难推出的关键一点就是:往新的维度拉伸的时侯,已有的某个概念增加的数量=原来的数量*2+低一级的概念的数量。例如,2维往3维拉伸正方形时,面数量即立方体的面数=正方形的面数*2+正方形线的数量;立方体线数=正方形线数*2+正方形点的数量

证明方法,比较严密的方法还想不出,不过很容易想到:往新的维度拉伸时,拉伸的起点和终点使某空间概念的数量拷贝了一份,另外拉伸时,比该空间概念底一级的空间概念拉伸产生了该空间概念。

这个说得比较抽象,具体公式可以由下面的图表示出:


有了这些概念后,可以编程出一些内容了~~~
由于在OpenGL中体是用面包装起来表示的,因此我们必须找出n维立方体中点、线、面之间的规律,至于更高一层概念的规律可以暂时不理了。先给出一个还不完整类声明:

 1#pragma once
 2#include "mainWindowStyle.h"
 3
 4class CSuperCube:public CY_Screen
 5{
 6    //-----------------------------------------------------------
 7    int MaxDim;//维度数量
 8    int *PointsCount;
 9    int *LinesCount;
10    int *FaceCount;
11    //-----------------------------------------------------------
12
13    float Length;//边长
14    //-----------------------------------------------------------------------------------------
15    bool isDone;//已经可以渲染的标志
16
17    float *Points;//n维空间中的点(以DimensionNum为一组为一个点坐标,PointNum为点数量,所以该float数组大小为DimensionNum*PointNum)
18    int    DimensionNum;
19    int PointNum;
20
21    struct SLine
22    {
23        float *points1;
24        float *points2;
25        SLine()
26        {
27            points1=0;
28            points2=0;
29        }

30    }
;
31    SLine *Lines;//n维空间中的线(以2个点的x坐标索引为起始)
32    int LineNum;
33
34    struct SFace
35    {
36        float *points1;
37        float *points2;
38        float *points3;
39        float *points4;
40        SFace()
41        {
42            points1=0;
43            points2=0;
44            points3=0;
45            points4=0;
46        }

47    }
;
48    int FaceNum;
49    SFace *Faces;//n维空间中的面
50    //---------------------------------------------------------------------------------------------
51
52
53    void CaculatePHelp(int currentDim);
54    void CaculateLHelp(int currentDim);
55    void CaculateFHelp(int currentDim);
56    inline int PtAtIndex(int i)const
57    {
58        return i*DimensionNum;
59    }

60public:
61    CY_TextBox *DimensionInput;
62    
63
64    CY_Button  *CreateBtn;
65
66    //初始化各个维度的立方体中,点、线、面的数量
67    //输入:maxDim最大维数
68    void InitMaxPLF(int maxDim);
69
70    //计算Dim维度下的立方体的点、线、面分布
71    void CaculatePLF(int Dim);
72}
;


初始化点、线、面在各个维度立方体中的数量:其中maxDim表示最大维度,一般设一个小于16的值,

 1void CSuperCube::InitMaxPLF(int maxDim)
 2{
 3    if (MaxDim || maxDim<3)
 4        return;
 5    
 6    MaxDim=maxDim+1;
 7
 8    PointsCount=new int[MaxDim];
 9    LinesCount=new int[MaxDim];
10    FaceCount=new int[MaxDim];
11
12    int i;
13
14    PointsCount[0]=1;
15    for (i=1;i<MaxDim;++i)
16        PointsCount[i]=PointsCount[i-1]*2;
17
18    LinesCount[0]=0;
19    LinesCount[1]=1;
20    for (i=2;i<MaxDim;++i)
21        LinesCount[i]=LinesCount[i-1]*2+PointsCount[i-1];
22
23    FaceCount[0]=0;
24    FaceCount[1]=0;
25    FaceCount[2]=1;
26    for(i=3;i<MaxDim;++i)
27        FaceCount[i]=FaceCount[i-1]*2+LinesCount[i-1];
28}

下一步开始定位在Dim维空间中点、线、面的分布:
 1void CSuperCube::CaculatePLF(int Dim)
 2{
 3    if(!MaxDim || Dim<2 || Dim>=MaxDim)return;
 4
 5    if(isDone)
 6    {
 7        delete []Points;
 8        delete []Lines;
 9        delete []Faces;
10    }

11    
12    //-------------------------------------分配好内存空间
13    DimensionNum=Dim;
14    PointNum=PointsCount[DimensionNum];
15    LineNum=LinesCount[DimensionNum];
16    FaceNum=FaceCount[DimensionNum];
17
18    Points=new float[PointNum*DimensionNum];
19    for (int i=0;i<PointNum*DimensionNum;++i)
20    {
21        Points[i]=0;
22    }

23    
24    Lines=new SLine[LineNum];
25    Faces=new SFace[FaceNum];
26
27    //-------------------------------------计算值
28    int currentDim=0;
29    while (currentDim<=DimensionNum)
30    {
31        CaculatePHelp(currentDim);
32        //CaculateLHelp(currentDim);
33        //CaculateFHelp(currentDim);
34        ++currentDim;
35    }

36}
其中从while (currentDim<=DimensionNum)那句开始就是算法的所在,目前只完成点空间分布的算法,思路是:先把所有点所有坐标初始化为0.
从0维开始往上计算坐标,0维时,得到第一个点,坐标为0;以后每次增加一个维度,都把前面计算好的所有点的原来维度复制到新的一批点,对新的维度值设为Length,这个值即n维立方体的边长:

 1void CSuperCube::CaculatePHelp(int currentDim)
 2{
 3    int i;
 4    //----------------------点计算
 5    if(currentDim==0)
 6        return;
 7    else
 8    {
 9        int targetStart=2<<(currentDim-1);//复制的起始点
10        int targetEnd=2<<currentDim;//复制的结束点下一点
11        for (i=targetStart;i<targetEnd;++i)
12        {
13            int index=DimensionNum*i;//目标点的x坐标索引
14            int source=DimensionNum*targetStart;//来源点的x坐标索引负偏移量
15            for (int j=0;j<currentDim;++j)
16            {
17                Points[index+j]=Points[index-source+j];//复制
18            }

19            Points[index+currentDim]=Length;//新加的维度设为边长
20        }

21    }

22}

线的空间分布比点的分布计算难了些,不过已经初步分析出来,思路大概如下:
初始化1维的线的两端点分别是索引点1,索引点2;以后每增加一个维度,把原来已经初始化了的线复制过来,再把线的两个索引点的值全部偏移“2的(当前维度-1)次方”,再初始化“2的(当前维度-1)次方”条边,起始点索引分别为前“2的(当前维度-1)次方”个点,终点的索引点分别为接着的“2的(当前维度-1)次方”个点。
线的空间分布代码明天贴出。

接下来,面的空间分布计算又更进一步难了,还有最后一个问题就是所有OpenGL渲染要素完成后,为了展示效果,还要旋转这个n维超立方体,于是需要旋转矩阵,n维矩阵的旋转公式应该如何推导,这两个问题各位图形爱好者共同想想,一起努力~~~
posted on 2009-07-31 21:32 陈昱(CY) 阅读(2080) 评论(8)  编辑 收藏 引用 所属分类: 图形学算法

FeedBack:
# re: 一个想法,用程序画出高维超立方体在三维上的投影!!!(1)[未登录] 2009-07-31 23:25 hdqqq
演示4维立方体的falsh
http://4d.shadowpuppet.net/4d.php  回复  更多评论
  
# re: 一个想法,用程序画出高维超立方体在三维上的投影!!!(1)[未登录] 2009-08-01 00:04 欲三更
有一个纪录片专门讲述这方面,好像叫dimensions,你可以去找找  回复  更多评论
  
# re: 一个想法,用程序画出高维超立方体在三维上的投影!!!(1) 2009-08-01 11:02 凡客诚品
不错  回复  更多评论
  
# re: 一个想法,用程序画出高维超立方体在三维上的投影!!!(1) 2009-08-01 11:08 mybios
屏幕只是二维,要表现四维的东西,还是有困难的。
就好比在一维显示器上显示三维画面一样困难。
三维的画面可以投影到二维屏幕上,那四维画面就应该投影到三维屏幕上才对。  回复  更多评论
  
# re: 一个想法,用程序画出高维超立方体在三维上的投影!!!(1) 2009-08-01 20:21 haskell
# re: 一个想法,用程序画出高维超立方体在三维上的投影!!!(1) 2009-08-01 22:17 陈昱(CY)
感谢各位提供资料,目前程序初步成功~  回复  更多评论
  
# re: 一个想法,用程序画出高维超立方体在三维上的投影!!!(1) 2009-08-02 12:07 mybios
@陈昱(CY)
可喜可贺  回复  更多评论
  
# re: 一个想法,用程序画出高维超立方体在三维上的投影!!!(1)[未登录] 2009-08-03 14:45 欲三更
@mybios
一维的显示器?您没事吧?

另外,这个投影是成立的,4维投3维,三维再投成2维。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理