上一次我们用了简单的直线和迭代法画点的形式画出了美丽的图形,但是自然界除了有其神奇的特性,更多地是有规律可寻的。
今天我们就要用递归来画出可以自己控制的图片!
我们先来介绍一下递归,所谓递归,就是自己的方法中还在调用自己的方法。但是实际上我们可以不用这样来考虑,我们就可以认为在方法中又调用了一个方法,
这个方法和自己的方法的用途一样,只是带入的参数不同。
在递归中我们要注意几点:
1、注意退出条件的控制,递归是个死循环,没有退出条件就会一直递归下去,直至栈溢出,然后报错。
2、递归时注意变量的传递和值的变化。
3、我们还要关注进入时的参数值变化和返回时返回值的变化。
首先我们来画一个递归画直线的:
/** * 递归画直线的方法 * @param g图形对象 * @param x1第一个点横坐标 * @param y1第一个点纵坐标 * @param x2第二个点横坐标 * @param y2第二个点纵坐标 * @param count递归次数 */ public void drawline(Graphics g, int x1, int y1, int x2, int y2, int count) { count--; //如果count等于0就返回 if (count < 1) { return; } g.drawLine(x1, y1, x2, y2);//画线 drawline(g, x1, y1 + 50, (int) (2.0 / 3 * x1 + 1.0 / 3 * x2), y2 + 50, count);//递归画左边直线 drawline(g, x2, y2 + 50, (int) (2.0 / 3 * x2 + 1.0 / 3 * x1), y1 + 50, count);//递归画右边直线 }
正方形:
/** * 画正方形的方法 * @param g图形对象 * @param x正方形中心横坐标 * @param y正方形中心纵坐标 * @param r正方形边长的一半 * @param count迭代次数 */ public void drawsquare(Graphics g, int x, int y, int r, int count) { count--; //如果count为0,返回 if (count < 1) { return; } g.fillRect(x - r, y - r, 2 * r, 2 * r);//画正方形 //迭代画周围的8个小正方形 drawsquare(g, x - (int) (r * 2.5), y - (int) (r * 2.5), r / 3, count); drawsquare(g, x, y - (int) (r * 2.5), r / 3, count); drawsquare(g, x + (int) (r * 2.5), y - (int) (r * 2.5), r / 3, count); drawsquare(g, x - (int) (r * 2.5), y, r / 3, count); drawsquare(g, x + (int) (r * 2.5), y, r / 3, count); drawsquare(g, x - (int) (r * 2.5), y + (int) (r * 2.5), r / 3, count); drawsquare(g, x, y + (int) (r * 2.5), r / 3, count); drawsquare(g, x + (int) (r * 2.5), y + (int) (r * 2.5), r / 3, count); }
三角形:
/** * 画三角形 * @param g图形对象 * @param x1上边的横坐标 * @param y1上边的纵坐标 * @param x2左边的横坐标 * @param y2左边的纵坐标 * @param x3右边的横坐标 * @param y3右边的纵坐标 * @param count画三角形的迭代次数 */ public void drawtriangle(Graphics g, int x1, int y1, int x2, int y2, int x3, int y3, int count) { count--;//count减一 if (count < 1)//如果count小于1,返回 { return; } //画线 g.drawLine(x1, y1, x2, y2); g.drawLine(x1, y1, x3, y3); g.drawLine(x3, y3, x2, y2); //画中间的线 drawtriangle(g, (x1 + x2) / 2, (y1 + y2) / 2, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2, count); drawtriangle(g, x1, y1, (x1 + x2) / 2, (y1 + y2) / 2, (x1 + x3) / 2, (y1 + y3) / 2, count); drawtriangle(g, (x1 + x3) / 2, (y1 + y3) / 2, x3, y3, (x2 + x3) / 2, (y2 + y3) / 2, count); }
Koch雪花:
/** * 画雪花的方法 * * @param g图形对象 * @param x1左边点的横坐标 * @param y1左边点的纵坐标 * @param x2右边点的横坐标 * @param y2右边点的纵坐标 * @param count画线的次数 */ public void drawkoch(Graphics g, double x1, double y1, double x2, double y2, int count) { if (count <= 1) { g.drawLine((int) x1, (int) y1, (int) x2, (int) y2);// 画线 } else { double x3 = (2 * x1 + x2) / 3;// 第一个三等份点的x坐标 double y3 = (2 * y1 + y2) / 3;// 第一个三等份点的y坐标 double x4 = (x1 + 2 * x2) / 3;// 第二个三等份点的x坐标 double y4 = (y1 + 2 * y2) / 3;// 第二个三等份点的y坐标 double k = (x1 - x2) * (y1 - y2);// 线的斜率 double x5 = x1, y5 = y1;// 第一个三等份点的x坐标 if (y3 == y4)// 直线 { x5 = (x3 + x4) / 2; y5 = y3 - (x4 - x3) * Math.sqrt(3) / 2; } else if (k < 0)// 左斜线 { x5 = x1; y5 = y4; } else if (k > 0)// 右斜线 { x5 = x2; y5 = y3; } if (x3 == x4) // 如果斜线为竖线 { x5 = x3; y5 = y3; } // 画尖端的左面那条线 drawkoch(g, x3, y3, x5, y5, count - 1); // 画尖端的右面那条线 drawkoch(g, x5, y5, x4, y4, count - 1); // 画左边那条直线 drawkoch(g, x1, y1, x3, y3, count - 1); // 画右边那条直线 drawkoch(g, x4, y4, x2, y2, count - 1); } }
相关推荐
在计算机图形学中,递归分形树是一种用以模拟自然界中复杂树形结构的有效方式,尤其适用于生成具有动态动画效果的视觉艺术作品。 "摇曳的递归分形树"这个标题暗示了我们将探讨一种能够动态变化的分形树生成技术,...
递归分形树模型可以有效地模拟自然界中树木的生长形态,通过对不同参数的调整,可以生成各种形态各异的树。 3. **递归算法**:递归是程序设计中的一个重要概念,它是指一个函数或过程在执行过程中调用自身的过程。...
总的来说,递归分形树的动画实现是一个融合了数学、算法和艺术的项目,它可以锻炼你的编程技能,同时也是一种探索数学美学和自然界规律的好方式。通过不断迭代和优化,你可以创造出更加逼真和复杂的分形树动画。
在现代数学领域,分形几何作为20世纪数学的一个新兴分支,已经得到了广泛的应用。分形几何不仅在科研领域中占有...同时,分形几何的学习也有助于学生认识到数学与自然界、艺术等领域之间的联系,拓宽学生的知识视野。
### 递归分形Java知识点解析 #### 一、递归分形概念 递归分形是一种通过递归算法绘制出来的图形,具有自相似性,即整体与部分形状相同或相似。递归分形在计算机图形学中有广泛的应用,如自然景观模拟、艺术设计等...
分形(Fractal)是一种在数学、艺术以及自然界中广泛存在的几何形态,它们具有自相似性和无穷细节。在计算机图形学中,通过编程实现分形图形的绘制是一种有趣且富有挑战性的任务,尤其是使用递归算法。递归是程序...
分形递归算法不仅在艺术和视觉效果上具有吸引力,也对理解自然界中复杂系统的生长和演化过程有着重要的启示作用。 在压缩包文件"2_13"中,可能包含了源代码文件、编译后的可执行文件、资源文件或者用于演示的图片。...
算法思想——递归与分治 递归和分治是两种常用的算法思想,它们可以单独使用,也可以结合使用以解决复杂的问题。下面我们将详细探讨这两种算法思想。 递归是一种算法思想,它的基本思想是将一个问题分解成一个或多...
在Java中,我们需要为每个非终结符设计一个递归子程序。这些子程序通常以方法的形式存在,它们接受输入的符号流,根据文法规则进行匹配,并返回一个表示当前非终结符的AST节点。例如,对于一个表达式非终结符,我们...
### 全排列——递归排序和字典序列 在计算机科学与编程领域中,全排列是一种重要的算法,它被广泛应用于解决多种问题,如组合优化、密码学等。本文将详细介绍两种实现全排列的方法:递归排列和字典序排列,并通过...
本实验“杭电编译原理实验——递归下降分析子程序”旨在帮助学生深入理解和掌握这一核心概念。 1. **递归下降分析概述**:递归下降分析是一种自顶向下的解析策略,它通过将文法规则转化为一系列的函数,每个函数...
汉诺塔——经典的递归 *实现移动函数 *递归实现汉诺塔函数
本文将深入探讨递归下降法在语法分析中的应用,并结合C语言来解析这一概念。 递归下降法是一种自顶向下的解析策略,它基于文法的递归性质来构建解析函数。在C语言的编译器设计中,递归下降法通常用于处理C语言的...
Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE...
在这个"opengl L系统递归算法实现分形树"的例子中,我们将深入探讨如何利用OpenGL和L系统来创建具有自相似性的分形树。 1. **OpenGL基础知识**: - OpenGL是跨语言、跨平台的图形API,用于渲染2D、3D矢量图形。 -...
C语言中递归是重中之重的部分,多数用于求解N!等含有迭代性质的问题,此文档详细介绍了递归算法,实用。
"奇妙的递归"这一主题,揭示了分形图形的核心特性——递归构造。递归是数学和计算机科学中的一个重要概念,它通过重复一个过程来解决问题或生成结构,每次迭代通常将问题规模减小或简化。 Koch曲线,是由瑞典数学家...
本主题主要探讨的是在C++中如何实现二叉树的前序、中序和后序遍历,同时包括递归和非递归两种方法。VS2008是Microsoft Visual Studio的一个版本,它提供了一个强大的开发环境,支持C++编程。 **前序遍历**: 前序...
### 编译原理生成四元式——递归子程序方法 #### 一、知识点概述 在编译原理中,四元式是一种常见的中间代码表示形式,它由四个部分组成:操作符、操作数1、操作数2以及结果的存放位置。这种表示方式非常适合于...