实现了一个基于LS(L系统)的二维分形演示程序。

实现这个演示程序的第一步当然是理解LS文法。咋看之下似乎有点难度,其实一点也不难。

举个例子就明白了:

LS文法先定义了绘图规则:

F:以当前方向前进一步,并画线;

f:以当前方向前进一步,不画线;

+:逆时针旋转角;

-:顺时针旋转角;

[:将海龟当前信息压栈;

]:将“[”时刻的海龟信息出栈。

Koch曲线的LS文法如下:

w:F(初始字母)

a :60(旋转角度)

P:F → F + F - - F + F(F的替代文法)

根据这一文法生成Koch曲线的步骤(假设迭代两次):

第一步: 得到迭代两次的文法。

第一次迭代结果:

F + F - - F + F

第二次迭代结果:(第一次迭代得到的结果的每一个F用规则P替换)

F + F - - F + F + F + F - - F + F - - F + F - - F + F + F + F - - F + F

第二步:按照迭代得到的文法绘图。

界面使用GLUI实现,写得比较简单。可以自己根据规则DIY文法,得到各种图形。全部演示程序代码如下:

#include <GL/glui.h>
#include<iostream>
#include<cmath>
#include<string>
#include<stack>
#define PI 3.1415926
#define lsSize 14using namespace std;
/** These are the live variables passed into GLUI ***/
int   wireframe = 0;int   main_window;int curr_string = 0;
int obj_type = 0;
GLfloat startX = 0.0f;
GLfloat startY = 0.0f;
GLUI_Panel  *obj_panel;
GLUI_Panel  *data_panel;
GLUI_Panel  *basic_data_panel;
GLUI_Panel  *tree_panel;
GLUI_RadioGroup  *radio;GLUI_EditText *textF;
GLUI_EditText *textX;
GLUI_EditText *textY;
GLUI_EditText *textS;string diyS;
string diyF;
string diyX;
string diyY;
GLfloat diyAngle;GLfloat  angle = 30.0; //步进角度
GLfloat len = 0.05f; //线段长度
GLint  depth = 4; //递归深度struct L_Sys{string name;string startStr;string replaceF;string replaceX;string replaceY;GLfloat angle;L_Sys(string nname,string nstartStr,string nreplaceF,string nreplaceX,string nreplaceY,GLfloat nangle){name = nname;startStr = nstartStr;replaceF = nreplaceF;replaceX = nreplaceX;replaceY = nreplaceY;angle = nangle;}
};  struct L_Sys ls[] = {L_Sys("Koch curve","F","F-F++F-F","","",60.0),L_Sys("Quadratic Koch IsLand","F+F+F+F","F+F-F-FF+F+F-F","","",90.0f),L_Sys("Dragon Curve","X","F","X+YF+","-FX-Y",90.0f),L_Sys("Gosper hexagonal curve","XF","F","X+YF++YF-FX--FXFX-YF+","-FX+YFYF++YF+FX--FX-Y",60.0),L_Sys("Sierpinski gasket","FXF--FF--FF","FF","--FXF++FXF++FXF--","",60.0f),L_Sys("SIerpinski arrowhead","YF","F","YF+XF+Y","XF-YF-X",60.0f),L_Sys("Hilbert curve","X","F","-YF+XFX+FY-","+XF-YFY-FX+",90.0f),L_Sys("F[+F]F[-F]F","F","F[+F]F[-F]F","","",30.0f),L_Sys("F[+F]F[-F][F]","F","F[+F]F[-F][F]","","",20.0f),L_Sys("FF-[-F+F+F]+[+F-F-F]","F","FF-[-F+F+F]+[+F-F-F]","","",22.5f),L_Sys("F[+X]F[-X]+X","X","FF","F[+X]F[-X]+X","",20.0f),L_Sys("F[+X][-X]FX","X","FF","F[+X][-X]FX","",25.7f),L_Sys("F-[[X]+X]+F[+FX]-X","X","FF","F-[[X]+X]+F[+FX]-X","",22.5f),L_Sys("","","","","",0.0)
};/***************************************** myGlutIdle() ***********/void myGlutIdle( void )
{if ( glutGetWindow() != main_window ) glutSetWindow(main_window);  glutPostRedisplay();
}void control_cb( int control )
{if(control == 5){ls[lsSize-1].angle = diyAngle;ls[lsSize-1].startStr = diyS;ls[lsSize-1].replaceF = diyF;ls[lsSize-1].replaceX = diyX;ls[lsSize-1].replaceY = diyY;curr_string = lsSize-1;}
}/**************************************** myGlutReshape() *************/void drawLine(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2){glBegin(GL_LINES);glVertex2f(x1,y1);glVertex2f(x2,y2);glEnd();
}void changeSize(int w, int h) {if(h == 0)h = 1;float ratio = 1.0* w / h;glMatrixMode(GL_PROJECTION);glLoadIdentity();glViewport(0, 0, w, h);gluPerspective(45,ratio,1,1000);gluLookAt(0.0,0.0,5.0, 0.0,0.0,-1.0,0.0f,1.0f,0.0f);glMatrixMode(GL_MODELVIEW);
}/***************************************** myGlutDisplay() *****************/
struct tpoint{GLfloat x;GLfloat y;GLfloat delta;
};void fractal(){string resultStr=ls[curr_string].startStr;GLfloat Delta= PI*(ls[curr_string].angle)/180;//生成角度//第一步 得到推进文法for(int i=0; i<depth;++i){string tmpStr;for(int j=0;j<resultStr.size();++j){if(resultStr[j]=='F'){tmpStr=tmpStr+ls[curr_string].replaceF;}else if(resultStr[j]=='X'){tmpStr=tmpStr+ls[curr_string].replaceX;}else if(resultStr[j]=='Y'){tmpStr=tmpStr+ls[curr_string].replaceY;}else{tmpStr=tmpStr+resultStr[j];}}resultStr = tmpStr;}//解析文法,绘制int k=0;tpoint bef={startX,startY,-PI/2},aft;//前一节点 和 后一节点stack<tpoint> s;while(k<resultStr.size()){switch(resultStr[k]) {case 'F':aft.x=bef.x+len*cos(bef.delta);aft.y=bef.y-len*sin(bef.delta);aft.delta = bef.delta;drawLine(bef.x,bef.y,aft.x,aft.y);bef=aft;break;case 'X':aft.x=bef.x+len*cos(bef.delta);aft.y=bef.y-len*sin(bef.delta);aft.delta = bef.delta;drawLine(bef.x,bef.y,aft.x,aft.y);bef=aft;break;case 'Y':aft.x=bef.x+len*cos(bef.delta);aft.y=bef.y-len*sin(bef.delta);aft.delta = bef.delta;drawLine(bef.x,bef.y,aft.x,aft.y);bef=aft;break;case '+':bef.delta += Delta;break;case '-':bef.delta -= Delta;break;case '[':s.push(bef);break;case ']':bef = s.top();s.pop();break;      default:break;}++k;}
}void renderScene(void) {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glColor3f(0.0f,1.0f,0.0f);fractal();glutSwapBuffers();
}/**************************************** main() ********************/int main(int argc, char* argv[])
{/****************************************//*   Initialize GLUT and create window  *//****************************************/glutInit(&argc, argv);glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );glutInitWindowPosition( 100, 100 );glutInitWindowSize( 500, 500 );main_window = glutCreateWindow( "OpenGL Fractal " );glutDisplayFunc( renderScene);glutReshapeFunc( changeSize );  glEnable(GL_DEPTH_TEST);GLUI *glui = GLUI_Master.create_glui( "Fractal" );new GLUI_StaticText( glui, "OpenGL Fractal Control Board" );basic_data_panel = new GLUI_Panel(glui,"basic data"); GLUI_Spinner *spinnerX = new GLUI_Spinner( basic_data_panel, "startX:", &startX);spinnerX->set_float_limits(-2.0, 2.0);spinnerX->set_alignment( GLUI_ALIGN_LEFT );GLUI_Spinner *spinnerY = new GLUI_Spinner( basic_data_panel, "startY:", &startY);spinnerY->set_float_limits(-3.0, 3.0);spinnerY->set_alignment( GLUI_ALIGN_LEFT );GLUI_Spinner *spinnerLen = new GLUI_Spinner( basic_data_panel, "lenth:", &len);spinnerLen->set_float_limits(0.0, 3.0);spinnerLen->set_alignment( GLUI_ALIGN_LEFT );GLUI_Spinner *spinnerDepth = new GLUI_Spinner( basic_data_panel, "depth:", &depth);spinnerDepth->set_int_limits(1, 10);spinnerDepth->set_alignment( GLUI_ALIGN_LEFT );data_panel = new GLUI_Panel(glui,"common curve");GLUI_Listbox *list = new GLUI_Listbox( data_panel, "", &curr_string );for(int i=0; i<7; ++i)list->add_item( i, ls[i].name.c_str());tree_panel = new GLUI_Panel(glui,"2D fractal tree");GLUI_Listbox *treeList = new GLUI_Listbox( tree_panel, "", &curr_string );for(int j=7; j<lsSize; ++j)treeList->add_item( j, ls[j].name.c_str());GLUI_Rollout *roll_diy = new GLUI_Rollout(glui, "DIY", false);GLUI_Panel *DIY_panel = new GLUI_Panel( roll_diy, "LS DIY" );textS = new GLUI_EditText( DIY_panel, "start", diyS, 1, control_cb );textF = new GLUI_EditText( DIY_panel, "F->", diyF, 2, control_cb );textX = new GLUI_EditText( DIY_panel, "X->", diyX, 3, control_cb );textY = new GLUI_EditText( DIY_panel, "Y->", diyY, 4, control_cb );textS->set_w(50);textF->set_w(50);textX->set_w(50);textY->set_w(50);textS->set_alignment( GLUI_ALIGN_LEFT);GLUI_Spinner *spinnerAngle = new GLUI_Spinner( DIY_panel, "angle:", &diyAngle);spinnerAngle->set_float_limits(0.0, 90.0);spinnerAngle->set_alignment( GLUI_ALIGN_LEFT );GLUI_Button *ok = new GLUI_Button(DIY_panel,"OK!!",5,control_cb);glui->set_main_gfx_window( main_window );GLUI_Master.set_glutIdleFunc( myGlutIdle ); new GLUI_Button( glui, "iQuit", 0,(GLUI_Update_CB)exit );glutMainLoop();return EXIT_SUCCESS;
}部分截图:

