`
尧尧1975417219
  • 浏览: 6317 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Java实现美丽的分形

阅读更多
    一谈到分形,我就来劲,看到各种美丽的分形图案,我就特别欣喜,所以,我常常到各大网站浏览各种分形图。据说,很多人学计算机语言都是从各种画图开始的,因为常常被美丽的图形所吸引,就会慢慢喜欢上原本比较枯燥编程,我就是那么一个人。之前吧,我对Java学习并没有那么大的兴趣,自从听了分形这个内容以后,我就慢慢的喜欢上了编程,当我独自把柯赫曲线做出来以后,我对编程的喜好就一发不可收拾,现在只要有时间,我就会打开电脑,编写自己喜欢的东西。
   制作一个分形并不是一件简单的事,需要对递归函数有比较深刻的认识,最重要的是要有一定的数学功底,因为在制作中需要计算很多的坐标,一不小心就会出错。之前在做毕达格拉斯树的时候就是因为坐标计算错误,做了一下午都没有没有做出来。后面通过我一步步的检查大概检查了一个小时才发现第二个点坐标计算错误,一个坐标的计算就花了我一下午的时间,所以说,学计算机数学很重要,所以说是“数学是计算机之父”这句话一点都没错。
   其实,这次不怎么想把自己做的分形放到博客上的,因为做的不太好,所以不想丢脸。但是东哥这周要我们写一个有关分形的博客,没办法,丑媳妇总得见公婆,就把之前做的几个不太好看的分形图给大家献丑献丑了。这次总共做了7个分形图,接下来就告诉大家我是怎么实现这七个图形的。

一、首先给大家介绍第一个分形图,雪花,它的原理很简单,就是把一条直线平均分成三段,中间一段是一个等边三角形,然后通过递归吧它做出来得到的就是柯赫曲线,然后改变初始坐标和计算方法,把另外两个柯赫曲线做出来,代码实现如下:
效果如下所示;

1.递归一次:


2.递归两次:



/**
* 第一个递归函数,用于画柯赫曲线上部分
*/
public void draw1(double x1, double y1, double x2, double y2, int n) {
g.setColor(new Color(0, 255, 0));
if (n <= 1) {// 退出递归条件
g.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
} else {
// 把x1——>x5作为局部变量,并计算变量
double x3 = (2 * x1 + x2) / 3;
double y3 = (2 * y1 + y2) / 3;
double x4 = (x1 + 2 * x2) / 3;
double y4 = (y1 + 2 * y2) / 3;
double x5 = 0, y5 = 0;
double k = (y4 - y3) / (x4 - x3);
if (y3 == y4) {
x5 = (x3 + x4) / 2;
y5 = y3 - (x4 - x3) * Math.sqrt(3) / 2;
} else {
if (k < 0) {
x5 = x1;
y5 = y4;
}
if (k > 0) {
x5 = x2;
y5 = y3;
}
}

g.setColor(new Color(n, n, n));
draw1(x1, y1, x3, y3, n - 1);
draw1(x3, y3, x5, y5, n - 1);
draw1(x5, y5, x4, y4, n - 1);
draw1(x4, y4, x2, y2, n - 1);
}
}

/**
* 第二个递归函数,用于画柯赫曲线右边
*/
public void draw2(double x1, double y1, double x2, double y2, int n) {
g.setColor(new Color(0, 255, 0));
if (n <= 1) {
g.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
} else {
// 把x1——>x5作为局部变量,计算x1-->x5,y1-》y5
double x3 = (2 * x1 + x2) / 3;
double y3 = (2 * y1 + y2) / 3;
double x4 = (x1 + 2 * x2) / 3;
double y4 = (y1 + 2 * y2) / 3;
double x5 = 0, y5 = 0;
double k = (y4 - y3) / (x4 - x3);
if (y3 == y4) {
x5 = (x3 + x4) / 2;
y5 = y3 + (x4 - x3) * Math.sqrt(3) / 2;
} else {
if (k < 0) {
x5 = x2;
y5 = y3;
}
if (k > 0) {
x5 = x1;
y5 = y4;
}
}
draw2(x1, y1, x3, y3, n - 1);
draw2(x3, y3, x5, y5, n - 1);
draw2(x5, y5, x4, y4, n - 1);
draw2(x4, y4, x2, y2, n - 1);
}
}

/**
* 第三个递归函数画柯赫曲线左边
*
*/
public void draw3(double x1, double y1, double x2, double y2, int n) {
g.setColor(new Color(0, 255, 0));
if (n <= 1) {

g.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
} else {
// 把x1——>x5作为局部变量
double x3 = (2 * x1 + x2) / 3;
double y3 = (2 * y1 + y2) / 3;
double x4 = (x1 + 2 * x2) / 3;
double y4 = (y1 + 2 * y2) / 3;
double x5 = 0, y5 = 0;
double k = (y4 - y3) / (x4 - x3);
if (y3 == y4) {
x5 = (x3 + x4) / 2;
y5 = y3 - (x4 - x3) * Math.sqrt(3) / 2;
} else {
if (k < 0) {
x5 = x1;
y5 = y4;
}
if (k > 0) {
x5 = x2;
y5 = y3;
}
}
draw3(x1, y1, x3, y3, n - 1);
draw3(x3, y3, x5, y5, n - 1);
draw3(x5, y5, x4, y4, n - 1);
draw3(x4, y4, x2, y2, n - 1);
}
}
二、接下来画的是是几棵竹子,它的实现是通过在一条直线上不断出现分支,然后递归就可以得到竹子,代码及效果图如下:

1.递归一次



2.递归两次



public void tree(double x1, double y1, double x2, double y2, int n,
Graphics g) {
if (n >= 1) {
double x3, x4, y3, y4;
// g.drawString("I believe !",0,300);
g.setColor(Color.green);
g.drawLine((int) (x1), (int) (y1), (int) (x2), (int) (y2));
x3 = (x1 + x2) / 2;
y3 = (y1 + y2) / 2;
tree(x1, y1, x3, y3, n - 1, g);
tree(x3, y3, x2, y2, n - 1, g);
x4 = (x2 + y2 - y3 - x3) * 0.7071 + x3;
y4 = (y2 - x2 + x3 - y3) * 0.7071 + y3;
tree(x3, y3, x4, y4, n - 1, g);
x3 = (x1 * 3 + x2) / 4;
y3 = (y1 * 3 + y2) / 4;

x2 = (x2 * 3 + x1) / 4;
y2 = (y2 * 3 + y1) / 4;
x4 = (x2 * 1.732 - y2 + 2 * x3 - x3 * 1.732 + y3) / 2;
y4 = (x2 + y2 * 1.732 - x3 + 2 * y3 - 1.732 * y3) / 2;
tree(x3, y3, x4, y4, n - 1, g);

}

}
三、毕达哥拉斯树的实现,首先,通过第一点把其余的四点计算出来,再把计算得到的点进行递归,这个计算有点复杂,好坑爹,代码及效果如下:

1.递归一次



2.递归两次





public void draw5(double x1, double y1, double L, double a, double b,
double c, int n) {
double x2;
double y2;
double x3;
double y3;
double x4;
double y4;
double x5;
double y5;
if (n < 1) {// 判断是否继续进行递归调用,注意:判断一定要放在递归调用之前,否则这段代码将永远不会被执行
return;
}
// 计算五个点的位置,以右下点为(X0,Y0)
x2 = x1 - L * Math.sin(a);
y2 = y1 - L * Math.cos(a);
x3 = x2 + L * Math.cos(Math.PI / 6) * Math.cos(a + Math.PI / 6);
y3 = y2 - L * Math.cos(Math.PI / 6) * Math.sin(a + Math.PI / 6);
x4 = x2 + L * Math.cos(a);
y4 = y2 - L * Math.sin(a);
x5 = x1 + L * Math.cos(a);
y5 = y1 - L * Math.sin(a);
Random r = new Random();
int R = r.nextInt(256);
int G = r.nextInt(256);
int B = r.nextInt(256);
g.setColor(new Color(R, G, B));
g.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
g.drawLine((int) x2, (int) y2, (int) x3, (int) y3);
g.drawLine((int) x3, (int) y3, (int) x4, (int) y4);
g.drawLine((int) x4, (int) y4, (int) x2, (int) y2);
g.drawLine((int) x4, (int) y4, (int) x5, (int) y5);
g.drawLine((int) x5, (int) y5, (int) x1, (int) y1);
// 划线——注意方法所需要的数据类型
draw5(x2, y2, L * Math.cos(Math.PI / 6), a + Math.PI / 6, b + Math.PI
/ 6, 0, n - 1);
draw5(x3, y3, L * Math.sin(Math.PI / 6), a - Math.PI / 3, b - Math.PI
/ 3, 0, n - 1);

// 进行递归调用(注意传到方法里的点是相对于新正方形的右下点)
}
四、谢宾斯基三角形,这个比较简单,就不多说了,代码及效果如下:

1、递归一次




2、递归两次





public void draw6(double x1, double y1, double x2, double y2, double x3,
double y3, int n) {
// (x1,y1),(x2,y2)(x3,y3)分别表示三角形的三个坐标
if (n <= 0) {// 跳出递归条件
return;

}
Random r = new Random();
int R = r.nextInt(256);
int G = r.nextInt(256);
int B = r.nextInt(256);
// (x4,y4),(x5,y5),(x6,y6)分别表示三角形的三边中点
double x4 = (x1 + x3) / 2;
double y4 = (y1 + y3) / 2;
double x5 = (x1 + x2) / 2;
double y5 = (y1 + y2) / 2;
double x6 = (x2 + x3) / 2;
double y6 = (y2 + y3) / 2;

g.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
g.drawLine((int) x1, (int) y1, (int) x3, (int) y3);
g.drawLine((int) x3, (int) y3, (int) x2, (int) y2);
draw6(x4, y4, x3, y3, x6, y6, n - 1);
draw6(x4, y4, x5, y5, x1, y1, n - 1);
draw6(x2, y2, x5, y5, x6, y6, n - 1);
g.setColor(new Color(R, G, B));

}

五、迷宫,这是我自己给它起的名字,因为不知道这玩意叫什么名字,就胡乱起了个名字,代码及效果图如下:

1、递归一次




2、递归两次






public void draw7(double x1, double y1, double x2, double y2, int n) {
// (x1,y1),(x2,y2)(x3,y3)分别表示三角形的三个坐标
if (n <= 0) {// 跳出递归条件
return;

}
Random r = new Random();
int R = r.nextInt(256);
int G = r.nextInt(256);
int B = r.nextInt(256);
// (x4,y4),(x5,y5),(x6,y6)分别表示三角形的三边中点
double x3 = x1 + (x2 - x1) / 3;
double y3 = y1 + (y2 - y1) / 3;
double x4 = x2 - (x2 - x1) / 3;
double y4 = y2 - (y2 - y1) / 3;
g.draw3DRect((int) x1, (int) y1, (int) x2 - (int) x1, (int) y2
- (int) y1, false);
g.draw3DRect((int) (x1 + (x2 - x1) / 3), (int) (y1 + (y2 - y1) / 3),
(int) (x2 - (x2 - x1) / 3) - (int) (x1 + (x2 - x1) / 3),
(int) (y2 - (y2 - y1) / 3) - (int) (y1 + (y2 - y1) / 3), true);

// 画对角部分
draw7(x1, y1, x3, y3, n - 1);
draw7(x4, y4, x2, y2, n - 1);
draw7(x4, y1, x2, y3, n - 1);
draw7(x1, y4, x3, y2, n - 1);
// 画四面部分
draw7(x3, y1, x4, y3, n - 1);
draw7(x1, y3, x3, y4, n - 1);
draw7(x4, y3, x2, y4, n - 1);
draw7(x3, y4, x4, y2, n - 1);
g.setColor(new Color(R, G, B));

}

六、无穷圆,代码实现及效果如下如下:

1、递归一次




2、递归两次




public void draw8(double x1, double y1, double x2, double y2, int n) {
// (x1,y1),(x2,y2)(x3,y3)分别表示三角形的三个坐标
if (n <= 0) {// 跳出递归条件
return;

}
Random r = new Random();
int R = r.nextInt(256);
int G = r.nextInt(256);
int B = r.nextInt(256);
// (x3,y3),(x4,y4),(x5,y5),(x6,y6)分别表示圆的起始和终点坐标
double x3 = x1;
double y3 = y1;
double x4 = (x2 + x1) / 2;
double y4 = y1;
double x5 = (x2 + x1) / 2;
double y5 = y1;
double x6 = x2;
double y6 = y2;
g.drawOval((int) x1, (int) (y1 - (x2 - x1) / 2), (int) (x2 - x1),
(int) (y2 + (x2 - x1) / 2 - y1 + (x2 - x1) / 2));
draw8(x3, y3, x4, y4, n - 1);
draw8(x5, y5, x6, y6, n - 1);
g.setColor(new Color(R, G, B));

}
七、树,代码及效果图如下:


1、递归一次




2、递归两次




public void draw9(double x0, double y0, double a, double b, double L, int n) {

if (n == 0) {
return;
}
double x1 = x0 + L * Math.cos(a) / 2;
double y1 = y0 - L * Math.sin(a) / 2;
double x2 = x1 - 2 * L * Math.cos(5 * Math.PI / 6 - a) / 3;
double y2 = y1 - 2 * L * Math.sin(5 * Math.PI / 6 - a) / 3;
double x3 = x1 + 2 * L * Math.cos(a - Math.PI / 6) / 3;
double y3 = y1 - 2 * L * Math.sin(a - Math.PI / 6) / 3;
g.setColor(new Color(100, 200, 220));
g.drawLine((int) x0, (int) y0, (int) x1, (int) y1);
g.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
g.drawLine((int) x1, (int) y1, (int) x3, (int) y3);
draw9(x2, y2, a + b, b, 3 * L / 4, n - 1);
draw9(x3, y3, a - b, b, 3 * L / 4, n - 1);
}
  • 大小: 7.9 KB
  • 大小: 7.2 KB
  • 大小: 5.9 KB
  • 大小: 8.6 KB
  • 大小: 2.6 KB
  • 大小: 5.8 KB
  • 大小: 7.3 KB
  • 大小: 9.3 KB
  • 大小: 9.5 KB
  • 大小: 9.5 KB
  • 大小: 15.6 KB
  • 大小: 2.5 KB
  • 大小: 5.6 KB
  • 大小: 11.7 KB
  • 大小: 15.3 KB
分享到:
评论

相关推荐

    Java实现的分形算法与程序设计

    #### 使用Java实现分形算法 Java作为一门跨平台的面向对象编程语言,在图形界面开发方面有着广泛的应用。利用Java来实现分形算法可以充分利用其图形处理能力,创建出丰富多彩的分形图案。 ##### Java中的图形环境 ...

    用Java实现的分形程序

    这个名为"用Java实现的分形程序"的项目,显然利用了Java编程语言来创建一个图形化程序,用于绘制美丽的分形图像。Java作为一种跨平台的编程语言,非常适合这种类型的应用,因为它提供了丰富的图形用户界面(GUI)库...

    dla.rar_ dla_DLA_java 模型_分形 DLA

    通过这个Java实现的分形DLA模型,学习者不仅可以了解分形理论,还能接触到基本的图形绘制和随机算法,这对于计算机图形学和算法设计的学习都是非常有价值的。同时,这种模拟实验也鼓励探索和创新,比如改进算法以...

    分形算法JAVA实现

    在IT领域,分形算法是一种...总之,"分形算法JAVA实现"资料包提供了一个全面的学习平台,让开发者能够从零开始掌握分形算法的Java实现。通过系统学习和实践,不仅可以提升编程技能,还能欣赏到数学与艺术的完美结合。

    分形算法与程序设计——Java实现

    在实现分形算法时,我们通常会用到以下几种数据结构和方法: 1. **复数运算**:许多分形算法基于复数,如Mandelbrot集和Julia集。Java虽然原生不支持复数类型,但我们可以自定义复数类,包括加减乘除和幂运算等方法...

    Java图形分形实例源码.rar

    在Java中,通过利用Java AWT(Abstract Window Toolkit)或Swing库,可以创建出交互式的图形界面来展示这些美丽的分形图案。 在描述中提到,这个源码可能有一定的复杂性,暗示可能涉及到递归算法和复杂的图形计算。...

    分形算法与程序设计 源代码 java版本

    读者将学习如何构建IFS规则,并用Java实现这些规则来生成自相似图形。 3. 第3章:可能会讲解L-系统,这是一种形式化的语法系统,常用于生成植物或树枝的分形模型。在Java中,通过解析和迭代L-系统规则,可以生成...

    分形算法与程序设计Java实现代码

    分形算法与程序设计——Java实现,此光盘收录的是《分形算法与程序设计java版》一书中所讲解的程序设计的源代码及部分供参考的效果图。具体内容和使用方法如下: 文件夹&lt;第2章JAVA&gt;包括: &lt;2_01&gt;:内含Cantor三分...

    论文研究-基于XML和Java技术的分形图像处理与网络传输.pdf

    本文将介绍一种基于XML(可扩展标记语言)和Java技术的分形图像处理与网络传输方法,该方法在保存磁盘空间和网络带宽方面表现出色。 首先,让我们了解一下XML和Java这两个关键词。 XML是一种用于存储和传输数据的...

    Java 分形几何图形源代码实例

    在Java编程中,实现分形通常涉及以下几个步骤: 1. 定义迭代规则:根据所选分形类型,编写计算新坐标点的函数。 2. 初始化画布:设置图形窗口的大小,以及颜色和像素映射。 3. 迭代计算:对画布上的每个像素进行...

    基于JAVA的分形图像生成研究.doc

    《基于JAVA的分形图像生成技术的研究》这篇论文主要探讨了如何使用JAVA语言来实现分形图像的生成,尤其关注L系统和Koch曲线的算法设计。分形图像生成技术是一种模仿自然形态的有效方法,其在艺术、科学、工程等多个...

    递归出来的美丽分形世界

    这篇博客可能详细介绍了如何使用编程语言(如Python、Java或C++)来实现递归算法,生成著名的科赫曲线(Koch Curve),这是分形几何中的经典例子。科赫曲线是由瑞典数学家Helge von Koch于1904年提出的,它通过将...

    计算机图形学实验实现正方体分形

    这些库提供了绘制3D图形和处理图形变换的函数,帮助我们实现分形的渲染。例如,OpenGL提供了一系列的函数来创建和管理顶点、设置投影矩阵、进行颜色着色以及绘制多边形。 在实际编程中,我们还需要关注性能优化,...

    分形算法与程序设计――Java实现

    本篇文章将深入探讨如何用Java语言来实现分形算法,并通过具体的程序设计来展示其应用。 1. **递归算法**: 递归是分形算法的基础,它通过函数或过程调用自身的方式来解决问题。例如,著名的曼德布罗特集...

    偶然玩分形 java测试

    本项目聚焦于使用 Java 语言来实现分形图像的绘制,通过源码解析,我们可以深入理解分形的生成原理以及 Java 在图形处理中的应用。 首先,我们要了解什么是分形。分形是由曼德勃罗集(Mandelbrot set)等经典例子...

    分形算法与程序设计——Java实现(7)

    分形算法与程序设计——Java实现,这是其中的第七个程序。

    分形设计—java,html,c。100个实例

    3. **C语言分形设计**:C语言以其高效和灵活性著称,是实现分形算法的理想选择。通过标准I/O和数学库,开发者可以直接在命令行界面或图形界面(如使用GTK+或SDL库)绘制分形。C语言的分形实现往往更为底层,可以提供...

Global site tag (gtag.js) - Google Analytics