如下图所示,先垂直绘制一根线段,然后在线段长度的三分之一处和三分之二处分别以固定夹角绘制另外两根线段,长度分别为原线段的2/3和1/3. 如此反复,直至线段长度小于某个较小的值。其中,线条颜色以及长度,夹角都可以自行进行微调。
先上代码:
主页面:
/**
* 怪兽先生
*/
private static final long serialVersionUID = 1L;
public PaintTree(){
setTitle("drawTree");
add(BorderLayout.CENTER,new DrawTreeCard(400, 10));
}
public static void main(String[] args){
PaintTree jFrame = new PaintTree();
jFrame.setLocationRelativeTo(null);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(500,500);
jFrame.setLocation(400, 200);
jFrame.setVisible(true);
}
card页面:private int min = 0;
private List<ArrayList<Integer>> points = new ArrayList<ArrayList<Integer>>();
private ArrayList<Integer> xList = new ArrayList<Integer>();
private ArrayList<Integer> yList = new ArrayList<Integer>();
public DrawTreeCard(int max,int min){
this.min = min;
getPoint(250,460,max,0.0);
}
public void paint(Graphics g) {
super.paintComponent(g);
for(int i=0;i< points.get(0).size();i+=2){
g.drawLine(points.get(0).get(i), points.get(1).get(i), points.get(0).get(i+1), points.get(1).get(i+1));
}
}
private void getPoint(int x,int y,int max1,double e){
if(max1<=min){
points.add(xList);
points.add(yList);
return;
}else{
xList.add(x);
yList.add(y);
int x1 = (int) (max1*Math.cos(Math.PI/2-e)+x);
int y1 = (int) (y-max1*Math.sin(Math.PI/2-e));
xList.add(x1);
yList.add(y1);
int maxRight = max1*2/3;
int x2 = x+(x1-x)/3;
int y2 = y-(y-y1)/3;
double e1 = e+Math.PI/6;
int maxLeft = max1/3;
int x3 = x+(x1-x)*2/3;
int y3 = y-(y-y1)*2/3;
double e2 = e-Math.PI/6;
getPoint(x3,y3,maxLeft,e2);
getPoint(x2,y2,maxRight,e1);
}
}
我将画枝叶和逻辑代码分开来写。重点解释逻辑代码:我递归出口在当树枝叶小于我设置的最小枝叶时,停止分支,否则根据我传入的起始坐标,现枝叶长度,角度计算终点坐标。当处理好现在的起始,终点坐标,再计算下一个起始坐标。
结果如下图:(当然枝叶颜色,转动角度可以自己设置)