基于OpenGL的LS分形演示程序相关推荐

  1. 基于OpenGL的Koch分形雪花实现

    基于OpenGL的Koch分形雪花实现 在这学期选修了一门计算机图形学,本来是想好好学习一番,但...总感觉老师的教学水平有限,一学期下来感觉没学到啥东西,最多就是在几次实战作业中熟悉了一下部分效果的 ...

  2. 计算机可视化仿真技术opengl,基于OpenGL的三维场景可视化仿真

    摘要: 随着计算机可视化技术的发展,计算机可视化应用的领域不断地拓宽,广泛地应用在科学计算.人工智能仿真.三维图形的制作方面等领域.可视化是计算机技术应用的热门领域,而这个热门领域的核心都集中在三维真 ...

  3. 转-基于OpenGL的3D天空仿真

    在进行3D场景渲染时,天空是必不可少的因素.对于3D天空的模拟在视景仿真系统.计算机游戏.三维动画中有着广泛的应用.但是,目前对于天空的仿真还存在很多不足,一些模拟方法中存在实现复杂.计算耗时.图像分 ...

  4. 基于OpenGL的3D天空仿真

    From:http://www.c-cnc.com/dz/news/news.asp?id=18622 在进行3D场景渲染时,天空是必不可少的因素.对于3D天空的模拟在视景仿真系统.计算机游戏.三维动 ...

  5. 基于OpenGL的地形建模技术的研究与实现

    毕业论文 基于OpenGL的地形建模技术的研究与实现 诚信声明 本人郑重声明:本设计(论文)及其研究工作是本人在指导教师的指导下独立完成的,在完成设计(论文)时所利用的一切资料均已在参考文献中列出. ...

  6. java opengl_java基于OpenGL ES实现渲染实例

    这篇文章主要介绍了java基于OpenGL ES实现渲染,实例分析了OpenGL渲染操作的相关技巧,需要的朋友可以参考下 本文实例讲述了java基于OpenGL ES实现渲染的方法.分享给大家供大家参 ...

  7. OpenGL 持久映射分形的实例

    OpenGL 持久映射分形 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <math.h> #include <omp.h&g ...

  8. 基于opengl的3d漫游游戏 - 古堡危机之丧尸围城

    作品名称: <古堡危机> 小组团队名称: 拾荒三人组 日期:2018年12月 目录 第一章 简介 3 前言 3 项目的创意设想.游戏类型.实现的功能.项目意义 3 Opengl 4 作品代 ...

  9. 基于OpenGL ES 的深度学习框架编写

    基于OpenGL ES的深度学习框架编写 背景与工程定位 背景 项目组基于深度学习实现了视频风格化和人像抠图的功能,但这是在PC/服务端上跑的,现在需要移植到移动端,因此需要一个移动端的深度学习的计算 ...

