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);
}
}
}