用Java绘制Sierpinski的三角形

我的代码有一些问题需要绘制一个Sierpinski的三角形(或者Sierpinski的垫片),但我不确定问题是什么。 绘制三角形的线条,然后绘制所有分形线,然后消失。 帮帮我?

import javax.swing.*; import java.awt.*; public class SierpinskiGasket extends JFrame { Point x=new Point(5,545), y=new Point(300,25), z=new Point(605,545), current=x, target; private int count=0; public SierpinskiGasket () { super("Sierpinski Gasket"); setSize(610,550); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); getContentPane().setBackground(Color.WHITE); setLocationRelativeTo(null); setResizable(false); setVisible(true); } public void paint(Graphics g) { super.paint(g); if(count==0) { g.drawLine(xx,xy,yx,yy); g.drawLine(xx,xy,zx,zy); g.drawLine(zx,zy,yx,yy); } else { while(count<10000) { int choice=(int)(Math.random()*3); switch(choice) { case 0: target=x; break; case 1: target=y; break; case 2: target=z; break; default: System.exit(0); } current=midpoint(current,target); g.drawRect(current.x,current.y,5,5); repaint(); count++; } } count++; } public Point midpoint(Point a, Point b) { return new Point((Math.round(a.x+bx)/2), (Math.round(a.y+by)/2)); } public static void main(String[] args) { new SierpinskiGasket(); } } 

  1. 不要从顶级容器(如JFrame )扩展,你不会添加任何好处。
  2. 避免油漆到顶层容器。 而是使用像JPanel这样的东西。
  3. 避免重写paint ,而是使用paintComponent 。 有关详细信息,请参阅执行自定义绘画

这不是绘画的工作方式(我不会尝试重写你的代码来制作它)。

当重绘系统决定需要更新UI的一部分或全部时,将调用Paint来响应许多事件。 绘制是破坏性的,也就是说,当调用paint时, Graphics将被完全刷新,需要您从头开始“重建”输出。

代替。

编写一个递归算法,可以绘制到像BufferedImage这样的东西,然后在paintComponent绘制…

更新

Swing中的绘画由RepaintManager控制,它有责任确定重绘屏幕的内容和时间。 你似乎认为paint是你可以控制的东西,当它不是时。

您需要准备好完全重新绘制UI或准备好可以根据需要绘制到UI上的缓冲区。

在此处输入图像描述

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.Path2D; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class SierpinskisGasket { public static void main(String[] args) { new SierpinskisGasket(); } public SierpinskisGasket() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { public TestPane() { } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); BaseShape base = new BaseShape(Math.min(getWidth(), getHeight())); Rectangle bounds = base.getBounds(); int x = (getWidth() - bounds.width) / 2; int y = (getHeight() - bounds.height) / 2; base.transform(AffineTransform.getTranslateInstance(x, y)); g2d.fill(base); g2d.dispose(); } } public class BaseShape extends Path2D.Float { public BaseShape(float size) { float subSize = size / 2f; Triangle top = new Triangle(subSize); top.transform(AffineTransform.getTranslateInstance((size - subSize) / 2, 0)); append(top, false); Triangle left = new Triangle(subSize); left.transform(AffineTransform.getTranslateInstance(0, subSize)); append(left, false); Triangle right = new Triangle(subSize); right.transform(AffineTransform.getTranslateInstance(subSize, subSize)); append(right, false); } } public class Triangle extends Path2D.Float { public Triangle(float size) { moveTo(size / 2f, 0); lineTo(size, size); lineTo(0, size); closePath(); } } } 

你永远不应该从可以改变UI状态并触发另一个repaint paint中调用任何东西,否则你将最终进入重绘的最终循环,最终会占用你的CPU。

您还应该看看AWT和Swing中的绘画

 int i = ((int)Math.random()*3); System.out.println("i:"+i); 

当我运行上面的时候,我总是得到0

所以你的“选择”变量总是为零……可能与你的问题有关?

只需删除repaint()调用就可以修复它。