画出一个棵树

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

}

}

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值