分形小结_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 分形小结

分形小结

 2014/3/22 19:07:56  沉沦的夏天  程序员俱乐部  我要评论(0)
  • 摘要:简单的说就是部分与整体以某种方式相似的形体,具有三个特性1.自相似性,部分是整体的缩影,2.自仿射性:局部到整体是在不同方向上的不等比例3.精细结构,即在任意小的比例尺度包含整体以下是编的一个分形树效果:如果加入随机变化的颜色,就可以做成礼花效果图:上图中的参数,没大多奥秘,其含义如下图所示,单元长度即AC,树枝伸展角度即W(程序中用A),主干生长角度即Theta(程序中用B表示),但测试结果好像树枝生长角度没多大意义,只是控制在屏幕中的旋转角度而已,分支长度系数即BE、BD
  • 标签:
简单的说就是部分与整体以某种方式相似的形体,具有三个特性
1. 自相似性,部分是整体的缩影,2.自仿射性:局部到整体是在不同方向上的不等比例
3.精细结构,即在任意小的比例尺度包含整体

以下是编的一个分形树效果




如果加入随机变化的颜色,就可以做成礼花效果图:




上图中的参数,没大多奥秘,其含义如下图所示,单元长度即AC,树枝伸展角度即W(程序中用A),主干生长角度即Theta(程序中用B表示),但测试结果好像树枝生长角度没多大意义,只是控制在屏幕中的旋转角度而已,分支长度系数即BE、BD、CG或者CF这四条相等线段与AC的比,主干长度系数即下一生长单元的长度与当前生长单元长度AC的比值。


下面是程序代码:
class="java" name="code">
package FractalTree;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.plaf.SliderUI;

public class Test {
	//用于存放文本框中字符串
	//分别对应于"单元长度","树枝伸展角度","主干生长角度","分支长度系数","顶点长度系数"的值
	private JTextField [] jtf=new JTextField[5];
	//给对应文本框内容赋初值
	private String [] jtf_str= new String[]{"120","35","15","0.6","0.4"};
	JRadioButton jrb1;//选中礼花效果的单选框
	JRadioButton jrb2;//选中长大效果的单选框
	private boolean flag=false;//是否进入效果标志
	Mylistener my;//监听器对象
	Graphics g;//中间面板的画布对象
	JPanel centerpal;//中间面板对象
	private Random random=new Random();//新建随机数类
	public static void main(String [] args){
		Test test=new Test();
		test.initUI();
	}

