也许是不小心又翻到了去年暑假的那个分形PPT,让我想起来还有一个没有完成的任务,就是L-system。
当时刚接触java,还是属于很年轻的,但是经过了那么久的积淀,我觉得我可以解决这个问题。
于是,我开始了探求L-system之旅。
首先我们还是来回顾一下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); } }
但是这一次,我们使用的并不仅仅是递归,而是用字母表和符号串来表达生成的对象的初始形式,称之为公理(axiom)。
现在我们可以定义如下字符规则:
F:在当前方向前进一个单位,并画线
+:逆时针旋转α角度
-:顺时针旋转α角度
我们再定义一个字符转换规则:F -> F-F++F-F
那么下一步将会转成:F-F++F-F-F-F++F-F++F-F++F-F-F-F++F-F
以此类推,我们取α=60度,便得到我们以前画的Koch雪花。
那么如果我们在每画完一条直线时,稍微附带着偏转一个角度,结果会更加的令人惊讶的!
public static final String strF = "F-F++F-F";// 基础字符串 private double theta = Math.PI * 60 / 180;// 偏转固定的角度 String axiom = "F-F++F-F";// "公理"字符串 double d = 50;// 单位长度 double garma = 3;// 微调时的偏转角度 double x1, y1;// 画线的初始点 /** * 根据字符串axiom,画出图形 * * @param axiom * @param g */ public void drawLS(String axiom, Graphics g) { // 把中点坐标定到屏幕正中心 x1 = getWidth() / 2; y1 = getHeight() / 2; double x2 = x1, y2 = y1;// 用于存取下一步的位置 double alpha = 0;// 当前所指向的角度 // 循环遍历字符串,根据字符串所给出的提示,F表示前进一个单位,+表示逆时针旋转α,-表示顺时针旋转α for (int i = 0; i < axiom.length(); i++) { switch (axiom.charAt(i)) { case 'F':// 如果是F就走一部 // 计算下一步的坐标 x2 = x1 + d * Math.cos(alpha); y2 = y1 + d * Math.sin(alpha); // 根据坐标画线 g.drawLine((int) x1, (int) y1, (int) x2, (int) y2); // x1,y1变到新的坐标点 x1 = x2; y1 = y2; break; case '-':// -表示顺时针旋转α alpha -= theta; // 在两个strF中间,要进行一个小角度的偏转,使得图形偏转角度趋于混乱 if (i < axiom.length() - 2) { if (axiom.charAt(i + 1) == 'F' && axiom.charAt(i + 2) == '+') { double a = Math.PI * garma / 180;// 根据γ计算出偏转角度a alpha -= a;// α再逆时针旋转a } } break; case '+':// +表示逆时针旋转α alpha += theta; break; } } } /** * 字符串递归的方法 * * @param str如果是small就是变小 * ,如果是large就是变大 */ public void dealAxiom(String str) { if (str.equals("small")) { if (!axiom.equals("F")) { axiom = axiom.replace(strF, "F");// 用"F"代替strF } } if (str.equals("large")) { axiom = axiom.replace("F", strF);// 用strF代替"F" } }
学习永远没有尽头,to be continue...
相关推荐
用L-system的方法生成一棵简单的平面内的树。
L-Studio 3.1 光盘镜像文件 使用L-System建模时必要的工具
资源来自pypi官网。 资源全名:L-System-Visualizer-1.0.6.tar.gz
L-system 绘图,部分源代码。包括3个类:LRules,Draw和Point
L-system或被称为Lindenmayer system是一个相似重写系统,是一系列不同形式的正规语法规则,多被用于植物生长过程建模,但是也被用于模拟各种生物体的形态。L-system也能用于生成自相似的分形,例如迭代函数系统。此...
基于MFC的L-System。所有参数可以自己设定。另外包含一个设计文档。
L-system 用java实现画图,的源码,用来画图
NULL 博文链接:https://wybwzl.iteye.com/blog/1275520
计算机图形学L-System实验,用L-system的方法生成一棵简单的三维树,可用鼠标控制观察方向。
导入由L-System-Visualizer导出的文件。 概述 L-System-Visualizer( )能够导出包含渲染中使用的模型的渲染以及这些模型的实例。 为了在其他项目中使用该信息,必须从导出的文件中提取该信息。 该进口商可以做到这...
介绍了一种新颖的从单张树木图片中提取树木的L-system规则的算法,并将其应用于三维树木建模。用户首先在图片上勾画出树木的主要可见枝干和树冠轮廓,通过图像处理的方法识别出树木的可见枝干的二维骨架;然后依据树木...
L系统算法代码,C++,可生成多种pattern的SVG格式图像。基于https://github.com/SHA-T/lindenmayer。在Win11 Visual Studio 2022下调试成功。需要配置GLM库...
L系统项目 软件工程| 索尔兹伯里大学数学与计算机科学系 项目介绍 该应用程序是用Python...python -m lsystem 替代方法 您也可以在本地克隆存储库并运行。 python ./__main__.py 使用应用程序 请按照内置教程按钮中的
系统Lindemayer 的 L 系统(植物) 控制: F1-F6:在不同的 L 系统中加载。 W、S、A、D:移动相机左右方向键:减小和增大分支旋转角度上下方向键:增加和减少迭代次数X,Z:放大和缩小Q,E:增加和减少组成树的线的...
介绍L系统源代码, 它实际上是字符串重写系统,如果把字符串解释成曲线,只要能生成字符串,也就等于生成了图形。它可以模拟多细胞体生长发育。随着计算机科学的发展,L系统的功能也得到了不断的扩展,现已经广泛的...
分形图形,在自然界中的存在,着实令人感到震撼,那是自然界巧夺天工的美,更让人感叹自然界的奇妙。
NULL 博文链接:https://xiaozhouzhou.iteye.com/blog/1893645
Lindenmayer system algorithm
Godot-L-系统分形树 Godot L系统分形树具有L系统,乌龟和Verlet集成资源
用dart编写的L系统解释器和渲染器Web应用程序。 要查看解释器本身,请访问 。变量: 在解释器中,进行以下变量命令映射: G和F:前进-:右转弯+:向左转角度[:保存状态]:弹出状态>:按颜色渐变逐步着色<:通过...