分形<二>分形的递归算法
2015-10-23 23:33
316 查看
递归算法是把问题转化为规模缩小了的同类问题的子问题。1)核心的子问题算法。2)递归调用。3)给定递归出口。
递归设计使程序简洁,也体现了设计思路在整体-局部上结合的严谨,但仍不提倡程序设计使用,因为其运行效率低且占用栈的空间问题突出。作为解决思路的一种方式还是具有魅力。
分形的自我相似,自我复制和自我嵌套用递归算法来实现是合适的,事实上经典分形图的绘制大多数可采用递归算法。
一.canto三分集。
**渲染框架上有方便绘制几何图形的ShapeRenderer类,它和Batch画笔都封装了调用底层渲染的接口。
注:**标签的段落无关分形算法,是渲染框架上的一些笔记。
三分集递归算法:
效果:
二.Koch妖魔曲线
算法(修改:增加深度参数):
最终效果:
比起三分集,妖魔曲线复杂一些,涉及到角度和方向上的计算,如果你把每条线段看成是有方向的向量,这些计算会更容易接受。算法中的alpha是绝对角度,两条线段的相对夹角不变,为60度但绝对角度是变化的,绝对角度的计算需要方向上的修正。见下图可粗略体会下(图作得粗糙别吐槽)
如果注释修正绝对角度的代码,结果会是这样子
妖魔曲线基本的算法就是这样。它的基本图元是一条直线,在此基础上可以修改其基本图元为一个封闭的几何图形来模拟雪花。
待续...
递归设计使程序简洁,也体现了设计思路在整体-局部上结合的严谨,但仍不提倡程序设计使用,因为其运行效率低且占用栈的空间问题突出。作为解决思路的一种方式还是具有魅力。
分形的自我相似,自我复制和自我嵌套用递归算法来实现是合适的,事实上经典分形图的绘制大多数可采用递归算法。
一.canto三分集。
**渲染框架上有方便绘制几何图形的ShapeRenderer类,它和Batch画笔都封装了调用底层渲染的接口。
注:**标签的段落无关分形算法,是渲染框架上的一些笔记。
三分集递归算法:
private void canto(int ax,int ay,int bx,int by){ if((bx-ax)<c){ renderer.line(ax, ay, bx, by); } else{ int cx,cy,dx,dy; renderer.line(ax, ay, bx, by); cx=ax+(bx-ax)/3; cy=ay+50; dx=bx-(bx-ax)/3; dy=by+50; ay=ay+50; by=by+50; canto(ax,ay,cx,cy); canto(dx,dy,bx,by); } }
效果:
二.Koch妖魔曲线
算法(修改:增加深度参数):
public void koch(float ax,float ay,float bx,float by,int depth){ //delpth为深度 if(depth<1){ renderer.line(ax, 600-ay, bx, 600-by); } else{ float cx,cy,dx,dy,ex,ey; float l,alfa; depth-=1; cx=ax+(bx-ax)/3; cy=ay+(by-ay)/3; ex=bx-(bx-ax)/3; ey=by-(by-ay)/3; l=(float) Math.sqrt((ex-cx)*(ex-cx)+(ey-cy)*(ey-cy)); alfa=(float) Math.atan((ey-cy)/(ex-cx)); //绝对角度在方向上的修正 if((alfa>=0&&(ex-cx)<0)||(alfa<0&&(ex-cx)<0)){ alfa=alfa+PI; } dx=(float) (cx+Math.cos(alfa+PI/3)*l); dy=(float) (cy+Math.sin(alfa+PI/3)*l); koch(ax,ay,cx,cy,depth); koch(ex,ey,bx,by,depth); koch(cx, cy, dx, dy,depth); koch(dx, dy, ex, ey,depth); } }
最终效果:
比起三分集,妖魔曲线复杂一些,涉及到角度和方向上的计算,如果你把每条线段看成是有方向的向量,这些计算会更容易接受。算法中的alpha是绝对角度,两条线段的相对夹角不变,为60度但绝对角度是变化的,绝对角度的计算需要方向上的修正。见下图可粗略体会下(图作得粗糙别吐槽)
如果注释修正绝对角度的代码,结果会是这样子
妖魔曲线基本的算法就是这样。它的基本图元是一条直线,在此基础上可以修改其基本图元为一个封闭的几何图形来模拟雪花。
public void kochIcing(int depth,float... vertexs){ int length=vertexs.length; if(length%2!=0) Gdx.app.error("kochIcing", "vertexsNum must be even"); for(int i=0;i<length-2;i+=2){ koch(vertexs[i], vertexs[i+1],vertexs[i+2],vertexs[i+3], depth); } koch(vertexs[length-2], vertexs[length-1],vertexs[0],vertexs[1], depth); }图元为一个等边三角形:
fractal.kochIcing(5, 180,120,360,432,540,120);
待续...
相关文章推荐
- 软件架构师应该知道的97件事之概括46-60
- field data-es控制聚合内存使用-elasticsearch权威指南翻译
- Java实现栈之计算器
- 栈和堆的生长方向
- Java实现栈之计算器
- 正则表达式
- JavaScript之 ------ 浏览器对象模型 (BOM)
- ASIHTTPRequest安装配置,实测
- Fragment startActivityForResult,接收requestCode方法
- LiteHttp 第十节:异步并发与调度策略
- C++类中 虚函数与纯虚函数的区别和作用
- CSS属性--过渡(transtion)
- 在 Ubuntu 和 Linux Mint 上安装 Terminator 0.98
- 从快的线上callback hell代码说起
- Zf2 自定义组件库如何设置
- 高精度加法
- 5.希尔排序
- ECMAScript5 Array新增方法
- 三,遍历方法 1$.each(数组/对象,function处理); //$对象 调用的 2$(选择器).each(function处理); //jquery对象 调用的
- C#中Trim()、TrimStart()、TrimEnd()的用法