




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、用计算机程序制作三维立体画摘 要 该文介绍了三维立体画的原理和制作方法,并给出了用c语言编写的源程序。借助于pbrush.exe,读者可以自己设计和欣赏各式各样的三维立体画。 目前,市面上正在流行各式各样的立体画,其特点是从外表来看与一般的图案很相似,但是双眼紧盯着注视片刻后,一恍惚之间眼前便出现了画中画立体像。笔者第一次看到这种画便被发明者的创意所倾倒。利用众所皆知的双眼视差原理,竟能在一张平面纸上制造出如此奇幻。但是立体画本身除了其发明者的灵感和画面创作者的别出心裁之外,其原理上并无神秘之处。用计算机程序来实现它,可说是易如反掌。笔者用一个晚上时间,便在微机上用basic语言实现了简单形体
2、平面圆饼的立体画。当然,要使该程序具有完善的功能,提高其制作速度,还是应该用编译语言(如c语言)来编写。本文中给出的源程序借助于windows中的.bmp图形文件,可使大家自己制作任意形态的立体画。一、立体画的原理 看过立体电影的人都知道,当人的双眼分别接收不同视角拍摄的图像时便会产生立体感。这是由于人眼长期观察的习惯造成的。和立体电影原理相同的立体摄影风景照片也很早就已出现。图1中给出了这种立体照片的示意图。左、右照片分别是人的双眼角度上观察一棱锥体时左右眼看到的图像(图2)。左眼看到的是棱锥的顶端向右错动了一些的图像,右眼的看到则是棱锥的顶端向左错动了一些的图像。如果用一张硬卡片隔开两张照
3、片(如图3),09a04000.gif;图109a04001.gif;图209a04002.gif;图3双眼分别看两张画,会看到一个立体的棱锥体。这种立体照片的观察方法在测绘学中也早已采用。但是,目前的三维立体画在形式上与这些很不相同。它是怎样在同一张画面上呈现立体的呢?首先,分析一下人们是怎样从这些立体画中看出“立体形体”的。从前面所说的可以知道,人眼要得到立体感,双眼必须有视差,即双眼看到的图像应该有差异。人们在看立体画时,都有“恍惚”一下的过程。在这过程中,双眼的视中心发生了错动(如图4)。这样09a04003.gif;图4左眼看到的是画面的“偏左像”,右眼看到的是画面的“偏右像”。只要
4、“偏左像”和“偏右像”的内容相当于图1的左、右照片,双眼就会感到立体形体。那么,能否把图1的左、右照片分别当做“偏左像”和“偏右像”,简单重叠来得到立体画呢?显然不行。能够合成立体画的“偏左像”和“偏右像”是要满足一定条件的。如果图5中表现的棱锥体的表面上有图案的话,09a04004.gif;图5像素a和像素a''应该具有相同的颜色,因为它们是从不同视角观察的同一个实体点。像素b和像素b''、像素c和像素c''的情况与此相同。把两幅画分别当作“偏左图”和“偏右图”,部分重叠成为同一画面时,在新的画面上这种关系仍应该表现为a=a''
5、,b=b'',c=c''(如图6)。但这时应该注意到,在这张合成09a04005.gif;图6画面上,点a''既是“偏右图”上的点a'',又是“偏左图”上的点b。而一张画面上相同坐标点的像素只可能是一种颜色,因此,产生了新的像素关系a''=b。另外,点a既是“偏左图”上的点a,又是“偏右图”上的点c'',所以,a=c''。以此类推,点b''和点c也有类似的情况。因此出现了新的关系表示式,.''=c=c''=a=a''=b
6、=b''=.。这就构成了立体画面上像素必须要满足的条件:“等颜色像素链”。立体画上的所有点都从属于某一条“等颜色像素链”。这就是所有立体画图案都呈现出某种程度上的水平周期性的原因。因此,对于任意立体形状,只要构造出相应的这种“等像素链”,并按其规律充填图案即可得到立体画。但是正如前面所述,由于这种“等像素链”条件的约束,人们虽然可以随意构造出各种形体的立体画,但其立体形体的表面图案是不能完全随人意愿的。二、制作立体画的计算机程序由于人的双眼的水平性,以上的“等像素链”只按水平方向分布,与垂直方向无关。因此,在程序中,各个像素行的处理过程是相互独立的。制作立体画的程序主结构图如图
7、7。09a04006.gif;图7 制作立体画的程序主结构图在以上结构图中,关键是如何建立“等像素链”。具体的处理如下。对于立体形体上的每一个点,首先求出该点在“偏左图”和“偏右图”上的坐标。以图1中的棱锥顶点为例,实际上其x坐标是在中心点,但由于双眼的位置并不在其正上方,顶点在“偏左图”上向右位移,在“偏右图”上向左位移,而且其位移值的大小显然与其高度有关,即该点坐标越高位移值就越大。,b,c等点也都有这些位移。在求出一个点在“偏左图”和“偏右图”上的坐标后,再算出在合成图(如图6)上的对应坐标,以建立“等像素”关系,如a=a''。当立体形体的一个水平剖面上的全部点经过以上处
8、理后,合成图的各条“等像素链”关系也就自然形成了。另外,由于有可能出现高点遮盖低点的情况,“等像素链”的构造应该从低点到高点逐层进行,高点的“等像素”关系将替代低点的“等像素”关系。这也是程序主结构图中“首先,对于没有任何形体存在的背景平面构造等像素链”的原因。下面给出了根据以上结构图用c语言编写的源程序。程序中,每一个坐标点对应一个结构型数据,它包含“前像素”、“后像素”两个指针。“前像素”指针指向该坐标点作为“偏右图”上的一点,在“偏左图”所对应的点的坐标。“后像素”指针指向该坐标点作为“偏左图”上的一点,在“偏右图”所对应的点的坐标。程序中,“立体形体水平剖面的高低坐标数据”、“原始图案
9、素材”和输出的“立体画”的文件格式都是采用了windows3.1 的pbrush产生的bmp图形文件格式。图幅大小要求都是640×400,用16种颜色方式。其中,立体形体上各点的高低坐标用图形文件中的颜色值表示,因此该图形文件的图形与带颜色的等高线图安全相同。通常情况下,在16色的bmp文件中颜色值从小到大的顺序为:黑色、暗红色、暗绿色、暗黄色、暗蓝色、暗紫色、暗青色、暗灰色、灰色、明红色、明绿色、明黄色、明蓝色、明紫色、明青色、白色。本程序采用最简单的“图案充填”方案,即各条“链”上的像素点皆采用该“链”上的第一个像素的颜色。程序中的常数eye-space表示“偏左图”和“偏右图”
10、之间的偏差,bo-dot是表明“链”的首或尾的指针标志。该程序寄生在windows 3.1中的pbrush软件上。借助于它来构筑立体形体(即立体形体水平剖面高低坐标数据文件图8),设计原始图案(图9)。程序运行后,逐行输入并处理以上两个文件中的图形,然后输出立体画结果文件(图10)。最后,用pbrush来观赏立体画result.bmp。当然,要设计出令人赏心悦目的立体画,必须在立体形体和图案素材的选择和搭配上做到天衣无缝,独具匠心。09a04007.gif;图809a04008.gif;图909ain the file */bitmapfileheader;struct tagbitmapin
11、foheaderunsigned long int bisize,/* size of bitmapinfoheader */biwidth;/* width in pixels biheight;/* height in pixels */unsigned int biplanes, /* always 1 */bibitcount; /* color bits per pixel must be 1,4,8 or 24 */unsigned long int bicompression, /*bi-rgb,bi-rle 8 or 4*/bisizeimage, /*total bytes
12、in image */bixpelspermeter,/* 0,or opt,h res. */biypelspermeter,/* 0,or opt,h res. */biclrused, /* normally 0,can set a lower no. colors than bibitcount */biclrimportant; /* normally 0 */bitmapinfoheader;struct tagrgbquadunsigned char rgbblue, /* blue intensity,0-255 */rgbgreen, /* green intensity,0
13、-255 */rgbred, /* red intensity,0-255 */rgbreserved; /* reserved,set to zero */rgbquadnum-color;char *fn-layer="layer.bmp"char *fn-org="origin.bmp"char *fn-result="result.bmp"file *flayer,*forigin, *fresult;unsigned char tmp-byte1,tmp-byte2;unsigned int line,i-byte,i-pi
14、xel,x;unsigned int layer;int left-x,right-x;tmp-x;unsigned long int cur-offset;unsigned char hwidth,org-colorwidth;puts("-wintrick-");puts("-by li jisong -");if( (flayer=fopen(fn-layer,"rb") )!=null) fread(&bitmapfileheader,size-of-bitmapfilehader,1,flayer);fread(&a
15、mp;bitmapinfoheader,size-of-bitmapinfoheader,1,flayer);if( bitmapfileheader.bftype1=''b'' && bitmapfileheader.bftype2=''m''&& bitmapinfoheader.biwidth=width && bitmapinfoheader.biheight=num-line&& bitmapinfoheader.bibitcount=bits-per-pi
16、xel&& bitmapinfoheader.bicompression=compression)fread(rgbquad,size-of-rgbquad,num-color,flayer);elsefclose(flayer);printf("file %s is not fit for this program!n",fn-layer);getch();exit(1);elseprintf("file %s does not exist!n",fn-layer);getch();exit(2);if( (forigin=fopen(
17、fn-org,"rb")!=null) fread(& bitmapfileheader,size-of-bitmapfileheader,1,forigin);fread(& bitmapinfoheader,size-of-bitmapinfoheader,1,forigin);if( bitmapfileheader.bftype1=''b'' && bitmapfileheader.bftype2=''m''&& bitmapinfoheader.biwi
18、dth=width && bitmapinfohdader.biheight=num-line&& bitmapinfoheader.bibitcount=bits-per-pixel&& bitmapinfoheader.bicompression=compression)fread(rgbquad,size-of-rgbquad,num-color,forigin);else fclose(forigin);printf("file %s is not fit for this program!n",fn-org);get
19、ch();exit(3);else printf("file %s does not exist!n",fn-org);getch();exit(4);if( (fresult=fopen(fn-result,"wb")!=null)fwrite(&bitmapfileheader,size-of-bitmapfileheader,1,fresult);fwrite(& bitmapinfohiader,size-of-bitmapinfoheader,1,fresult);fwrite(rgbquad,size-of-rgbquad,n
20、um-color,fresult);else printf("file %s open error!n",fn-result);getch();exit(5);for(line=0;line<num-line;line+)printf("line=%dn",line);cur-offset=(unsigned long int)pixel-data-offset+(unsigned long int)byte-per-line*line;fseek (flayer,cur-offset,seek-set);fseek (forigin,cur-of
21、fset,seek-set);for(i-byte=0;i-byte<byte-per-line;i-byte+) fread(&tmp-byte1,1,1,flayer);fread(&tmp-byte2,1,1,forigin);for(i-pixel=0;i-pixel<pixel-per-byte;i-pixel+) x=i-byte*pixel-per-byte+i-pixel;if(x<width) hx=(unsigned char) (tmp-byte1<<(bits-per-pixel*i-pixel) /(unsigned ch
22、ar)0x80>>(bits-per-pixel-1);org-colorx=(unsigned char) (tmp-byte2<<(bits-per-pixel*i-pixel)/(unsigned char)0x80>>(bits-per-pixel-1);for(x=0;x<width;x+) dotx.color=0;dotx.nxt-x=no-dot;dotx.pri-x=no-dot;if(x+eye-space)<width) dotx.nxt-x=x+eye-space;if(signed)x-eye-space)>=0)dotx.pri-x=x-eye-space;for(layer=1;layer<num-color;layer+)for(x=0;x<width;x+) left-x=x-eye-space/2+(layer/2);right-x=x+eye-space/2-(layer
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 医疗健康管理在商业领域的应用与挑战
- 教案检查工作总结模版
- 上海 房东租房合同范例
- 红褐色扁平风网络安全模板
- 储罐厂家供货合同范例
- 产品定制打样合同范例
- 供销付款合同范例
- 防溺水安全家长会发言稿模版
- 住建部买房合同范例
- 职业性硬皮病的临床护理
- 广东省广州三校2023-2024学年高二下学期期末考试+物理试卷(含答案)
- 驾驶员安全驾驶培训课件
- 部编版语文四年级下册第四单元大单元作业设计
- 金融大数据银行项目使用手册
- 建筑公司挂靠协议书范文
- 人工智能训练师(中级数据标注员)理论考试题库(含答案)
- 中考数学解题技巧专题巧用旋转进行计算全国公开课一等奖百校联赛微课赛课特等奖课件
- MOOC 人工智能原理-北京大学 中国大学慕课答案
- 《杠杆 第1课时》示范公开课教学设计【初中物理苏科版九年级上册】
- 泛血管疾病抗栓治疗中国专家共识2024版解读课件
- 经典导读与欣赏智慧树知到期末考试答案2024年
评论
0/150
提交评论