	//初始化界面
	public void initUI(){
		//新建窗体,并赋属性
		JFrame jf = new JFrame();
		jf.setSize(700,600);
		jf.setTitle("分形树");
		jf.setLocationRelativeTo(null);
		jf.setDefaultCloseOperation(3);
		jf.setResizable(false);
		//创建东边面板用于参数设置,中间面板画图
		 centerpal=new JPanel(){
			// Graphics g;
			public void paint(Graphics g){
				super.paint(g);
				int length=0;
				float a=0,b=0,z=0,c=0;//定义树枝伸展角度,主干生长角度,树枝长度系数,顶点长度系数
				//将文本框的内容取出
				for(int i=0;i<jtf_str.length;i++){
					jtf_str[i]=jtf[i].getText();
				}
				//各文本框的内容转换为对应数值
				a=Integer.parseInt(jtf_str[1]);
				b=Integer.parseInt(jtf_str[2]);
				a=(float) (a*Math.PI/180);
				b=(float) (b*Math.PI/180);
				length=Integer.parseInt(jtf_str[0]);
				z=Float.parseFloat(jtf_str[3]);
				c=Float.parseFloat(jtf_str[4]);
//				if(jrb2.isSelected()){
//						//选中长大效果
//						if(!flag){
//							flag=true;
//							z=z/10;
//							c=c/10;
//							length=50+(length-50)/10;
//							for(int i=0;i<10;i++){
//								z=z+z*i;
//								c=c+c*i;
//								length=50+(length-50)/10*(i+1);
//								try {
//									Thread.sleep(100);
//								} catch (InterruptedException e) {
//									// TODO Auto-generated catch block
//									e.printStackTrace();
//								}
//								this.draw(250, 600, length,a,b,z,c,g);
//								this.repaint();
//							}				
//					}
//				}
				
				
			
				//this.draw(300, 600, 120,35*Math.PI/180, 5*Math.PI/180,0.6,0.4,g);		
					this.draw(250, 600, length,a,b,z,c,g);	
					//如果礼花效果被选中
				if(jrb1.isSelected()){
					for(int i=0;i<10;i++){
						//休眠200ms
						try {
							Thread.sleep(20);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						//重绘
						this.repaint();
						
					}		
					
					}
				
				
			}
			//画生长单元的递归方法
			public void draw(int X,int Y,int LEN,double A,double B,double Z,double C,Graphics g){
				
				int len=0,x=0,y=0,x1=0,y1=0,x1l=0,y1l=0,x1r=0,y1r=0,x2=0,y2=0,x2l=0,y2l=0,x2r=0,y2r=0;
				if(LEN>7){
					len=(int)(LEN*Z);//获得树枝长度
					//获得B点(x1,y1)坐标
					 x1=(int)(X+len*Math.sin(B));
					 y1=(int)(Y-len*Math.cos(B));
					//获得B点(x1,y1)左右分支点坐标
					 x1l=x1+(int)(len*Math.sin(B-A)); 
					 y1l=y1-(int)(len*Math.cos(B-A));
					x1r=x1+(int)(len*Math.sin(B+A)); 
					 y1r=y1-(int)(len*Math.cos(B+A));
					
					//获得C点(x2,y2)坐标
					 x2=(int)(X+LEN*Math.sin(B));
					 y2=(int)(Y-LEN*Math.cos(B));
					//获得C点(x2,y2)左右分支点坐标
					 x2l=x2+(int)(len*Math.sin(B-A)); 
					 y2l=y2-(int)(len*Math.cos(B-A));
					 x2r=x2+(int)(len*Math.sin(B+A)); 
					 y2r=y2-(int)(len*Math.cos(B+A));
					 
					 //如果礼花效果选中,颜色为随机
					 if(jrb1.isSelected()){
						 g.setColor(new Color(random.nextInt(256), random.nextInt(256),random.nextInt(256)));
					 }
					 //否则,颜色固定为绿色
					 else {
						 g.setColor(Color.green);
					 }
					g.drawLine(X, Y, x2, y2);//主干线
					//B点(x1,y1)坐标处的两条分支
					g.drawLine(x1, y1, x1l, y1l);
					g.drawLine(x1, y1, x1r, y1r);
					//C点(x2,y2)坐标处的两条分支
					g.drawLine(x2, y2, x2l, y2l);
					g.drawLine(x2, y2, x2r, y2r);
					//递归
					this.draw(x2, y2, (int)(LEN*C), A, B+B, Z, C,g);
					this.draw(x1l, y1l, len, A, B-A, Z, C,g);
					this.draw(x1r, y1r, len, A, B+A, Z, C,g);
					this.draw(x2l, y2l, len, A, B-A, Z, C,g);
					this.draw(x2r, y2r, len, A, B+A, Z, C,g);
					}
				}
		};
		//中间面板背景颜色
		centerpal.setBackground(new Color(0,0,0));
		//创建监听器,传入中间面板
		my=new Mylistener(centerpal);
		//创建东边面板
		JPanel eastpal=this.creat_eastpal();
		jf.add(eastpal,BorderLayout.EAST);
		jf.add(centerpal,BorderLayout.CENTER);
		jf.setVisible(true);//窗体可见
		
		
	}
	
	//创建东边面板方法
	public JPanel creat_eastpal(){
		JPanel eastpal=new JPanel();
		eastpal.setPreferredSize(new Dimension(100,0));
		eastpal.setBackground(new Color(222,222,222));
		eastpal.setLayout(null);
		//5个标签和5个文本框
		String [] str_lab=new String[]{"单元长度:","树枝伸展角度:","主干生长角度:","分支长度系数:","顶点长度系数:"};
		for(int i=0;i<str_lab.length;i++){
			JLabel lab=new JLabel(str_lab[i]);
			lab.setBounds(5, 30+50*i, 90, 20);
			//每个标签下对应的文本框存入数组,方便取数
			 jtf[i]= new JTextField();
			jtf[i].setBounds(5, 55+50*i, 90, 25);
			jtf[i].setText(jtf_str[i]);
			eastpal.add(lab);
			eastpal.add(jtf[i]);
		}
		//创建单选框,选中为礼花效果,并加入东边面板中
		 //jcb=new JCheckBox("礼花效果");
		 jrb1=new JRadioButton("礼花效果");
		 jrb1.setBounds(5, 310, 90, 30);
		 jrb1.addActionListener(my);
		 eastpal.add(jrb1);
		
		//创建单选框,选中为长大效果,并加入东边面板中
		 //jcb=new JCheckBox("长大效果");
		 jrb2=new JRadioButton("长大效果");
		 jrb2.setBounds(5, 360, 90, 30);
		 //jrb2.addActionListener(my);
		 eastpal.add(jrb2);
		 
		//确定按钮,开始绘制
		JButton jb=new JButton("确定");
		jb.setBounds(15, 420, 70, 30);
		jb.addActionListener(my);
		eastpal.add(jb);
		return eastpal;	
	}


	
}



另外一个按钮监听器类
package FractalTree;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

public class Mylistener implements ActionListener{
	private JPanel panel;

	
	public Mylistener (JPanel panel){
		this.panel=panel;
	}
	
	public void actionPerformed(ActionEvent e) {
		
		if(e.getActionCommand().equals("确定")){
			panel.repaint();	
		}
	
	}
	
	
		
	
		


}



很遗憾,长大效果还没做出来,有待研究
  • 大小: 56.8 KB
  • 大小: 139.8 KB
  • 大小: 30.1 KB
  • 查看图片附件
  • 相关文章
发表评论
用户名: 匿名