对计算机语言越熟悉越是感觉到基础部分的重要性,数理逻辑,数据结构,算法设计与分析,都是越嚼越有味道,这几天一直在看关于递归以及尽量使用递归做东西,发现越是熟悉,越是觉得递归程式的美妙,我们且跨过递归的薄弱部分不谈,就它的优点足以让我兴奋!下面是我用递归实现的两幅图片,一副是毕达哥拉斯树,就是满足毕达哥拉斯定理(勾股定理)的一个分形树,还有一颗自定义树:
毕达哥拉斯树:
以上就是毕达哥拉斯树,大家可以明显看出最底层的那三个正方形明显就是我们第一次学勾股定理时,介绍说毕达哥拉斯发现勾股定理的三块地板砖。。。。哈哈,以此类推,每个正方形如此下去便形成毕达哥拉斯树分形。
自定义树:
如上是自定义树,自定义树与毕达哥拉斯树的不同就在于刚才我们看的那三个正方形不再是30度,60度,90度了,而是形成等腰直角三角形,这个比上面的那个看起来要规整的多了吧,其实我们还可以调整角度的,我们可以加个拉杆,让其中的一个非直角改变,就会得到不一样的美妙效果了!这么美得图,你动心了吗!?
附录源代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
* 利用递归生成毕达哥拉斯树
* @author LONG 2013-04-11
* @version 1.0
public class BidaTree extends JFrame {
private static final long serialVersionUID = 1L;
private static final double PI = Math.PI;
private JPanel jp = null; //声明面板类型变量
private Graphics gr = null; //声明画布类型变量
private int deepth = 0; //用来记录递归画的深度
private double x_start; //定义初始点的x坐标
private double y_start; //定义初始点的y坐标
private ButtonGroup bg = null; //声明按钮组变量
private double angle_1 = PI/6;
* 程序的入口
* @param args
public static void main(String[] args){
BidaTree bt = new BidaTree(); //声明并创建窗体对象
bt.initUI(); //调用自身的方法初始化界面
* 用来初始化界面的程序
private void initUI(){
this.setTitle("毕达哥拉斯树");
this.setSize(1000,600);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(3);
//添加选项按钮来选择画的树的种类
JRadioButton jr_bi = new JRadioButton("毕达哥拉斯树",true);
jr_bi.setActionCommand("bi");
jr_bi.setBackground(Color.WHITE);
JRadioButton jr_zi = new JRadioButton("自定义树");
jr_zi.setActionCommand("zi");
jr_zi.setBackground(Color.WHITE);
bg = new ButtonGroup();
bg.add(jr_bi);
bg.add(jr_zi);
//添加一个重置按钮
JButton jb_reset = new JButton("重置");
jb_reset.setPreferredSize(new Dimension(70,25));
jp = new JPanel();
jp.setPreferredSize(new Dimension(1000,570));
jp.setBackground(Color.WHITE);
JPanel jp_tool = new JPanel();
jp_tool.setPreferredSize(new Dimension(1000,30));
jp_tool.setBackground(Color.WHITE);
jp_tool.add(jr_bi);
jp_tool.add(jr_zi);
jp_tool.add(jb_reset);
this.add(jp_tool,BorderLayout.NORTH);
this.add(jp,BorderLayout.SOUTH);
this.setResizable(false);
this.setVisible(true);
gr = jp.getGraphics();
//给面板添加监听器
jp.addMouseListener(new MouseAdapter(){ //为面板添加监听器
public void mousePressed(MouseEvent e){ //当鼠标按下时,刷新面板
x_start = e.getX();
y_start = e.getY();
deepth++; //每次都是先增加deepth然后才会画的,所以初始化为0
repaint();
public void mouseReleased(MouseEvent e){ //当鼠标松开时,执行画的动作
String values = bg.getSelection().getActionCommand();
if(values.equals("bi")){
angle_1 = PI/6;
}else if(values.equals("zi")){
angle_1 = PI/4;
draw(x_start,y_start,x_start + 100,y_start,deepth);
jb_reset.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
repaint();
deepth = 0;
* 用来递归的方法画出毕达哥拉斯树的方法
* @param x 传入的x坐标
* @param y 传入的y坐标
private void draw(double x1,double y1,double x2,double y2,int de){//传入正方形的两个顶点,以及递归的深度,和角度
if(de > 0){ //来判断当递归深度大于0时执行
double extent = getLength(x1,y1,x2,y2); //用来得到两点之间的距离
double angle = getAngle(x1,y1,x2,y2);
double x3 = x1 + Math.cos(angle - PI/4)*Math.sqrt(2)*extent;
double y3 = y1 + Math.sin(angle - PI/4)*Math.sqrt(2)*extent;
double x4 = x1 + Math.cos(angle - PI/2)*extent;
double y4 = y1 + Math.sin(angle - PI/2)*extent;
int[] x = {(int)x1,(int)x2,(int)x3,(int)x4};
int[] y = {(int)y1,(int)y2,(int)y3,(int)y4};
gr.fillPolygon(x, y, 4);
double temp_x = x4 + Math.cos(angle - angle_1)*Math.cos(angle_1)*extent;
double temp_y = y4 + Math.sin(angle - angle_1)*Math.cos(angle_1)*extent;
draw(x4,y4,temp_x,temp_y,de - 1);
draw(temp_x,temp_y,x3,y3,de - 1);
* 用于计算两点之间的距离
* @param x0
* @param y0
* @param x2
* @param y2
* @return
private double getLength(double x1,double y1,double x2,double y2){
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
* 传入两个点,得到两点连线与x轴正方向的夹角,规定逆时针为负角度,
* 且以第一个点为起始点
* @param x0
* @param y0
* @param x2
* @param y2
* @return
private double getAngle(double x1,double y1,double x2,double y2){
double angle = 0.0;
if(x1 == x2){ //说明两点在同一条竖直线上
if(y1 > y2){
angle = PI*3/2;
}else if(y2 > y1){
angle = PI/2;
}else{ //说明两点不在同一条竖直线上
double temp_angle = Math.atan((y2 - y1)/(x2 - x1));
if(x2 > x1){ //说明x2在x0点的左边
angle = temp_angle;
}else if(x2 < x1){ //说明x2在x0的右边
angle = temp_angle + PI;
return angle;
对计算机语言越熟悉越是感觉到基础部分的重要性,数理逻辑,数据结构,算法设计与分析,都是越嚼越有味道,这几天一直在看关于递归以及尽量使用递归做东西,发现越是熟悉,越是觉得递归程式的美妙,我们且跨过递归的薄弱部分不谈,就它的优点足以让我兴奋!下面是我用递归实现的两幅图片,一副是毕达哥拉斯树,就是满足毕达哥拉斯定理(勾股定理)的一个分形树,还有一颗自定义树: 毕达哥拉斯树: 以上...
for a in range(1, max_bondary):
for b in range(1, max_bondary):
for c in range(1, max_bondary):
分形几何学是一门以不规则几何形态为研究对象的几何学。一个数学意义上分形的生成是基于一个不断迭代的方程式,即一种基于递归的反馈系统。虽然分形是一个数学构造,它们同样可以在自然界中被找到,这使得它们被划入艺术作品的范畴。
计算机协助了人们推开分形几何的大门。法国数学家曼德尔勃罗特这位计算机和数学兼通的人物,开创了新的数学分支——分形几何学。分形在医学、土力学、地震学和技术分析中都有应用。
毕达哥拉斯树(Pythagoras tree)是由毕达哥拉斯根据勾股定理所画出来的一个可以无限重复的图形。又因为重复数次
1.分形的算法都是公开的,问题在于如何将分形的算法变成SVG元素的坐标. 可以通过数学向量的技术实现.
2.分形图形一般都是一层一层的,创建图形也是由上一层计算出下一层,变色动画也可以按照层级来变化
0.1今天开始学码绘1.背景介绍2.准备工作
1.背景介绍
这个学期因为课程的缘故接触了P5.js,毕竟也是刚开始接触,只知道这是一个专门用来绘制图形图像的Javascript库。
由于它能很方便地将代码鲜明地呈现出来让人兴趣十足并且应老师的要求,我打算将自己完成作业和日常学习过程记录下来。
2.准备工作
首先我们需要去官网把p5.js的库下载下来,下载方式非常简单,只需要打开官网,点击“Down...
最近学习python,看到了别人写的一个求解字谜的程序,十分精简,充分应用了python的itertools模块,也体现其特有的语法。这里我稍作修改后,把每段代码都做了详细注释,适合初学者阅读
#coding=utf-8
字谜程序 如:
HAWAII + IDAHO + IOWA + OHIO == STATES
其中每个总目对应数字,上式的解为
510199 + 981