2.2.1題目描述
畫出一個棵樹,樹的一個簡單表示形式如下:
圖一 樹的簡單
選擇一個樹枝,然後生出這個樹枝的兩個子樹枝,子樹枝是生出的位置分別爲這個父樹枝的1/3處和2/3處,子樹枝的長度選擇合適即可,此處選擇的長度分別爲父樹枝的1/3和2/3,然後判斷是否滿足結束條件,如果滿足,則停止生成子樹枝,如果不滿足則繼續把子樹枝當做父樹枝生成其子樹枝。
2.2.2程序使用說明
直接運行Client.java文件,出現圖形化界面,可以在Client.java中修改輸入條件改變樹形結構。如下這條語句是Client.java文件中的一條調用語句,語句中有五個傳入參數,參數1,2表示整個圖形的寬高,第三個參數顯示樹的主軸高度,第四個參數表示樹的旋轉的角度,第五個參數表示樹杈的角度。
2.2.3簡要分析和設計
程序開始輸入兩個點座標,代表最開始的主樹幹,然後分別計算這個主樹幹的兩個子樹幹的角度,長度,然後在分別計算兩個子樹幹的兩個點的座標,並保存在一個集合中,然後遞歸計算兩個子樹幹的孩子樹幹,直到達到結束條件爲止。最後將集合中的點對畫出,則形成一個樹。其中用到兩對公式,用於計算三等分點和根據座標和長度計算線段的另一個座標。
公式一:
公式二:
僞代碼:
輸入:最開始主幹的線段的下端座標x,y,主幹長度len,主幹開始角度angle,及樹杈的角度increase
輸出:在面板上畫出一棵樹
Draw(x,y,len,angle,increase)
X1=y - cos(angle)*l;//父枝幹的上端座標
Y1=x + sin(angle)*l;
//計算孩子節點開始座標點
//孩子節點1
x3 = (2*x1+x)/3
Y3=(2*y1+y)/3
X4=(2*x+x1)/3
Y4=(2*y+y1)/3
//畫出父枝幹
Drawline(x,y,x1,y1);
//遞歸畫左側孩子節點,increase爲樹杈角度
Draw(x3,y3,len/3,angle-increase,increase)
//遞歸畫出右孩子節點
Draw(x4,y4,len*2/3,angle+increase,increase)
算法複雜度:由結束條件而定
2.2.4測試用例
測試用例一:(400,800,0,800,30)
結果:
測試用例二:(400,800,90,800,40)
結果:
測試用例三:(400,800,200,800,20)
結果:
2.2.5源代碼
目錄結構:
package one.two;
import javax.swing.JFrame;
/**
* @author ym
*/
public class Client {
public static void main(String[]args) {
JFrame jf =new JFrame("樹");
jf.setSize(800,800);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
PaintingTrre treePanel = new PaintingTrre(400,800,800,300,20);
jf.add(treePanel);
jf.setVisible(true);
}
}
package one.two;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class PaintingTrre extends JPanel {
/**
* 序列id
*/
private static final long serialVersionUID = 1L;
//中間選段起始座標
private int x=0;
private int y=0;
//中間線段起始長度
private double len=0;
//增長角度
private double increaseAngle=0;
//旋轉角度
private double rotateAngle=0;
/**
* 初始化
*
* @param x
* @param y
* @param len
* @param rotateAngle
* @param increaseAngle
*/
public PaintingTrre(int x,int y,double len,double rotateAngle,double increaseAngle){
this.x=x;
this.y=y;
this.len = len;
this.rotateAngle = rotateAngle;
this.increaseAngle=increaseAngle;
}
/**
* 重寫畫圖類
*/
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int w2 = getWidth() / 2;
int h2 = getHeight() / 2;
g2d.rotate(-Math.toRadians(rotateAngle), w2, h2);
super.paintComponent(g);
draw(g2d,this.x, this.y,this.len,0);
}
/**
* 角度
*
* @param x
* @param y
* @param len
* @param angle
*/
public void draw(Graphics g,int x,int y,double len,double angle){
if(len>10){
int x1=x+(int)(Math.sin(Math.toRadians(angle))*len);
int y1=y-(int)(Math.cos(Math.toRadians(angle))*len);
//畫出父枝幹
g.drawLine(x, y, x1, y1);
/**
* 計算三等分點
* X3=(X2+2X1)/3,Y3=(Y2+2Y1)/3
* X4=(2X2+X1)/3,Y4=(2Y2+Y1)/3
*/
int x3=(x+2*x1)/3;
int y3=(y+2*y1)/3;
int x4=(2*x+x1)/3;
int y4=(2*y+y1)/3;
draw(g, x3, y3, len/3, angle-increaseAngle);
draw(g, x4, y4, len*2/3, angle+increaseAngle);
}
}
}