基于OpenGL的LS分形演示程序
实现了一个基于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分形演示程序相关推荐
- 基于OpenGL的Koch分形雪花实现
基于OpenGL的Koch分形雪花实现 在这学期选修了一门计算机图形学,本来是想好好学习一番,但...总感觉老师的教学水平有限,一学期下来感觉没学到啥东西,最多就是在几次实战作业中熟悉了一下部分效果的 ...
- 计算机可视化仿真技术opengl,基于OpenGL的三维场景可视化仿真
摘要: 随着计算机可视化技术的发展,计算机可视化应用的领域不断地拓宽,广泛地应用在科学计算.人工智能仿真.三维图形的制作方面等领域.可视化是计算机技术应用的热门领域,而这个热门领域的核心都集中在三维真 ...
- 转-基于OpenGL的3D天空仿真
在进行3D场景渲染时,天空是必不可少的因素.对于3D天空的模拟在视景仿真系统.计算机游戏.三维动画中有着广泛的应用.但是,目前对于天空的仿真还存在很多不足,一些模拟方法中存在实现复杂.计算耗时.图像分 ...
- 基于OpenGL的3D天空仿真
From:http://www.c-cnc.com/dz/news/news.asp?id=18622 在进行3D场景渲染时,天空是必不可少的因素.对于3D天空的模拟在视景仿真系统.计算机游戏.三维动 ...
- 基于OpenGL的地形建模技术的研究与实现
毕业论文 基于OpenGL的地形建模技术的研究与实现 诚信声明 本人郑重声明:本设计(论文)及其研究工作是本人在指导教师的指导下独立完成的,在完成设计(论文)时所利用的一切资料均已在参考文献中列出. ...
- java opengl_java基于OpenGL ES实现渲染实例
这篇文章主要介绍了java基于OpenGL ES实现渲染,实例分析了OpenGL渲染操作的相关技巧,需要的朋友可以参考下 本文实例讲述了java基于OpenGL ES实现渲染的方法.分享给大家供大家参 ...
- OpenGL 持久映射分形的实例
OpenGL 持久映射分形 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <math.h> #include <omp.h&g ...
- 基于opengl的3d漫游游戏 - 古堡危机之丧尸围城
作品名称: <古堡危机> 小组团队名称: 拾荒三人组 日期:2018年12月 目录 第一章 简介 3 前言 3 项目的创意设想.游戏类型.实现的功能.项目意义 3 Opengl 4 作品代 ...
- 基于OpenGL ES 的深度学习框架编写
基于OpenGL ES的深度学习框架编写 背景与工程定位 背景 项目组基于深度学习实现了视频风格化和人像抠图的功能,但这是在PC/服务端上跑的,现在需要移植到移动端,因此需要一个移动端的深度学习的计算 ...
最新文章
- 万物皆可JOJO:这个GAN直接让马斯克不做人啦 !Demo在线可玩!
- select/poll/epoll 与 /dev/poll
- 【BZOJ-1458】士兵占领 最大流
- python框架Flask学习笔记之get和post请求
- Java基础系列8:Java的序列化与反序列化(修)
- MVC 特性使用总结
- Xftp报no matching outgoing encryption algorithm found
- HW Eth-Trunk链路聚合
- bootstrap引入文件方法
- 浅谈Android选项卡(二)
- 【Verilog HDL】4.全减器
- 3.c++计算字符串长度的函数
- android箭头的样式修改,安卓自定义控件 一个指示用的箭头
- 怎么更改网络中的计算机名字,修改网络 “本地连接”的中网络名称“网络2”为其他名称...
- SSL协议与Nginx安装SSL模块和ssl证书
- OPPO A96和oppo Reno 7 哪个好
- 学渣的刷题之旅 leetcode刷题 13.罗马数字转整数
- c语言中余数恒等于1,费马小定理_KANGMANG201102_新浪博客
- Arrays.deepToString()与Arrays.toString()的区别
- 力扣 2200. 找出数组中的所有 K 近邻下标
热门文章
- 热风枪概述和使用方法
- 正运动学 与 逆运动学 区别
- 关于HBulider,mui框架入手可行性
- 深入理解:单一入口、MVC、ORM、CURD、ActiveRecord概念
- 七夕到了,你还单身吗?
- Genome Research | 呼吸疾病国家重点实验室华大研究院合作解析新冠轻重症患者血浆cfRNA特征谱...
- 【算法系列】非线性最小二乘求解-梯度下降法
- 【将金令】1.19欧盘简讯:短线可博小空单
- 微型计算机cpu主要有两部分构成 他们是,【单选题】微型计算机的CPU主要由两部分构成,它们是( )
A. 内存和控制器
B. 内存和外存
C. 运算器和控制器
D. 外存和运算器...
- 安装完jdk后,cmd 运行java和java -version都行,就是运行javac不行