gpt4 book ai didi

java - Java Swing 中的 Sierpinski Gasket 实现仅有时出现

转载 作者:行者123 更新时间:2023-11-30 02:50:59 24 4
gpt4 key购买 nike

所以我必须使用 Swing 创建 Sierpinski 垫片的实现。我不能使用递归或三角形。我必须使用以下内容算法:

Pick 3 points to define a triangle.

Select one of the vertices as current Loop 50,000 times: Randomly choose a vertex as the target. Draw a pixel at the mid-point between the target and current. Make current the mid-point.

下图中是我有时在编译时得到的结果,但有时它会弹出然后消失,或者根本不显示。如果它确实出现,然后我调整窗口大小,它就会消失(我不关心这个,但如果它有帮助的话。)我有时只能在编译时生成下面的图像(大约 1/3 的时间。)下图是我的代码,分为两类。

Image of when it works

import java.awt.*;
import javax.swing.JFrame;


public class SierpinskiGasket {

public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("SierpinskiGasket");
frame.setSize(630,580);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


drawSierpinski Sierpinski = new drawSierpinski();

frame.add(Sierpinski);

frame.setVisible(true);

}
}




import javax.swing.*;
import java.awt.*;


public class drawSierpinski extends JPanel{

Point point1 = new Point(10,550),
point2 = new Point(300,30),
point3 = new Point(600,555),
current = point1, target;
private int count = 0;


public void paintComponent(Graphics g){
super.paintComponent(g);

while(count<= 50000){
int choice = (int)(Math.random()*3);
switch(choice){
case 0: target = point1; break;
case 1: target = point2; break;
case 2: target = point3; break;
default: System.exit(0);

}
current = midpoint(current,target);
g.drawLine(current.x,current.y,current.x,current.y);

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


}

我假设它与 Swing 的多线程处理方式有关,但不幸的是我对如何修复它没有太多了解。非常感谢您的帮助!

最佳答案

这个循环:

while(count<= 50000) { 

// ....

}

可能需要一段时间才能完成,同时它将在最关键的时刻(绘图时)完全阻塞 Swing 事件线程。更重要的是,任何微不足道的重新绘制都会触发循环重新运行,再次完全卡住您的 GUI。

解决方案:在paintComponent 之外进行绘图。相反,创建一个 JPanel 大小的 BufferedImage,获取图像的 Graphics 对象,在 BufferedImage 中为三角形绘制随机点,然后在 JPanel 的 PaintComponent 方法中显示该图像。您可以在程序启动时绘制图像,然后在完成后启动 GUI,或者您可以启动 GUI 并在后台线程中绘制到 BufferedImage,并在完成后显示它,两者都可以(如果这是你的 GUI 唯一应该做的事情)。

例如:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class SierpTest {
public static final int BI_WIDTH = 630;
public static final int BI_HEIGHT = 580;

public static void main(String[] args) {

// do this stuff off the swing event thread
final BufferedImage sierpImg = new BufferedImage(BI_WIDTH, BI_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics g = sierpImg.getGraphics();

// draw triangle with g here

g.dispose(); // always dispose of any Graphics you create yourself

// do this on the Swing event thread
SwingUtilities.invokeLater(() -> {
SierpPanel sierpPanel = new SierpPanel(sierpImg); // pass in image
JFrame frame = new JFrame("Siep Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(sierpPanel);
frame.pack(); // size it to the size of the JPanel
frame.setLocationRelativeTo(null); // center it
frame.setVisible(true);
});
}
}

class SierpPanel extends JPanel {
private BufferedImage img = null;

public SierpPanel(BufferedImage img) {
this.img = img;
}

// so that JPanel sizes itself with the image
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || img == null) {
return super.getPreferredSize();
}
return new Dimension(img.getWidth(), img.getHeight());
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
}

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class SierpTest {
public static final int BI_WIDTH = 630;
public static final int BI_HEIGHT = 580;
private static final int MAX_COUNT = 100000;

public static void main(String[] args) {

// do this stuff off the swing event thread
Point point1 = new Point(10, 550);
Point point2 = new Point(300, 30);
Point point3 = new Point(600, 555);
Point current = point1;
Point target = current;
int count = 0;

final BufferedImage sierpImg = new BufferedImage(BI_WIDTH, BI_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics g = sierpImg.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, BI_WIDTH, BI_HEIGHT);
g.setColor(Color.BLACK);

while (count <= MAX_COUNT) {
int choice = (int) (Math.random() * 3);
switch (choice) {
case 0:
target = point1;
break;
case 1:
target = point2;
break;
case 2:
target = point3;
break;
default:
System.exit(0);

}
current = midpoint(current, target);
g.drawLine(current.x, current.y, current.x, current.y);

count++;
}

// draw triangle with g here

g.dispose(); // always dispose of any Graphics you create yourself

// do this on the Swing event thread
SwingUtilities.invokeLater(() -> {
SierpPanel sierpPanel = new SierpPanel(sierpImg); // pass in image
JFrame frame = new JFrame("Siep Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(sierpPanel);
frame.pack(); // size it to the size of the JPanel
frame.setLocationRelativeTo(null); // center it
frame.setVisible(true);
});
}

public static Point midpoint(Point a, Point b) {
return new Point((Math.round(a.x + b.x) / 2), (Math.round(a.y + b.y) / 2));
}
}

class SierpPanel extends JPanel {
private BufferedImage img = null;

public SierpPanel(BufferedImage img) {
this.img = img;
}

// so that JPanel sizes itself with the image
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || img == null) {
return super.getPreferredSize();
}
return new Dimension(img.getWidth(), img.getHeight());
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
}

请注意,如果您想在创建三角形时获得奇特效果并延迟绘制三角形,请考虑使用 Swing Timer 或 SwingWorker。

关于java - Java Swing 中的 Sierpinski Gasket 实现仅有时出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38668266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com