我如何绘制元胞自动机
How i can draw a cellular automaton
我在 java 做元胞自动机练习,遇到了一个问题。
CA的逻辑部分工作正常,如果我想把它安排在控制台上就可以了,但我想把它画在面板上,当它是 1 画一个黑色方块时,当它为 0 时绘制一个白色方块
让我们进入问题
发生的事情是整个逻辑运行正常,但是绘制java时只绘制了最新一代的CA,我读到java paintComponent仅在java决定时起作用到而不是何时被调用。
My question is: how the best way to solve this problem and how to do it.
我想到了一些事情,但因为我不知道java所以我决定问你
我想过也许把所有的数组保存到一个数组中然后从中绘制(但我不知道我该怎么做)我想也许每个循环都有一种绘制的方法,但我没有找到了(我用了repaint()但是没用)
无论如何,如果有人能给我一个解决方案,我将不胜感激,我已经遇到这个问题好几天了,我还没有找到解决方案,下面是所有代码
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class CA extends JFrame {
Rules rules = new Rules();
public CA() {
super("Cellular Automaton");
setLayout(new BorderLayout());
add(new GUI_CA(), BorderLayout.CENTER);
pack();
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new CA();
}
});
}
}
}
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class GUI_CA extends JPanel {
int cellSize = 10;
Rules rules = new Rules();
private BufferedImage img;
private Graphics2D g2d;
public GUI_CA() {
img = new BufferedImage(cellSize, cellSize, BufferedImage.TYPE_INT_RGB);
g2d = (Graphics2D) img.createGraphics();
evolution();
}
public void evolution() {
rules.cells = new int[987/cellSize];
rules.cells[rules.cells.length/2] = 1;
System.out.println(Arrays.toString(rules.cells));
for (int generationCount = 0; generationCount < 10; generationCount++) {
rules.generate();
System.out.println(Arrays.toString(rules.cells));
repaint();
}
}
public void drawCA(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
for (int i = 1; i < rules.cells.length -1; i++) {
if (rules.cells[i] == 1) {
g2d.setColor(Color.BLACK);
g2d.fillRect(i * cellSize, rules.generation * 5, cellSize, cellSize);
System.out.println(Arrays.toString(rules.cells));
}else {
g2d.setColor(Color.WHITE);
g2d.fillRect(i * cellSize, rules.generation * 5, cellSize, cellSize);
}
}
}
public void drawBackground(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int width = 987;
int height = 545;
g2d.setPaint(Color.WHITE);
g2d.fillRect(0, 0, width, height);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawBackground(g);
drawCA(g);
g.drawImage(img, 0, 0, null);
}
public Dimension getPreferredSize() {
return new Dimension(987, 545);
}
}
public class Rules {
int[] cells;
int[] ruleSet = new int[] {0, 1, 1, 1, 1, 0, 0, 0};
//int cellSize = 10;
int generation = 0;
void generate() {
int[] nextGeneration = new int[cells.length];
for (int i = 1; i < cells.length - 1; i++) {
int left = cells[i - 1];
int me = cells[i];
int right = cells [i + 1];
nextGeneration[i] = rules(left, me, right);
}
cells = nextGeneration;
generation++;
}
int rules(int left, int me, int right) {
String s = "" + left + me + right;
int index = Integer.parseInt(s, 2);
//System.out.println(index);
return ruleSet[index];
}
}
GUI 编程不同于控制台编程,因为您必须使用事件系统而不是仅仅使用 while 循环来重复生成输出的任务。我建议您首先添加一个按钮,用户单击该按钮可进入下一代自动机。当你开始工作时,你可以更进一步添加一个定时器,它会在一定时间后自动进入下一代。
我在 java 做元胞自动机练习,遇到了一个问题。
CA的逻辑部分工作正常,如果我想把它安排在控制台上就可以了,但我想把它画在面板上,当它是 1 画一个黑色方块时,当它为 0 时绘制一个白色方块
让我们进入问题
发生的事情是整个逻辑运行正常,但是绘制java时只绘制了最新一代的CA,我读到java paintComponent仅在java决定时起作用到而不是何时被调用。
My question is: how the best way to solve this problem and how to do it.
我想到了一些事情,但因为我不知道java所以我决定问你
我想过也许把所有的数组保存到一个数组中然后从中绘制(但我不知道我该怎么做)我想也许每个循环都有一种绘制的方法,但我没有找到了(我用了repaint()但是没用)
无论如何,如果有人能给我一个解决方案,我将不胜感激,我已经遇到这个问题好几天了,我还没有找到解决方案,下面是所有代码
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class CA extends JFrame {
Rules rules = new Rules();
public CA() {
super("Cellular Automaton");
setLayout(new BorderLayout());
add(new GUI_CA(), BorderLayout.CENTER);
pack();
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new CA();
}
});
}
}
}
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class GUI_CA extends JPanel {
int cellSize = 10;
Rules rules = new Rules();
private BufferedImage img;
private Graphics2D g2d;
public GUI_CA() {
img = new BufferedImage(cellSize, cellSize, BufferedImage.TYPE_INT_RGB);
g2d = (Graphics2D) img.createGraphics();
evolution();
}
public void evolution() {
rules.cells = new int[987/cellSize];
rules.cells[rules.cells.length/2] = 1;
System.out.println(Arrays.toString(rules.cells));
for (int generationCount = 0; generationCount < 10; generationCount++) {
rules.generate();
System.out.println(Arrays.toString(rules.cells));
repaint();
}
}
public void drawCA(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
for (int i = 1; i < rules.cells.length -1; i++) {
if (rules.cells[i] == 1) {
g2d.setColor(Color.BLACK);
g2d.fillRect(i * cellSize, rules.generation * 5, cellSize, cellSize);
System.out.println(Arrays.toString(rules.cells));
}else {
g2d.setColor(Color.WHITE);
g2d.fillRect(i * cellSize, rules.generation * 5, cellSize, cellSize);
}
}
}
public void drawBackground(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int width = 987;
int height = 545;
g2d.setPaint(Color.WHITE);
g2d.fillRect(0, 0, width, height);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawBackground(g);
drawCA(g);
g.drawImage(img, 0, 0, null);
}
public Dimension getPreferredSize() {
return new Dimension(987, 545);
}
}
public class Rules {
int[] cells;
int[] ruleSet = new int[] {0, 1, 1, 1, 1, 0, 0, 0};
//int cellSize = 10;
int generation = 0;
void generate() {
int[] nextGeneration = new int[cells.length];
for (int i = 1; i < cells.length - 1; i++) {
int left = cells[i - 1];
int me = cells[i];
int right = cells [i + 1];
nextGeneration[i] = rules(left, me, right);
}
cells = nextGeneration;
generation++;
}
int rules(int left, int me, int right) {
String s = "" + left + me + right;
int index = Integer.parseInt(s, 2);
//System.out.println(index);
return ruleSet[index];
}
}
GUI 编程不同于控制台编程,因为您必须使用事件系统而不是仅仅使用 while 循环来重复生成输出的任务。我建议您首先添加一个按钮,用户单击该按钮可进入下一代自动机。当你开始工作时,你可以更进一步添加一个定时器,它会在一定时间后自动进入下一代。