绘制谢尔宾斯基的三角Java中 [英] Drawing Sierpinski's Triangle in Java

查看:216
本文介绍了绘制谢尔宾斯基的三角Java中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些问题,我的code绘制谢尔宾斯基的三角形(或谢尔宾斯基的垫片),但我不知道是什么问题。为三角形的线绘制,那么所有的分形,然后消失。帮助?

 进口的javax.swing *。
进口java.awt中的*。公共类SierpinskiGasket扩展的JFrame {点x =新的点(5,545)
      Y =新的点(300,25)
      Z =新的点(605545),
      电流= X,目标;
私人诠释计数= 0;公共SierpinskiGasket(){
    超(谢尔宾斯基垫片);
    的setSize(610550);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    。的getContentPane()的setBackground(Color.WHITE);
    setLocationRelativeTo(NULL);
    的setResizable(假);
    调用setVisible(真);
}公共无效漆(图形G){
    super.paint(G);
    如果(计数== 0){
    g.drawLine(x.x表示,xy格式的,y.x,y.y);
    g.drawLine(x.x表示,xy格式的,z.x,z.y);
    g.drawLine(z.x,z.y,y.x,y.y);
    }其他{
        而(COUNT< 10000){
            INT选择=(int)的(的Math.random()* 3);
            开关(选择){
                情况下0:目标= X;打破;
                案例1:目标= Y;打破;
                案例2:目标= Z;打破;
                默认:System.exit(0);
            }
            电流=中点(电流,目标);
            g.drawRect(current.x,current.y,5,5);
            重绘();
            算上++;
        }
    }
    算上++;
}公共点的中点(A点,B点){
    返回新的点((Math.round(a.x + b.x)/ 2),
                     (Math.round(a.y + b.y)/ 2));
}公共静态无效的主要(字串[] args){
    新SierpinskiGasket();
}
}


解决方案

  1. 请不要从顶层容器扩展(如的JFrame ),你不增加的好处什么吧。

  2. 避免绘画到顶层容器。相反,使用类似的JP​​anel

  3. 避免重写油漆,使用的paintComponent 来代替。请参见执行风俗画了解详情

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

油漆被称为响应于一些事件时,重绘系统决定的部分或需要更新整个UI的。油漆是破坏性的,也就是说,当油漆被调用时,图形将完全刷新,需要你重建从零开始的输出。

相反。

写一个递归算法,可以画成类似的BufferedImage ,并绘制在的paintComponent ...

更新

在Swing绘画是由的RepaintManager ,这是它的责任控制,以确定什么时候重绘屏幕。你似乎在想的油漆是你的东西控制,当它不是。

您需要或者是ppared完全重绘UI还是有一个缓冲prepared可以绘制到UI,根据您的需要$ P $。

 进口java.awt.BorderLayout中;
进口java.awt.Dimension中;
进口java.awt.EventQueue中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口java.awt.Rectangle中;
进口java.awt.geom.AffineTransform中;
进口java.awt.geom.Path2D;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.UIManager中;
进口javax.swing.UnsupportedLookAndFeelException;公共类SierpinskisGasket {    公共静态无效的主要(字串[] args){
        新SierpinskisGasket();
    }    公共SierpinskisGasket(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
                }                JFrame的帧=新的JFrame(测试);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(新的BorderLayout());
                frame.add(新TestPane());
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);
            }
        });
    }    公共类TestPane继承JPanel {        公共TestPane(){
        }        @覆盖
        公共尺寸的get preferredSize(){
            返回新尺寸(200,200);
        }        @覆盖
        保护无效paintComponent(图形G){
            super.paintComponent方法(G);
            Graphics2D的G2D =(Graphics2D的)g.create();
            BaseShape基地=新BaseShape(Math.min(的getWidth()的getHeight()));
            矩形范围= base.getBounds();
            INT X =(的getWidth() - bounds.width)/ 2;
            INT Y =(的getHeight() - bounds.height)/ 2;
            base.transform(AffineTransform.getTranslateInstance(X,Y));
            g2d.fill(基峰);
            g2d.dispose();
        }
    }    公共类BaseShape扩展Path2D.Float {        公共BaseShape(浮点大小){            漂浮小尺寸=大小/ 2F;
            三角顶部=新的三角形(小尺寸);
            top.transform(AffineTransform.getTranslateInstance((大小 - 小尺寸)/ 2,0));
            追加(顶部,FALSE);            三角左=新的三角形(小尺寸);
            left.transform(AffineTransform.getTranslateInstance(0,小尺寸));
            追加(左,FALSE);            三角右=新的三角形(小尺寸);
            right.transform(AffineTransform.getTranslateInstance(小尺寸,小尺寸));
            追加(右,FALSE);        }    }    公共类三角形扩展Path2D.Float {        公共三角(浮点大小){            的moveTo(尺寸/ 2F,0);
            了lineTo(尺寸,大小);
            了lineTo(0,大小);
            调用closePath();        }    }}

您应该永远不会被调用从油漆任何可能改变UI的状态,并触发另一重绘,否则,你将要在重新绘制,最终将消耗你的CPU的结束周期结束了。

您也应该看看在AWT 绘画和Swing

I'm having some issues with my code to draw a Sierpinski's Triangle (or Sierpinski's Gasket), but I'm not sure what the problem is. The lines for the triangle are drawn, then all the fractals, then it disappears. Help?

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

解决方案

  1. Don't extend from a top level container (like JFrame), you're not adding anything of benefit to it.
  2. Avoid painting to top level containers. Instead use something like JPanel.
  3. Avoid overriding paint, use paintComponent instead. See Performing Custom Painting for more details

This is not how paint works (and I'm not going to try to rewrite your code to make it).

Paint is called in response to a number of events when the repaint system decides that part or whole of the UI needs to be updated. Paints are destructive, that is, when paint is called, the Graphics will be completely refreshed, requiring you to "rebuild" the output from scratch.

Instead.

Write a recursive algorithm that can paint to something like BufferedImage and draw that within the paintComponent...

Updated

Painting in Swing is controlled by the RepaintManager, it is it's responsibility to determine what and when to repaint the screen. You seem to be thinking the paint is something your control, when it's not.

You need to either be prepared to completely repaint the UI or have a buffer prepared that you can paint onto the UI, depending on your needs.

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

        }

    }

}

You should never be calling anything from paint that could alter the state of the UI and trigger another repaint, otherwise you are going to end up in a end cycle of repaints that will eventually consume your CPU.

You should also take a look at Painting in AWT and Swing

这篇关于绘制谢尔宾斯基的三角Java中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