绘图谢尔宾斯基的三角在Java中(Drawing Sierpinski's Triangle

2019-09-02 05:11发布

我有一些问题,我的代码绘制谢尔宾斯基的三角(或谢尔宾斯基的垫片),但我不知道是什么问题。 对于三角线被描绘,那么所有的分形,然后消失。 救命?

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(x.x,x.y,y.x,y.y);
    g.drawLine(x.x,x.y,z.x,z.y);
    g.drawLine(z.x,z.y,y.x,y.y);
    } 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+b.x)/2),
                     (Math.round(a.y+b.y)/2));
}

public static void main(String[] args) {
    new SierpinskiGasket();
}
}

Answer 1:

  1. 不要从顶层容器(如延长JFrame ),你不增加的好处什么的。
  2. 避免画到顶层容器。 相反,使用类似JPanel
  3. 避免压倒一切的paint ,用paintComponent代替。 请参阅执行自定义绘制更多细节

这不是油漆是如何工作的(我不打算尝试重写你的代码,使之)。

当重绘系统决定部分或需要更新整个UI的油漆被称为响应一些事件。 油漆是破坏性的,也就是说,当油漆被调用时, 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();

        }

    }

}

你应该永远不会被调用从任何paint ,可能改变用户界面的状态,并引发另一repaint ,否则你会在重新绘制,最终将消耗你的CPU的结束周期结束。

你也应该看看画中的AWT和Swing



Answer 2:

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

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

所以,你的“选择”变量始终是零......可能有一些跟你的问题吗?



Answer 3:

只是去掉repaint()调用固定它。



文章来源: Drawing Sierpinski's Triangle in Java