小白第一步|Java实现递归分形(以谢尔宾斯基三角形和勾股树为例)
一个递归分形搞得我心态爆炸
于是
我一定要写个博客祭奠一下!!!!!!
首先回顾一下递归的几个要素:
1、return:往上回溯
2、调用自身:往下挖掘
3、设置条件:防止无限递归
4、递归操作:分析什么操作可以重复
先实现我们的窗体,以便于我们的画画
Windows.java
package divisions;import java.awt.Graphics;
import java.awt.event.MouseListener;import javax.swing.JFrame;public class windows {public static void showUI(){//设置窗体JFrame win = new JFrame();win.setSize(1200, 1000);win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);win.setLocationRelativeTo(null);win.setVisible(true);//设置监听器mouse m = new mouse();win.addMouseListener(m);//设置画布Graphics graphics = win.getGraphics();m.setGraphics(graphics);}public static void main(String[] args) {showUI();}
}
package divisions;import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;public class mouse implements MouseListener{public void setGraphics(Graphics g){this.g = g;}@Overridepublic void mouseClicked(MouseEvent e) {}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) { }@Overridepublic void mouseExited(MouseEvent e) {}}
下面我们就来实现一下谢尔宾斯基三角形和勾股树的实现
首先是谢尔宾斯基三角形
首先我们要想
递归的重复操作是什么?
以我拙见,大概是这个图形:
这样我们可以想到:每次画六个线画出这个形状,然后转到三个角的位置来继续重复操作就ok
这样,我们可以首先获取三个点的坐标,存到数组中,设置递归次数
int[][] points = new int[3][2];//不要设置过大,这样电脑反应会有点慢,例如我的破电脑哈哈哈哈哈哈int length = 10;
获取成功后可以就可以进行draw操作,其中draw函数是一个递归函数,传参传进去的是最外层三角的坐标和递归控制数
public void mousePressed(MouseEvent e) {points[temp][0] = e.getX();points[temp][1] = e.getY();temp++;if(temp == 3){int x1 = points[0][0];int y1 = points[0][1];int x2 = points[1][0];int y2 = points[1][1];int x3 = points[2][0];int y3 = points[2][1];draw(x1, y1, x2, y2, x3, y3, length);}}
再转到draw函数:
public void draw(int x1,int y1,int x2,int y2,int x3,int y3,int num){//画图g.drawLine(x1, y1, x2, y2);g.drawLine(x2, y2, x3, y3);g.drawLine(x3, y3, x1, y1);g.drawLine((x1+x2)/2,(y1+y2)/2,(x1+x3)/2,(y1+y3)/2);g.drawLine((x2+x3)/2,(y2+y3)/2,(x2+x1)/2,(y2+y1)/2);g.drawLine((x3+x1)/2,(y3+y1)/2,(x3+x2)/2,(y3+y2)/2);//递归判断if(num <= 0)return;num--;//定义中点int tx1 = (x1+x2)/2;int ty1 = (y1+y2)/2;int tx2 = (x2+x3)/2;int ty2 = (y2+y3)/2;int tx3 = (x3+x1)/2;int ty3 = (y3+y1)/2;//转到三个角递归调用draw(x1, y1, tx1, ty1, tx3, ty3, num);draw(tx1, ty1, x2, y2, tx2, ty2, num);draw(tx3, ty3, tx2, ty2, x3, y3, num);}
看下效果:
大成功!
带着三角形做出来的心情我们转到可爱的勾股树
同样的,我们分析一下这个图形的递归图像:
很容易发现:就是一个个的正方形
首先先解决一个大难题:正方形在知道对角线坐标的时候可以进行公式计算算出另外两个坐标的公式:
(引用于百度)
我们设确定的点的坐标是(x1,y1),(x3,y3),公式出来的为(x2,y2),(x4,y4)
下面需要确定的是三个正方形夹住的三角形的一个角度:
可以定义一个arg = PI / 4;
然后再根据公式计算出以(x1,y1),(x2,y2)为三角形两点的另外一个点的坐标:
其中A1 = arg,A2 = PI / 2 - arg;
代入确认一点为(x,y)
然后在左树:根据上式,未知点为1点,已知点为(x1,y1)为4点,(x,y)为3点
解方程得1点
在右树:根据上式,未知点为1点,已知点为(x,y)为4点,(x2,y2)为3点
解方程再得1点
(注意:上面左右树有不同点,请注意)
然后递归调用即可(代码见下)
代码(其中注释掉的是谢尔宾斯基三角形的代码)
package divisions;import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;public class mouse implements MouseListener{// int[][] points = new int[3][2];int[][] points = new int[2][2];int temp = 0;double arg = Math.PI / 3;int length = 15;Graphics g;public void setGraphics(Graphics g){this.g = g;}@Overridepublic void mouseClicked(MouseEvent e) {}@Overridepublic void mousePressed(MouseEvent e) {// points[temp][0] = e.getX();
// points[temp][1] = e.getY();
// temp++;
// if(temp == 3){// int x1 = points[0][0];
// int y1 = points[0][1];
// int x2 = points[1][0];
// int y2 = points[1][1];
// int x3 = points[2][0];
// int y3 = points[2][1];
// draw(x1, y1, x2, y2, x3, y3, length);
// }
// }points[temp][0] = e.getX();points[temp][1] = e.getY();temp++;if(temp == 2){int x1 = points[0][0];int y1 = points[0][1];int x2 = points[1][0];int y2 = points[1][1];draw(x1,y1,x2,y2,length);}}// public void draw(int x1,int y1,int x2,int y2,int x3,int y3,int num){// g.drawLine(x1, y1, x2, y2);
// g.drawLine(x2, y2, x3, y3);
// g.drawLine(x3, y3, x1, y1);
// g.drawLine((x1+x2)/2,(y1+y2)/2,(x1+x3)/2,(y1+y3)/2);
// g.drawLine((x2+x3)/2,(y2+y3)/2,(x2+x1)/2,(y2+y1)/2);
// g.drawLine((x3+x1)/2,(y3+y1)/2,(x3+x2)/2,(y3+y2)/2);
// if(num <= 0)return;
// num--;
// int tx1 = (x1+x2)/2;
// int ty1 = (y1+y2)/2;
// int tx2 = (x2+x3)/2;
// int ty2 = (y2+y3)/2;
// int tx3 = (x3+x1)/2;
// int ty3 = (y3+y1)/2;
// draw(x1, y1, tx1, ty1, tx3, ty3, num);
// draw(tx1, ty1, x2, y2, tx2, ty2, num);
// draw(tx3, ty3, tx2, ty2, x3, y3, num);
//
// }public void draw(int x1,int y1,int x3,int y3,int num){int x4 = (x1 + y1 + x3 - y3)/2;int y4 = (-x1 + y1 + x3 + y3)/2;int x2 = (x1 - y1 + x3 + y3)/2;int y2 = (x1 + y1 - x3 + y3)/2;g.drawLine(x1, y1, x2, y2);g.drawLine(x2, y2, x3, y3);g.drawLine(x3, y3, x4, y4);g.drawLine(x4, y4, x1, y1);num--;if(num <= 0)return;double r = Math.sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)) / 2;int x = (int) ((x1 * (1 / Math.tan(Math.PI / 2 - arg)) + x2 * (1 / Math.tan(arg)) + y2 - y1) / ((1 / Math.tan(arg)) + (1 / Math.tan(Math.PI / 2 - arg))));int y = (int) ((y1 * (1 / Math.tan(Math.PI / 2 - arg)) + y2 * (1 / Math.tan(arg)) + x1 - x2) / ((1 / Math.tan(arg)) + (1 / Math.tan(Math.PI / 2 - arg))));int tx1 = x1 - y1 + y;int ty1 = x1 + y1 - x;int tx2 = x - y + y2;int ty2 = x + y - x2;draw(tx1, ty1, x, y, num);draw(tx2, ty2, x2, y2,num);}public void mouseReleased(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseEntered(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseExited(MouseEvent e) {// TODO Auto-generated method stub}}
小白第一步|Java实现递归分形(以谢尔宾斯基三角形和勾股树为例)相关推荐
- 简单分形(谢尔宾斯基三角形和地毯)
对于分形,我的理解就是:由小元件组成整体,然后再用另一或相同整体替换元件形成的循环迭代图形. 下面以谢尔平斯基三角形为例,介绍下最简单的分形思路. 第一步,先构造一个正三角形,取正三角形三边中点并连线 ...
- 数据结构与算法(Python版)二十二:递归可视化(谢尔宾斯基三角形)
谢尔宾斯基Sierpinski三角形 分形构造, 平面称谢尔宾斯基三角形, 立体称谢尔宾斯基金字塔 谢尔宾斯基三角形:作图思路 根据自相似特性, 谢尔宾斯基三角形是由3个尺寸减半的谢尔宾斯基三角形按照 ...
- Python数据结构15:turtle模块制图,画直线,正方形,星星,递归可视化:分形树,谢尔宾斯基三角形
1. Python中的turtle模块制图 前面已经讲了递归的原理,这里用递归作图来直观的理解递归. 首先了解以下Python中用于作图的内置海龟作图系统turtle module. Python内置 ...
- Java面向对象编程:利用递归思想绘制“谢尔宾斯基地毯”和“谢尔宾斯基三角形”
1.递归:在方法中调用本方法. 2.递归调用会无限循环下去,因此方法体中必须有结束方法的条件.返回值为void时通常写为: if (条件) {return; } 下面使用递归绘制"谢尔宾斯基 ...
- 混沌与分形(一):谢尔宾斯基三角形与门格海绵
研究混沌运动,少不了对分形理论的探讨.分形:通常被定义为"一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状",即具有自相似的性质. 本篇将从 ...
- 分形——谢尔宾斯基三角形
分形--谢尔宾斯基三角形 普通几何学研究的对象,一般都具有整数的维数.比如,零维的点.一维的线.二维的面.三维的立体.乃至四维的时空.在20世纪70年代末80年代初,产生了新兴的分形几何学(fract ...
- python螺旋圆的绘制_python 使用turtule绘制递归图形(螺旋、二叉树、谢尔宾斯基三角形)...
插图工具使用Python内置的turtle模块,为什么叫这个turtle乌龟这个名字呢,可以这样理解,创建一个乌龟,乌龟能前进.后退.左转.右转,乌龟的尾巴朝下,它移动时就会画一条线.并且为了增加乌龟 ...
- 混沌分形之谢尔宾斯基(Sierpinski)
本文以使用混沌方法生成若干种谢尔宾斯基相关的分形图形. (1)谢尔宾斯基三角形 给三角形的3个顶点,和一个当前点,然后以以下的方式进行迭代处理: a.随机选择三角形的某一个顶点,计算出它与当前点的中点 ...
- 分形之谢尔宾斯基(Sierpinski)地毯
前面讲了谢尔宾斯基三角形,和这一节的将把三角形变为正方形,即谢尔宾斯基地毯,它是由瓦茨瓦夫·谢尔宾斯基于1916年提出的一种分形,是自相似集的一种. 谢尔宾斯基地毯的构造与谢尔宾斯基三角形相似,区别仅 ...
最新文章
- 安卓 发送短信两种方式
- 新计算推动信息技术产业新发展?
- WKWebView 实现iOS与H5的交互转
- 2020年李永乐线性代数强化笔记-行列式与矩阵
- REST WebService与SOAP WebService的比较
- 干货|靶场|工具|字典 分享
- iOS探索:Block解析浅谈
- HDU1812 - Count the Tetris
- HttpServletRequest简述
- 从中工毕业到年薪30万,我用了2年9个月
- PHP 将Base64图片保存到 Sae storage
- 优酷视频手机上能发现投屏设备,但投屏失败?
- 磁盘配额超出 linux,使用linux的warnquota命令发送邮件给超出配额的用户
- 在脚本中, 使用sqlite3检查android程序生成的数据库是否OK
- [下载] Zend studio 8 Windows版
- zookeeper源码_阿里P8带你从源码级别——深挖Zookeeper监听机制
- 因云而生,阿里云全面进入云原生时代
- 肯德基营销策略案例分析PPT模板
- FastText学习笔记
- 计组-流水线(三张图解决流水线概念计算吞吐率)