基于前一段时间对于分形的学习,让我们感受到了分形的强大魅力,于是在这基础上小组打算做一个分形的小软件,一来可以整合前一段时间的学习内容,达到温故出新知的目的。二来充分发挥小组成员的想象力,画出一些不同格调的图形或实现图形的动态效果。
分形训练是以小组为单位进行的,在各种图形中我挑选了最基本的进行实现,因为个人能力有限 :cry:
谢尔斯宾三角型(递归)
是以前就写过的一个图形 当我回头再看时发现许多代码都是不必要的
大致思路:先引入需要的类;定义类和各个点;实例化一个窗体;确定各个点坐标通过公式计算位置
package sample0604;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
//定义一个DP类
public class DrawPane {
int x1,x2,y1,y2,x3,y3;//定义各个点 整型
Graphics g;//获取画布g
public void JFrame(){//实例化一个表现框
JFrame jf = new JFrame();
jf.setSize(600,800);//定义大小
jf.setTitle("三角行");
jf.setVisible(true);
jf.setDefaultCloseOperation(3);
g=jf.getGraphics();
//加上自定义的鼠标事务器:鼠标开释时调用办法
jf.addMouseListener(new MouseAdapter() {
//鼠标按下时的点的坐标
public void mouseReleased(MouseEvent e) {
draw(e);
}
});
}
public void draw(MouseEvent e) {
x1=100;
y1=600;
x2=500;
y2=600;//确定各个点的坐标
draw_digui(x1,y1,x2,y2,10);
}
public void draw_digui(int x1,int y1,int x2,int y2,int count){
count--;
if(count>0){
x3=(int)Math.abs(x2+x1)/2;
y3=(int) Math.abs(y2-Math.sqrt(3)*Math.abs(x2-x1)/2);
g.drawLine(x1,y1,x2,y2);
g.drawLine(x1,y1,x3,y3);
g.drawLine(x2,y2,x3,y3);
int x11=(x1+x2)/2;
int y11=(y1+y2)/2;
int x22=(x2+x3)/2;
int y22=(y2+y3)/2;
int x33=(x1+x3)/2;
int y33=(y1+y3)/2;
g.drawLine(x11,y11,x22,y22);
g.drawLine(x11,y11,x33,y33);
g.drawLine(x22,y22,x33,y33);
draw_digui(x1,y1,x11,y11,count);
draw_digui(x11,y11,x2,y2,count);
draw_digui(x33,y33,x22,y22,count);
}
}
public static void main (String []args){
DrawPane san = new DrawPane();
san.JFrame();
}
}
第二个是哈夫曼树(可以调角度和大小)
package Draw;
import java.awt.Color;//引入颜色
import java.awt.FlowLayout;//流式布局
import java.awt.Graphics;//画布
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Draw1 extends JFrame {
private static final long serialVersionUID = 1L;
private Graphics g;
//整体旋转角度
private int rotateAngle = 0;
//三角形左边角度
private int triangleAngle = 30;
//递归次数
private int callTimes = 30;
private JSlider js;
private JSlider js2;
public static void main(String args[]){
Draw1 draw = new Draw1();
draw.initUI();
}
public void initUI(){
setSize(400,400);
setLayout(new FlowLayout());
js = new JSlider();
js.setMinimum(-180);
js.setMaximum(180);
js.setValue(30);
js.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent e){
g.setColor(Draw1.this.getBackground());
g.fillRect(0, 50, Draw1.this.getWidth(), Draw1.this.getHeight());
g.setColor(Color.green);
triangleAngle = js.getValue();
int width = Draw1.this.getWidth()/9;
draw(new Point(Draw1.this.getWidth()/2-width/2,Draw1.this.getHeight()-10), width, triangleAngle ,rotateAngle, callTimes);
}
});
this.add(js);
js2 = new JSlider();
js2.setMinimum(-180);
js2.setMaximum(180);
js2.setValue(0);
js2.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent e){
g.setColor(Draw1.this.getBackground());
g.fillRect(0, 50, Draw1.this.getWidth(), Draw1.this.getHeight());
g.setColor(Color.green);
rotateAngle = js2.getValue();
int width = Draw1.this.getWidth()/9;
draw(new Point(Draw1.this.getWidth()/2-width/2,Draw1.this.getHeight()-10), width, triangleAngle ,rotateAngle, callTimes);
}
});
this.add(js2);
this.setVisible(true);
g = this.getGraphics();
}
public void draw(Point p, double length, double angle, double rotate, int times){
if(times-- < 0 || length < 2)
return;
Point p2 = getSecondPoint(p, length, rotate);
Point p3 = getSecondPoint(p2, length, rotate+90);
Point p4 = getSecondPoint(p3, length, rotate+180);
//角度转换成弧度
double ra = angle * Math.PI / 180;
Point p5 = getSecondPoint(p4, Math.abs(Math.cos(ra)*length), rotate+angle);
draw(p4,Math.abs(Math.cos(ra)*length), angle, angle+rotate, times);
draw(p5,Math.abs(Math.sin(ra)*length), angle, 270+angle+rotate, times);
g.drawLine(p.x, p.y, p2.x, p2.y);
g.drawLine(p2.x, p2.y, p3.x, p3.y);
g.drawLine(p3.x, p3.y, p4.x, p4.y);
g.drawLine(p4.x, p4.y, p.x, p.y);
g.drawLine(p4.x, p4.y, p5.x, p5.y);
g.drawLine(p3.x, p3.y, p5.x, p5.y);
}
//根据一个点、长度和角度计算另一个点的坐标
public Point getSecondPoint(Point p, double length, double angle){
//角度转换成弧度
angle = angle * Math.PI / 180;
double x = p.getX()+Math.cos(angle)*length;
double y = p.getY()-Math.sin(angle)*length;
return new Point((int)x,(int)y);
}
}
小结:分形之美只有在过程中才能体会,开始的时候只能看到图形表面的美丽,只有在编码的过程中才能体会其神秘感,看似杂乱无章的图形,运用一定的规则可以画出各种让人赏心悦目的图形来。现实生活中,很多事情都是这样的,在找寻到一定的规律之后就可以事半功倍,达到目的。 :arrow:
分形训练是以小组为单位进行的,在各种图形中我挑选了最基本的进行实现,因为个人能力有限 :cry:
谢尔斯宾三角型(递归)
是以前就写过的一个图形 当我回头再看时发现许多代码都是不必要的
大致思路:先引入需要的类;定义类和各个点;实例化一个窗体;确定各个点坐标通过公式计算位置
package sample0604;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
//定义一个DP类
public class DrawPane {
int x1,x2,y1,y2,x3,y3;//定义各个点 整型
Graphics g;//获取画布g
public void JFrame(){//实例化一个表现框
JFrame jf = new JFrame();
jf.setSize(600,800);//定义大小
jf.setTitle("三角行");
jf.setVisible(true);
jf.setDefaultCloseOperation(3);
g=jf.getGraphics();
//加上自定义的鼠标事务器:鼠标开释时调用办法
jf.addMouseListener(new MouseAdapter() {
//鼠标按下时的点的坐标
public void mouseReleased(MouseEvent e) {
draw(e);
}
});
}
public void draw(MouseEvent e) {
x1=100;
y1=600;
x2=500;
y2=600;//确定各个点的坐标
draw_digui(x1,y1,x2,y2,10);
}
public void draw_digui(int x1,int y1,int x2,int y2,int count){
count--;
if(count>0){
x3=(int)Math.abs(x2+x1)/2;
y3=(int) Math.abs(y2-Math.sqrt(3)*Math.abs(x2-x1)/2);
g.drawLine(x1,y1,x2,y2);
g.drawLine(x1,y1,x3,y3);
g.drawLine(x2,y2,x3,y3);
int x11=(x1+x2)/2;
int y11=(y1+y2)/2;
int x22=(x2+x3)/2;
int y22=(y2+y3)/2;
int x33=(x1+x3)/2;
int y33=(y1+y3)/2;
g.drawLine(x11,y11,x22,y22);
g.drawLine(x11,y11,x33,y33);
g.drawLine(x22,y22,x33,y33);
draw_digui(x1,y1,x11,y11,count);
draw_digui(x11,y11,x2,y2,count);
draw_digui(x33,y33,x22,y22,count);
}
}
public static void main (String []args){
DrawPane san = new DrawPane();
san.JFrame();
}
}
第二个是哈夫曼树(可以调角度和大小)
package Draw;
import java.awt.Color;//引入颜色
import java.awt.FlowLayout;//流式布局
import java.awt.Graphics;//画布
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Draw1 extends JFrame {
private static final long serialVersionUID = 1L;
private Graphics g;
//整体旋转角度
private int rotateAngle = 0;
//三角形左边角度
private int triangleAngle = 30;
//递归次数
private int callTimes = 30;
private JSlider js;
private JSlider js2;
public static void main(String args[]){
Draw1 draw = new Draw1();
draw.initUI();
}
public void initUI(){
setSize(400,400);
setLayout(new FlowLayout());
js = new JSlider();
js.setMinimum(-180);
js.setMaximum(180);
js.setValue(30);
js.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent e){
g.setColor(Draw1.this.getBackground());
g.fillRect(0, 50, Draw1.this.getWidth(), Draw1.this.getHeight());
g.setColor(Color.green);
triangleAngle = js.getValue();
int width = Draw1.this.getWidth()/9;
draw(new Point(Draw1.this.getWidth()/2-width/2,Draw1.this.getHeight()-10), width, triangleAngle ,rotateAngle, callTimes);
}
});
this.add(js);
js2 = new JSlider();
js2.setMinimum(-180);
js2.setMaximum(180);
js2.setValue(0);
js2.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent e){
g.setColor(Draw1.this.getBackground());
g.fillRect(0, 50, Draw1.this.getWidth(), Draw1.this.getHeight());
g.setColor(Color.green);
rotateAngle = js2.getValue();
int width = Draw1.this.getWidth()/9;
draw(new Point(Draw1.this.getWidth()/2-width/2,Draw1.this.getHeight()-10), width, triangleAngle ,rotateAngle, callTimes);
}
});
this.add(js2);
this.setVisible(true);
g = this.getGraphics();
}
public void draw(Point p, double length, double angle, double rotate, int times){
if(times-- < 0 || length < 2)
return;
Point p2 = getSecondPoint(p, length, rotate);
Point p3 = getSecondPoint(p2, length, rotate+90);
Point p4 = getSecondPoint(p3, length, rotate+180);
//角度转换成弧度
double ra = angle * Math.PI / 180;
Point p5 = getSecondPoint(p4, Math.abs(Math.cos(ra)*length), rotate+angle);
draw(p4,Math.abs(Math.cos(ra)*length), angle, angle+rotate, times);
draw(p5,Math.abs(Math.sin(ra)*length), angle, 270+angle+rotate, times);
g.drawLine(p.x, p.y, p2.x, p2.y);
g.drawLine(p2.x, p2.y, p3.x, p3.y);
g.drawLine(p3.x, p3.y, p4.x, p4.y);
g.drawLine(p4.x, p4.y, p.x, p.y);
g.drawLine(p4.x, p4.y, p5.x, p5.y);
g.drawLine(p3.x, p3.y, p5.x, p5.y);
}
//根据一个点、长度和角度计算另一个点的坐标
public Point getSecondPoint(Point p, double length, double angle){
//角度转换成弧度
angle = angle * Math.PI / 180;
double x = p.getX()+Math.cos(angle)*length;
double y = p.getY()-Math.sin(angle)*length;
return new Point((int)x,(int)y);
}
}
小结:分形之美只有在过程中才能体会,开始的时候只能看到图形表面的美丽,只有在编码的过程中才能体会其神秘感,看似杂乱无章的图形,运用一定的规则可以画出各种让人赏心悦目的图形来。现实生活中,很多事情都是这样的,在找寻到一定的规律之后就可以事半功倍,达到目的。 :arrow: