分形几何 之 美妙的树 把递归用到极致
"一尺之锤、日取其半、万世不竭"这和分形几何的思想极为相似。
无论从美学的观点还是从科学的观点,许多人在第一次见到分形时都有新的感受。----曼德勃罗
在外形看来分形艺术似乎是魔术。但不会有任何数学家疏于了解他的结构和意义。
分形是自然界的几何学。我们看到了一些以前没有看到过得东西,它让我们用另一种眼光去看世界。
蜿蜒曲折的海岸线、起伏不定的山脉、粗糙不堪的断层、变换无常的浮云、九曲回肠的河流、纵横交错的血管、令人眼花缭乱的繁星,他们都那么的极不规则、极不光滑。粗略的说这些对象都是分形。分形几何据有自相似性、自仿射性。分形几何与欧式几何有着明显的区别:首先它是无规则的(不光滑的)、他是无限的、可以从局部看出整体、看上去复杂但结构相当简单、他的维数一般为分数
想了解分形几何可以去baidu百科找http://baike.baidu.com/view/44498.htm
下面我就以递归的思想,采用java语言画一树叶
截图看一下:
import java.awt.*; import java.awt.event.*; import java.util.Random; import javax.swing.*; /** * * @author http://javaflex.iteye.com/ * */ public class GraphicsTest extends JFrame implements ActionListener { public static final double PI = Math.PI / 180; JPanel panel; JPanel pnlCtl; JButton button; JButton button2; Graphics2D g2; public GraphicsTest(String string) { super(string); } public void init() { panel = new JPanel(); pnlCtl = new JPanel(); button = new JButton("分形树"); button2 = new JButton("清除"); this.add(panel, BorderLayout.CENTER); button.addActionListener(this); button2.addActionListener(this); pnlCtl.add(button); pnlCtl.add(button2); this.add(pnlCtl, BorderLayout.NORTH); setSize(800, 600); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); Dimension winSize = Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation((winSize.width - this.getWidth()) / 2, (winSize.height - this.getHeight()) / 2); g2 = (Graphics2D) panel.getGraphics(); } public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); GraphicsTest testPanel = new GraphicsTest("分形树:QQ:三2824七676"); testPanel.init(); } @Override public void actionPerformed(ActionEvent e) { if ("分形树".equals(e.getActionCommand())) { drawLeaf(g2, 400, 500, 100, 210+random.nextInt(100)); } else if ("清除".equals(e.getActionCommand())) { panel.getGraphics().clearRect(0, 0, 800, 800); } } Random random=new Random(); public void drawLeaf(Graphics g, double x, double y, double L, double a) { //random=new Random(); //可以方面速度画以了解其算法 // try { // Thread.sleep(1000); // } catch (InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } int red = random.nextInt(127); int green = random.nextInt(127); int blue = random.nextInt(127); //随机颜色 g.setColor(new Color(red, green, blue)); double x1, x2, x1L, x2L, x2R, x1R, y1, y2, y1L, y2L, y2R, y1R; float deflection = 50-random.nextInt(20);//侧干主干的夹角 float intersection = random.nextInt(40)-20;//主干偏转角度 float depth = 2+random.nextInt(2);//限制递归深度 float ratio = 3f;//主干侧干长度比(可调整使其更茂密或稀疏) float ratio2 = 1.2f;//上级主干与本级主干长度比(可调整使其变高低) if (L > depth) { x2=x+L*Math.cos(a*PI); y2=y+L*Math.sin(a*PI); x2R=x2+L/ratio*Math.cos((a+deflection)*PI); y2R=y2+L/ratio*Math.sin((a+deflection)*PI); x2L=x2+L/ratio*Math.cos((a-deflection)*PI); y2L=y2+L/ratio*Math.sin((a-deflection)*PI); x1=x+L/ratio*Math.cos(a*PI); y1=y+L/ratio*Math.sin(a*PI); x1L=x1+L/ratio*Math.cos((a-deflection)*PI); y1L=y1+L/ratio*Math.sin((a-deflection)*PI); x1R=x1+L/ratio*Math.cos((a+deflection)*PI); y1R=y1+L/ratio*Math.sin((a+deflection)*PI); g.drawLine((int)x,(int)y,(int)x2,(int)y2); g.drawLine((int)x2,(int)y2,(int)x2R,(int)y2R); g.drawLine((int)x2,(int)y2,(int)x2L,(int)y2L); g.drawLine((int)x1,(int)y1,(int)x1L,(int)y1L); g.drawLine((int)x1,(int)y1,(int)x1R,(int)y1R); drawLeaf(g,x2,y2,L/ratio2,a+intersection); drawLeaf(g,x2R,y2R,L/ratio,a+deflection); drawLeaf(g,x2L,y2L,L/ratio,a-deflection); drawLeaf(g,x1L,y1L,L/ratio,a-deflection); drawLeaf(g,x1R,y1R,L/ratio,a+deflection); } } }
希望对大家有所帮助,特别是对分形几何感兴趣的朋友,希望可以进一步交流