为什么输出错误

时间:2019-04-16 04:18:45

标签: java l-systems

我应该得到一棵树。 但是我没有树。 我要的东西很长,不是树。

这是我的代码:

Main.java

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Main extends JFrame {

private static final long serialVersionUID = 1L;

public Main() {

    setTitle("Tree");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    //setResizable(false);

    add(new TreeDrawer(), BorderLayout.CENTER);
    getContentPane().setBackground(Color.BLACK);

    //button shit
    JButton generate = new JButton("Generate");
    generate.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

            TreeDrawer.generate();
            repaint();
        }
    });

    add(generate, BorderLayout.SOUTH);
    pack();
    setVisible(true);

}

public static void main(String[] args) {

    SwingUtilities.invokeLater(() -> {
        new Main();
    });

    }

}

TreeDrawer.java

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;

import javax.swing.JComponent;

public class TreeDrawer extends JComponent {

private static final long serialVersionUID = 1L;

public static final int ROOM_WIDTH = 1080;
public static final int ROOM_HEIGHT = 720 - 47;// 47 is the height of menu bar on top of jframe or some shit
static double len = 100; the length of each branch shit

public TreeDrawer() {
    setPreferredSize(new Dimension(ROOM_WIDTH, ROOM_HEIGHT));
}

private static String axiom = "F";
private static String sentence = axiom;

private static Graphics2D graphics;

//this shit will change on vary of l system, new rules and etc
private static String rules(char a) {
    if(a == 'F')//a rule
        return "FF+[+F-F-F]-[-F+F+F]";
    return "";//if nothing else works, shit
}

//generates the whole shit
    //probably correct
public static void generate() {
    len *= 0.5;//shrink the shit
    String nextSentence = "";
    for(int i = 0; i < sentence.length(); i++) {
        char current = sentence.charAt(i);
        nextSentence += rules(current);
    }
    sentence = nextSentence;
    System.out.println(sentence);
    turtle();
}

public static void turtle() {

    AffineTransform transform = null;//so you can save shit

    for(int i = 0; i < sentence.length(); i++) {
        char current = sentence.charAt(i);

        if(current == 'F') {//draw up
            graphics.drawLine(0, 0, 0, (int) -len);
            graphics.translate(0, -len);
        }

        else if(current == '+') {//right turn
            graphics.rotate(Math.PI / 6);
        }

        else if(current == '-') {//left turn
            graphics.rotate(-Math.PI / 6);
        }
        //probably wrong shit
        else if(current == '[') {//save transformations

            transform = graphics.getTransform();
        }
        //also probably wrong shit
        else if(current == ']') {//restore from last save
            graphics.setTransform(transform);
        }
    }
}

@Override
public void paintComponent(Graphics g) {//so that shit is drawn
    graphics = (Graphics2D) g;
    graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    super.paintComponent(graphics);
    graphics.translate(ROOM_WIDTH / 2, ROOM_HEIGHT - 10);
    graphics.setPaint(Color.WHITE);

    turtle();

}
}

我做错了什么。我不知道如何发布我得到的输出的屏幕截图,但是看起来完全不对。我知道我的L系统算法是正确的,因为它运行良好。但是我认为当我尝试保存和恢复转换状态时,出现了问题。保存转换状态的是方括号([和]。'['保存,']'从该保存中恢复)。但是我不知道怎么了。我需要帮助以查找问题所在。谢谢。

1 个答案:

答案 0 :(得分:2)

观察...

  1. 如果您没有创建Graphics的实例,则不应保留对该实例的引用超过使用所需的时间。相反,您应该将其作为参数传递给需要使用它的方法。这将使您免于遭受一些严重的怪异伪像和可能的NullPointerException
  2. 如果要转换Graphics上下文,最好先创建它的副本,因为它是所有要绘制的组件之间的共享资源。
  3. 在这种情况下,static不是您的朋友,而且设计拙劣。

考虑到所有这些,在基本级别上类似以下内容的工作

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Main extends JFrame {

    private static final long serialVersionUID = 1L;

    private TreeDrawer treeDrawer;

    public Main() {

        setTitle("Tree");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        //setResizable(false);

        treeDrawer = new TreeDrawer();
        add(treeDrawer, BorderLayout.CENTER);
        getContentPane().setBackground(Color.BLACK);

        //button shit
        JButton generate = new JButton("Generate");
        generate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                treeDrawer.generate();
                repaint();
            }
        });

        add(generate, BorderLayout.SOUTH);
        pack();
        setVisible(true);

    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            new Main();
        });

    }

    public class TreeDrawer extends JComponent {

        private static final long serialVersionUID = 1L;

        public static final int ROOM_WIDTH = 1080;
        public static final int ROOM_HEIGHT = 720 - 47;// 47 is the height of menu bar on top of jframe or some shit
        double len = 100;

        public TreeDrawer() {
            setPreferredSize(new Dimension(ROOM_WIDTH, ROOM_HEIGHT));
        }

        private String axiom = "F";
        private String sentence = axiom;

        private String rules(char a) {
            if (a == 'F')//a rule
            {
                return "FF+[+F-F-F]-[-F+F+F]";
            }
            return "";//if nothing else works, shit
        }

        //probably correct
        public void generate() {
            len *= 0.5;//shrink the shit
            String nextSentence = "";
            for (int i = 0; i < sentence.length(); i++) {
                char current = sentence.charAt(i);
                nextSentence += rules(current);
            }
            sentence = nextSentence;
            System.out.println(sentence);
//            turtle();
        }

        public void turtle(Graphics2D graphics) {

            AffineTransform transform = null;//so you can save shit

            for (int i = 0; i < sentence.length(); i++) {
                char current = sentence.charAt(i);

                if (current == 'F') {//draw up
                    graphics.drawLine(0, 0, 0, (int) -len);
                    graphics.translate(0, -len);
                } else if (current == '+') {//right turn
                    graphics.rotate(Math.PI / 6);
                } else if (current == '-') {//left turn
                    graphics.rotate(-Math.PI / 6);
                } //probably wrong shit
                else if (current == '[') {//save transformations

                    transform = graphics.getTransform();
                } //also probably wrong shit
                else if (current == ']') {//restore from last save
                    graphics.setTransform(transform);
                }
            }
        }

        @Override
        public void paintComponent(Graphics g) {//so that shit is drawn
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            super.paintComponent(g2d);
            g2d.translate(ROOM_WIDTH / 2, ROOM_HEIGHT - 10);
            g2d.setPaint(Color.WHITE);

            turtle(g2d);
            g2d.dispose();
        }
    }

}