Sierpinski镂垫
Sierpinski镂垫是一个非常有趣的图案, 有着悠久的历史, 在分形几何中等领域里引起了人们极大地兴趣, 是用递归和随机方式定义的几何形状, 在极限情况下, 它所表现的性质并没有随机性.
生成算法如下:
(1)在三角形内部随机选取一个点作为初始点
(2)在三角形的3个顶点中随机选取一个,求出该顶点与初始点连线的中点,画出该中点
(3)将(2)中的中点作为初始点,转到(2)
下面利用SDL+OpenGL分别在二维和三维中来实现。
二维
/***************************************************************************** Copyright: 2012, ustc All rights reserved. contact:k283228391@126.com File name: main.c Description:Sierpinski 2d. Author:Silang Quan Version: 1.0 Date: 2012.12.02 *****************************************************************************/ #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <stdio.h> #include <stdlib.h> SDL_Surface *screen; void quit( int code ) { SDL_Quit( ); /* Exit program. */ exit( code ); } void handleKeyEvent( SDL_keysym* keysym ) { switch( keysym->sym ) { case SDLK_ESCAPE: quit( 0 ); break; case SDLK_SPACE: break; default: break; } } void resizeGL(int width,int height) { if ( height == 0 ) { height = 1; } //Reset View glViewport( 0, 0, (GLint)width, (GLint)height ); //Choose the Matrix mode glMatrixMode( GL_PROJECTION ); //reset projection glLoadIdentity(); //set perspection gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 ); //choose Matrix mode glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); } void handleEvents() { // Our SDL event placeholder. SDL_Event event; //Grab all the events off the queue. while( SDL_PollEvent( &event ) ) { switch( event.type ) { case SDL_KEYDOWN: // Handle key Event handleKeyEvent( &event.key.keysym ); break; case SDL_QUIT: // Handle quit requests (like Ctrl-c). quit( 0 ); break; case SDL_VIDEORESIZE: //Handle resize event screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 16, SDL_OPENGL|SDL_RESIZABLE); if ( screen ) { resizeGL(screen->w, screen->h); } break; } } } void initSDL(int width,int height,int bpp,int flags) { // First, initialize SDL's video subsystem. if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { fprintf( stderr, "Video initialization failed: %s\n", SDL_GetError( ) ); quit( 1 ); } atexit(SDL_Quit); //Set some Attribute of OpenGL in SDL SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); //Set the video mode screen= SDL_SetVideoMode( width, height, bpp,flags); if(!screen ) { fprintf( stderr, "Video mode set failed: %s\n",SDL_GetError( ) ); quit( 1 ); } resizeGL(screen->w, screen->h); //Set caption SDL_WM_SetCaption( "Sierpinski 2D", NULL ); } void renderGL() { // Clear the color and depth buffers. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // We don't want to modify the projection matrix. */ glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); // Move down the z-axis. glTranslatef( -20.0, -20.0, -60.0 ); //Draw a square /* A triangle */ GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}}; int i, j, k; srand(10); /* standard random number generator */ GLfloat p[2] ={7.5,5.0}; /* an arbitrary initial point inside traingle */ glClear(GL_COLOR_BUFFER_BIT); /* clear the window */ glBegin(GL_POINTS); /* compute and plots 5000 new points */ for( k=0; k<500000; k++) { j=rand()%3; /* pick a vertex at random */ /* Compute point halfway between selected vertex and old point */ p[0] = (p[0]+vertices[j][0])/2.0; p[1] = (p[1]+vertices[j][1])/2.0; /* plot new point */ glVertex2fv(p); } glEnd(); SDL_GL_SwapBuffers( ); } void initGL( int width, int height ) { float ratio = (float) width / (float) height; // Our shading model--Gouraud (smooth). glShadeModel( GL_SMOOTH ); // Set the clear color. glClearColor( 0, 0, 0, 0 ); // Setup our viewport. glViewport( 0, 0, width, height ); //Change to the projection matrix and set our viewing volume. glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 60.0, ratio, 1.0, 100.0 ); } int main( int argc, char* argv[] ) { // Dimensions of our window. int width = 640; int height = 480; // Color depth in bits of our window. int bpp = 32; int flags= SDL_OPENGL|SDL_RESIZABLE; //Set the SDL initSDL(width, height, bpp,flags); //Set the OpenGL initGL( width, height ); //main loop while(true) { /* Process incoming events. */ handleEvents( ); /* Draw the screen. */ renderGL( ); } return 0; }
三维
/***************************************************************************** Copyright: 2012, ustc All rights reserved. contact:k283228391@126.com File name: main3D.c Description:Sierpinski 3D. Author:Silang Quan Version: 1.0 Date: 2012.12.02 *****************************************************************************/ #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <stdio.h> #include <stdlib.h> SDL_Surface *screen; GLfloat colors[4][3]={{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{0.0,1.0,1.0}}; void quit( int code ) { SDL_Quit( ); /* Exit program. */ exit( code ); } void handleKeyEvent( SDL_keysym* keysym ) { switch( keysym->sym ) { case SDLK_ESCAPE: quit( 0 ); break; case SDLK_SPACE: break; default: break; } } void resizeGL(int width,int height) { if ( height == 0 ) { height = 1; } //Reset View glViewport( 0, 0, (GLint)width, (GLint)height ); //Choose the Matrix mode glMatrixMode( GL_PROJECTION ); //reset projection glLoadIdentity(); //set perspection gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 ); //choose Matrix mode glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); } void handleEvents() { // Our SDL event placeholder. SDL_Event event; //Grab all the events off the queue. while( SDL_PollEvent( &event ) ) { switch( event.type ) { case SDL_KEYDOWN: // Handle key Event handleKeyEvent( &event.key.keysym ); break; case SDL_QUIT: // Handle quit requests (like Ctrl-c). quit( 0 ); break; case SDL_VIDEORESIZE: //Handle resize event screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 16, SDL_OPENGL|SDL_RESIZABLE); if ( screen ) { resizeGL(screen->w, screen->h); } break; } } } void initSDL(int width,int height,int bpp,int flags) { // First, initialize SDL's video subsystem. if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { fprintf( stderr, "Video initialization failed: %s\n", SDL_GetError( ) ); quit( 1 ); } atexit(SDL_Quit); //Set some Attribute of OpenGL in SDL SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); //Set the video mode screen= SDL_SetVideoMode( width, height, bpp,flags); if(!screen ) { fprintf( stderr, "Video mode set failed: %s\n",SDL_GetError( ) ); quit( 1 ); } resizeGL(screen->w, screen->h); //Set caption SDL_WM_SetCaption( "Sierpinski 3D", NULL ); } void triangle( GLfloat *va, GLfloat *vb, GLfloat *vc) { glVertex3fv(va); glVertex3fv(vb); glVertex3fv(vc); } void tetra(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d) { glColor3fv(colors[0]); triangle(a,b,c); glColor3fv(colors[1]); triangle(a,c,d); glColor3fv(colors[2]); triangle(a,d,b); glColor3fv(colors[3]); triangle(b,d,c); } void divide_tetra(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d, int m) { GLfloat mid[6][3]; int j; if(m>0) { /* compute six midpoints */ for(j=0; j<3; j++) mid[0][j]=(a[j]+b[j])/2; for(j=0; j<3; j++) mid[1][j]=(a[j]+c[j])/2; for(j=0; j<3; j++) mid[2][j]=(a[j]+d[j])/2; for(j=0; j<3; j++) mid[3][j]=(b[j]+c[j])/2; for(j=0; j<3; j++) mid[4][j]=(c[j]+d[j])/2; for(j=0; j<3; j++) mid[5][j]=(b[j]+d[j])/2; /* create 4 tetrahedrons by subdivision */ divide_tetra(a,mid[0],mid[1],mid[2], m-1); divide_tetra(mid[0],b,mid[3],mid[5], m-1); divide_tetra(mid[1],mid[3],c,mid[4], m-1); divide_tetra(mid[2],mid[4],d,mid[5], m-1); } else tetra(a,b,c,d); /* draw tetrahedron at end of recursion */ } void renderGL() { //Define a triangle in space GLfloat v[4][3]={{0.0, 0.0, 1.0},{0.0, 0.942809, -0.33333},{-0.816497, -0.471405, -0.333333},{0.816497, -0.471405, -0.333333}}; // Clear the color and depth buffers. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // We don't want to modify the projection matrix. */ glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); // Move down the z-axis. glTranslatef( 0.0, 0.0, -2.0 ); glRotatef(50,0,1,0); glRotatef(30,1,0,0); glClear(GL_COLOR_BUFFER_BIT); /* clear the window */ glBegin(GL_TRIANGLES); divide_tetra(v[0],v[1],v[2],v[3],3); glEnd(); SDL_GL_SwapBuffers( ); } void initGL( int width, int height ) { float ratio = (float) width / (float) height; // Our shading model--Gouraud (smooth). glShadeModel( GL_SMOOTH ); // Set the clear color. glClearColor( 0, 0, 0, 0 ); // Setup our viewport. glViewport( 0, 0, width, height ); //Change to the projection matrix and set our viewing volume. glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 60.0, ratio, 1.0, 100.0 ); } int main( int argc, char* argv[] ) { // Dimensions of our window. int width = 640; int height = 480; // Color depth in bits of our window. int bpp = 32; int flags= SDL_OPENGL|SDL_RESIZABLE; //Set the SDL initSDL(width, height, bpp,flags); //Set the OpenGL initGL( width, height ); //main loop while(true) { /* Process incoming events. */ handleEvents( ); /* Draw the screen. */ renderGL( ); } return 0; }
参考:Sierpinski镂垫程序-http://www.codeforge.com/read/45707/Sierpinski%E9%95%82%E5%9E%AB%E7%A8%8B%E5%BA%8F.txt__html
转载于:https://blog.51cto.com/8672742/1368354
Sierpinski镂垫相关推荐
- 计算机图形学——是什么?为什么?怎么做?
目录 一. 计算机图形学的应用领域 1.1 计算机游戏(Computer Game) 1.2 计算机辅助设计(CAD/CAM) 1.3 计算机艺术(CA) 1.4 分形艺术 1.5 虚拟现实(VR) ...
- Qt OpenGL(07)递归细分四面体法绘制球体
文章目录 Qt OpenGL通过递归细分逼近球面 思路 下面就是绘制的代码: Widget.cpp 顶点着色器 片段着色器 Qt OpenGL通过递归细分逼近球面 在OpenGL中绘制球面,不是太简单 ...
- 百度Aistudio飞桨七日游体验python爬虫和分析数据
前言 在某天,老妹给我发了一个截图,百度飞桨举办小白入门到大神的python,而且还有奖品.最近玩拼多多的多多消游戏第133关卡了一个星期废话(建议体验 前期智商碾压游戏 后期靠游戏眷顾) ,回归主 ...
- OpenGL进阶(七)-康托尔集 谢尔宾斯基地毯 Koch雪花
这一篇关于分形图像,当然只是入门. 分形通常被定义为"一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状",即具有自相似的性质.分形有几种类型 ...
- 螺钉装弹垫平垫机器人_一种批量组装螺钉、弹垫、平垫的工装及使用方法_2
于螺钉托盘1开有数个盲孔1-1的面上,手持螺钉托盘1进行晃动, 短时间之后,由于每个盲孔1-1孔口倒角的结构设计.盲孔1-1特定深度设计及螺钉5螺帽 的重心作用,螺钉5会呈螺帽在下,螺杆在上阵列于盲孔 ...
- 螺钉装弹垫平垫机器人_【经验总结】什么时候用平垫,什么时候用弹垫?
很多人为了节约成本想省了平垫或者弹垫,其实在螺栓使用过程中平垫和弹垫各自起着不可或缺的作用.今天咱们来针对平垫和弹垫给大家介绍一下. 左 平 垫 右 弹 垫 平垫,形状一般是一个平垫圈,中间有一个孔, ...
- 铺铜过孔不要十字_谈谈商周青铜器上圈足的镂孔现象
在商代铜器和西周早期的铜器上,常常会看到带有圈足的器物,圈足有的会有一个孔洞,孔洞的形制有圆形的.十字形的.不规则圆形的等,如簋.觚.盘.豆.尊.罍.瓿.卣.觯.壶等,如下: 最近,我们读 ...
- l380废墨收集垫已到使用寿命_湖北雨水收集系统定制
淮北海聚环保设备有限公司为您详细解读jrWVof湖北雨水收集系统定制的相关知识与详情, 1.三格化粪池,可设想为长方形或圆形.各粪池容积计较根据粪水储存时间定,即一般可按2:1:3计较.号 ...
- l380废墨收集垫已到使用寿命_湖北土工网垫
山东鸿跃环保科技股份有限公司为您详细解读ykPRFl湖北土工网垫的相关知识与详情,复合土工膜施工技术 复合土工膜正式铺设前,应停止小面积试铺,铺设参数和施工工艺及格后,再停止大面积施工.为了便于施工, ...
最新文章
- [转]通过脚本添加登陆/注销/开机/关机脚本
- 中报表导出带表头_来看看Java是 如何优雅的导出 Excel的
- MySQL优化系列_常见的sql使用-Mysql中的实践(Mysql优化系列8)
- 2015蓝桥杯省赛---java---A---8(移动距离)
- Oracle历史记录
- 旅游大数据:从投资决策到分析工作的常态化
- 事务机制主要是利用undo、redo日志?
- 读书摘要——矇矇的秘密基地(关于DODAF)
- 关于各式竞赛书籍的点评
- win10桌面新建|解压文件夹不自动显示|需要自动刷新
- “不能初始化photoshop,因为暂存盘已满”图文解决方案
- 指定条件查找计算机,Excel函数教程: 查找符合指定条件的数据-excel技巧-电脑技巧收藏家...
- L9110H电机驱动模块 Arduino 小水泵小风扇
- endNote教程-5、6-高效阅读文献+高效文献调研
- c语言什么意思 app 视频 新闻 视,C语言中csapp.h 是什么意思?
- han_attention(双向GRU+attention)(imdb数据集---文档分类)
- 华为服务器系统日志,系统日志服务器
- 固体火箭发动机常用设计参数
- Try to increase the 20000ms adb execution timeout represented by 'uiautomator2ServerInstallTimeout'
- GoogleVR与unity2019(cardboard)
热门文章
- zynq网络时钟控制寄存器_【干货分享】ZYNQ开发基本流程
- python找最长的字符串_在字符串python中查找最长的唯一子字符串
- 2021 「营销云」攻略合集.pdf
- 《CSS蝉意花园读书精记》(基础篇---------上.资料篇1)
- 26期20180703 正则 grep
- Hive的HQL(2)
- 使用树莓派和kali Linux打造便携式渗透套件
- Delphi XE2 新控件 布局Panel TGridPanel TFlowPanel
- Ubuntu14.04LST 安装Oracle SQL Developer 4.0.2
- 通过APNIC获取各运营商IP网段