最新文章

  1. 万物皆可JOJO:这个GAN直接让马斯克不做人啦 !Demo在线可玩!
  2. select/poll/epoll 与 /dev/poll
  3. 【BZOJ-1458】士兵占领 最大流
  4. python框架Flask学习笔记之get和post请求
  5. Java基础系列8:Java的序列化与反序列化(修)
  6. MVC 特性使用总结
  7. Xftp报no matching outgoing encryption algorithm found
  8. HW Eth-Trunk链路聚合
  9. bootstrap引入文件方法
  10. 浅谈Android选项卡(二)
  11. 【Verilog HDL】4.全减器
  12. 3.c++计算字符串长度的函数
  13. android箭头的样式修改,安卓自定义控件 一个指示用的箭头
  14. 怎么更改网络中的计算机名字,修改网络 “本地连接”的中网络名称“网络2”为其他名称...
  15. SSL协议与Nginx安装SSL模块和ssl证书
  16. OPPO A96和oppo Reno 7 哪个好
  17. 学渣的刷题之旅 leetcode刷题 13.罗马数字转整数
  18. c语言中余数恒等于1,费马小定理_KANGMANG201102_新浪博客
  19. Arrays.deepToString()与Arrays.toString()的区别
  20. 力扣 2200. 找出数组中的所有 K 近邻下标

热门文章

  1. 热风枪概述和使用方法
  2. 正运动学 与 逆运动学 区别
  3. 关于HBulider,mui框架入手可行性
  4. 深入理解:单一入口、MVC、ORM、CURD、ActiveRecord概念
  5. 七夕到了,你还单身吗?
  6. Genome Research | 呼吸疾病国家重点实验室华大研究院合作解析新冠轻重症患者血浆cfRNA特征谱...
  7. 【算法系列】非线性最小二乘求解-梯度下降法
  8. 【将金令】1.19欧盘简讯:短线可博小空单
  9. 微型计算机cpu主要有两部分构成 他们是,【单选题】微型计算机的CPU主要由两部分构成,它们是( ) A. 内存和控制器 B. 内存和外存 C. 运算器和控制器 D. 外存和运算器...
  10. 安装完jdk后,cmd 运行java和java -version都行,就是运行javac不行