写了个几何分形,准备在下次数媒课上展示
import io.netty.util.concurrent.DefaultThreadFactory;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
class TreeThread implements Runnable {
private FractalTree J;
private Random random = new Random();
private double ratio1;//调整树的稀疏度;
private double ratio2;//调整树的高度;
public TreeThread(FractalTree _J, double _ratio1, double _ratio2) {
J = _J;
ratio1 = _ratio1;
ratio2 = _ratio2;
}
public void run() {
int x = 598 + random.nextInt(3);
int y = 600;
J.get_g().setColor(new Color(1, 60, 10));
J.get_g().setStroke(new BasicStroke(4.0f));
J.get_g().drawLine(x, y, x, 450);
J.get_g().setStroke(new BasicStroke(1.0f));
J.drawTree(J.get_g(), x, 450, 100, 230 + random.nextInt(80), ratio1, ratio2);
}
}
class GrassThread implements Runnable {
private FractalTree J;
private Random random = new Random();
private double ratio1;
private double ratio2;
public GrassThread(FractalTree _J, double _ratio1, double _ratio2) {
J = _J;
ratio1 = _ratio1;
ratio2 = _ratio2;
}
public void run() {
for (int i = 0; i < 10; ++i) {
int x = random.nextInt(1200);
int y = 600;
J.drawTree(J.get_g(), x, y, 8, 270, ratio1, ratio2);
}
}
}
class FractalTree extends JFrame implements ActionListener {
private ThreadPoolExecutor executor;
private static final double PI = Math.PI / 180;
private Random random = new Random();
private JPanel panel = new JPanel();
private JPanel pnlCtl = new JPanel();
private JButton button1 = new JButton("New Tree");
private JButton button2 = new JButton("Clear");
private JButton button3 = new JButton("Exit");
private JButton button4 = new JButton("New Grass");
private Graphics2D g;
private boolean drawing = false;
public FractalTree(String title) {
super(title);
this.executor = new ThreadPoolExecutor(4, 4, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
new DefaultThreadFactory("draw"));
setSize(1200, 700);
this.add(panel, BorderLayout.CENTER);
pnlCtl.add(button1);
pnlCtl.add(button4);
pnlCtl.add(button2);
pnlCtl.add(button3);
button1.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);
button4.addActionListener(this); ;
this.add(pnlCtl, BorderLayout.SOUTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setLocationRelativeTo(null);
g = (Graphics2D) panel.getGraphics();
}
final public Graphics2D get_g() {
return g;
}
final public void actionPerformed(ActionEvent e) {
if (e.getSource() == button1) {
//开启新线程绘制树;
drawing = true;
TreeThread tree = new TreeThread(this, 2.0, 1.3);
executor.submit(tree);
}
if (e.getSource() == button4) {
drawing = true;
GrassThread grass = new GrassThread(this, 1.8, 2.0);
executor.submit(grass);
}
if (e.getSource() == button2) {
drawing = false;
panel.getGraphics().clearRect(0, 0, 1200, 700);
}
if (e.getSource() == button3) {
System.exit(0);
}
}
final public void drawTree(Graphics g, double x, double y, double L, double a,
double ratio, double ratio2) {
int red = 0;
int green = 0;
int blue = 0;
double x1, x2, x1L, x2L, x2R, x1R, y1, y2, y1L, y2L, y2R, y1R;
double deflection = 40 - random.nextInt(20);//侧干主干的夹角
double intersection = random.nextInt(40) - 20;//主干偏转角度
double depth = 2 + random.nextInt(2);//限制递归深度
if (!drawing) {
return;
}
if (L > depth) {
if (L < 8 && L > 2.5) {
red = random.nextInt(10);
green = random.nextInt(100) + 60;
blue = 0;
} else if (L < (ratio == 2.0 ? 2.3 : 2.468)) {
red = 15;
green = 230;
blue = 0;
} else {
red = 1;
green = 60;
blue = 10;
}
g.setColor(new Color(red, green, blue));
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);
//绘制下级主干;
drawTree(g, x2, y2, L / ratio2, a + intersection, ratio, ratio2);
//绘制侧杆;
drawTree(g, x2R, y2R, L / ratio, a + deflection, ratio, ratio2);
drawTree(g, x2L, y2L, L / ratio, a - deflection, ratio, ratio2);
drawTree(g, x1L, y1L, L / ratio, a - deflection, ratio, ratio2);
drawTree(g, x1R, y1R, L / ratio, a + deflection, ratio, ratio2);
}
}
}
public class TreeTest {
public static void main(String args[]) {
FractalTree t = new FractalTree("Fractal Tree");
}
}
这是跑出来的图