奇怪的随机错误,java绘图
我已经写了一个程序,我认为它应该能完美地工作。由于某种原因,它没有。我会提供代码,希望有人能找出问题所在。我已经坐了好几个小时了,但我再也坐不住了奇怪的随机错误,java绘图,java,Java,我已经写了一个程序,我认为它应该能完美地工作。由于某种原因,它没有。我会提供代码,希望有人能找出问题所在。我已经坐了好几个小时了,但我再也坐不住了 import java.awt.*; import javax.swing.*; public class CrystalModel { private int radius; private int index; private boolean[][] crystal; private Point concludi
import java.awt.*;
import javax.swing.*;
public class CrystalModel
{
private int radius;
private int index;
private boolean[][] crystal;
private Point concludingPoint;
private int escapeRadius;
/**
* Constructor. Initiates an electron bath of size 30x30.
*/
public CrystalModel()
{
radius = 30;
index = 30*2-1;
start();
}
/**
* Constructor. Initiates an electron bath of size r.
* @param r bath radius
*/
public CrystalModel(int r)
{
radius = r;
index = r*2-1;
start();
}
/**
* Initiates the experiment
*/
private void start()
{
crystal = new boolean[radius*2][radius*2];
crystal[radius][radius] = true; //The width is always even (2*r), this is as close to the center as one gets
escapeRadius = (int)(1.1*radius);
}
/**
* Determines if a given xy-coordinate is within radius
* @param x x-coordinate
* @param y y-coordinate
* @return whether the active ion is out of range
*/
private boolean outsideCircle(int r, int x, int y)
{
return (Math.pow(x,2)+Math.pow(y,2) >= Math.pow(r, 2));
}
/**
* Determines if the currently active ion has a neighbouring crystallized ion
* @param whether the is a neighbour
*/
private boolean anyNeighbours(int x, int y)
{
x = xBathToModel(x);
y = yBathToModel(y);
boolean left = (x-1 >= 0) && (x-1 <= index) && (y >= 0) && (y <= index) ? crystal[x-1][y] : false;
boolean right = (x+1 >= 0) && (x+1 <= index) && (y >= 0) && (y <= index) ? crystal[x+1][y] : false;
boolean up = (y-1 >= 0) && (y-1 <= index) && (x >= 0) && (x <= index) ? crystal[x][y-1] : false;
boolean down = (y+1 >= 0) && (y+1 <= index) && (x >= 0) && (x <= index) ? crystal[x][y+1] : false;
return ( left || right || up || down );
}
/**
* Determines an xy-coordinate at radius distance from the center
* @param radius radius of escape for ions
* @return Point object encapsulating x, y
*/
private Point dropNewIon()
{
double angle = (int)(Math.random()*2*Math.PI);
return new Point( (int)( Math.cos(angle)*(index/2) ), (int)( Math.sin(angle)*(index/2) ) );
}
/**
* Transform x-coordinate upon the moving of origo from center to top-left
* @ x x-coordinate
*/
public int xBathToModel(int x)
{
return radius+x;
}
/**
* Transform y-coordinate upon the moving of origo from center to top-left
* @param y y-coordinate
*/
public int yBathToModel(int y)
{
return radius+y;
}
/**
* Increments the number of ions in the crystal by one
* @return boolean indicating whether the experiment is done or not
*/
private Point crystallizeOneIon()
{
Point point = dropNewIon();
for( ; ; )
{
switch((int)(Math.random()*4+1))
{
case 1: point.x+=1;
break;
case 2: point.x-=1;
break;
case 3: point.y+=1;
break;
case 4: point.y-=1;
break;
}
if(outsideCircle(escapeRadius, point.x, point.y)) point = dropNewIon();
if(anyNeighbours(point.x, point.y)) break;
}
crystal[xBathToModel(point.x)][yBathToModel(point.y)] = true;
return point;
}
/**
* Let the algorithm (CrystalExperiment) simulate a number of steps
* @param steps how many steps
* @return boolean indiciating whether the experiment is concluded
*/
public boolean runExperiment(int steps)
{
for(int i=0; i<steps; i++)
{
concludingPoint = crystallizeOneIon();
if(outsideCircle((int)index/2, concludingPoint.x, concludingPoint.y))
{
concludingPoint.x = xBathToModel(concludingPoint.x);
concludingPoint.y = yBathToModel(concludingPoint.y);
return true;
}
else
{
concludingPoint.x = xBathToModel(concludingPoint.x);
concludingPoint.y = yBathToModel(concludingPoint.y);
}
}
return false;
}
/**
* Return a textual representation of the crystal
* @return String representing the crystal
*/
public String toString()
{
String output = "";
for(int y=-1; y<=index+1; y++)
{
for(int x=-1; x<=index+1; x++)
{
if(y == -1) output+="--";
else if(y == index+1) output+="--";
else
{
if(x == -1) output+="|";
else if(x == index+1) output+="|";
else
{
if(concludingPoint.equals(new Point(x,y))) output+="# ";
else if(crystal[x][y] == true) output+="* ";
else output+=" ";
}
}
}
output+="\n";
}
return output;
}
public int getIndexSize()
{
return index;
}
public boolean getMatrixValue(int x, int y)
{
return crystal[x][y];
}
private void drawCrystal()
{
JFrame frame = new JFrame("");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setBounds(0, 0, 200, 200);
CrystalView drawing = new CrystalView(this);
frame.add(drawing);
}
public static void main(String[] args)
{
(new CrystalModel(200)).drawCrystal();
}
}
import java.awt.*;
导入javax.swing.*;
公共类晶体模型
{
私有整数半径;
私有整数索引;
私有布尔[][]晶体;
私人点总结点;
私家车;
/**
*建造商。启动尺寸为30x30的电子浴。
*/
公共水晶模型()
{
半径=30;
指数=30*2-1;
start();
}
/**
*建造师。启动尺寸为r的电子浴。
*@param r浴池半径
*/
公共水晶模型(INTR)
{
半径=r;
指数=r*2-1;
start();
}
/**
*开始实验
*/
私有void start()
{
crystal=新布尔值[radius*2][radius*2];
crystal[radius][radius]=true;//宽度始终为偶数(2*r),这是最接近中心的距离
逃逸半径=(int)(1.1*半径);
}
/**
*确定给定xy坐标是否在半径范围内
*@param x x坐标
*@param y坐标
*@return活动离子是否超出范围
*/
私有布尔外圆(int r,int x,int y)
{
return(Math.pow(x,2)+Math.pow(y,2)>=Math.pow(r,2));
}
/**
*确定当前活动离子是否有相邻的结晶离子
*@param是否为邻居
*/
私有布尔任意邻域(int x,int y)
{
x=xBathToModel(x);
y=yBathToModel(y);
布尔左=(x-1>=0)和(x-1=0)和(y=0)和(x+1=0)和(y=0)和(y-1=0)和(x=0)和(y+1=0)和(x公共空心颜料组件(图形g)
{
而(!model.runExperiment(1))
{
对于(int y=0;y我试图修复您的代码(请参见下文)。问题的位置用TODO标记。不知道它打算如何工作,但现在它引出了一些要点
如前一个答案中所述,您无法获得这样的动画。仅调用一次paintComponent()
方法来绘制组件。例如,在调整窗体大小时会发生这种情况。因此,您只能获得静态图像
CrystalModel.java
import java.awt.Point;
import javax.swing.JFrame;
public class CrystalModel
{
private int radius;
private int index;
private boolean[][] crystal;
private Point concludingPoint;
private int escapeRadius;
/**
* Constructor. Initiates an electron bath of size 30x30.
*/
public CrystalModel()
{
radius = 30;
index = 30*2-1;
start();
}
/**
* Constructor. Initiates an electron bath of size r.
* @param r bath radius
*/
public CrystalModel(int r)
{
radius = r;
index = r*2-1;
start();
}
/**
* Initiates the experiment
*/
private void start()
{
crystal = new boolean[radius*2][radius*2];
crystal[radius][radius] = true; //The width is always even (2*r), this is as close to the center as one gets
escapeRadius = (int)(1.1*radius);
}
/**
* Determines if a given xy-coordinate is within radius
* @param x x-coordinate
* @param y y-coordinate
* @return whether the active ion is out of range
*/
private boolean outsideCircle(int r, int x, int y)
{
return (Math.pow(x,2)+Math.pow(y,2) >= Math.pow(r, 2));
}
/**
* Determines if the currently active ion has a neighbouring crystallized ion
* @param whether the is a neighbour
*/
private boolean anyNeighbours(int x, int y)
{
x = xBathToModel(x);
y = yBathToModel(y);
boolean left = (x-1 >= 0) && (x-1 <= index) && (y >= 0) && (y <= index) ? crystal[x-1][y] : false;
boolean right = (x+1 >= 0) && (x+1 <= index) && (y >= 0) && (y <= index) ? crystal[x+1][y] : false;
boolean up = (y-1 >= 0) && (y-1 <= index) && (x >= 0) && (x <= index) ? crystal[x][y-1] : false;
boolean down = (y+1 >= 0) && (y+1 <= index) && (x >= 0) && (x <= index) ? crystal[x][y+1] : false;
return ( left || right || up || down );
}
/**
* Determines an xy-coordinate at radius distance from the center
* @param radius radius of escape for ions
* @return Point object encapsulating x, y
*/
private Point dropNewIon()
{
double angle = (int)(Math.random()*2*Math.PI);
return new Point( (int)( Math.cos(angle)*(index/2) ), (int)( Math.sin(angle)*(index/2) ) );
}
/**
* Transform x-coordinate upon the moving of origo from center to top-left
* @ x x-coordinate
*/
public int xBathToModel(int x)
{
return radius+x;
}
/**
* Transform y-coordinate upon the moving of origo from center to top-left
* @param y y-coordinate
*/
public int yBathToModel(int y)
{
return radius+y;
}
/**
* Increments the number of ions in the crystal by one
* @return boolean indicating whether the experiment is done or not
*/
private Point crystallizeOneIon()
{
Point point = dropNewIon();
for( ; ; )
{
switch((int)(Math.random()*4+1))
{
case 1: point.x+=1;
break;
case 2: point.x-=1;
break;
case 3: point.y+=1;
break;
case 4: point.y-=1;
break;
}
if(outsideCircle(escapeRadius, point.x, point.y)) point = dropNewIon();
if(anyNeighbours(point.x, point.y)) break;
break;
}
try {
// TODO The logic is wrong here - calculated points sometimes are out of array. See console output
crystal[xBathToModel(point.x)][yBathToModel(point.y)] = true;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Oops, point (" + point.x + ", " + point.y + ") is out of array");
}
return point;
}
/**
* Let the algorithm (CrystalExperiment) simulate a number of steps
* @param steps how many steps
* @return boolean indiciating whether the experiment is concluded
*/
public synchronized boolean runExperiment(int steps)
{
for(int i=0; i<steps; i++)
{
concludingPoint = crystallizeOneIon();
if(outsideCircle((int)index/2, concludingPoint.x, concludingPoint.y))
{
concludingPoint.x = xBathToModel(concludingPoint.x);
concludingPoint.y = yBathToModel(concludingPoint.y);
return true;
}
else
{
concludingPoint.x = xBathToModel(concludingPoint.x);
concludingPoint.y = yBathToModel(concludingPoint.y);
}
}
return false;
}
/**
* Return a textual representation of the crystal
* @return String representing the crystal
*/
public String toString()
{
String output = "";
for(int y=-1; y<=index+1; y++)
{
for(int x=-1; x<=index+1; x++)
{
if(y == -1) output+="--";
else if(y == index+1) output+="--";
else
{
if(x == -1) output+="|";
else if(x == index+1) output+="|";
else
{
if(concludingPoint.equals(new Point(x,y))) output+="# ";
else if(crystal[x][y] == true) output+="* ";
else output+=" ";
}
}
}
output+="\n";
}
return output;
}
public int getIndexSize()
{
return index;
}
public boolean getMatrixValue(int x, int y)
{
return crystal[x][y];
}
private void drawCrystal()
{
JFrame frame = new JFrame("");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setBounds(0, 0, 600, 600);
CrystalView drawing = new CrystalView(this);
frame.add(drawing);
frame.validate();
}
public static void main(String[] args)
{
(new CrystalModel(200)).drawCrystal();
}
}
导入java.awt.Point;
导入javax.swing.JFrame;
公共类晶体模型
{
私有整数半径;
私有整数索引;
私有布尔[][]晶体;
私人点总结点;
私家车;
/**
*建造商。启动尺寸为30x30的电子浴。
*/
公共水晶模型()
{
半径=30;
指数=30*2-1;
start();
}
/**
*建造商。启动尺寸为r的电子浴。
*@param r浴池半径
*/
公共水晶模型(INTR)
{
半径=r;
指数=r*2-1;
start();
}
/**
*开始实验
*/
私有void start()
{
crystal=新布尔值[radius*2][radius*2];
crystal[radius][radius]=true;//宽度始终为偶数(2*r),这是最接近中心的距离
逃逸半径=(int)(1.1*半径);
}
/**
*确定给定xy坐标是否在半径范围内
*@param x x坐标
*@param y坐标
*@return活动离子是否超出范围
*/
私有布尔外圆(int r,int x,int y)
{
return(Math.pow(x,2)+Math.pow(y,2)>=Math.pow(r,2));
}
/**
*确定当前活动离子是否有相邻的结晶离子
*@param是否为邻居
*/
私有布尔任意邻域(int x,int y)
{
x=xBathToModel(x);
y=yBathToModel(y);
布尔左=(x-1>=0)和&(x-1=0)和&(y=0)和&(x+1=0)和&(y-1=0)和&(x=0)和&(y+1=0)和&(x)“请运行程序,您将看到我的意思。”.不,我不会。如果您需要帮助,您需要付出一些努力来告诉我们问题是什么。问题非常简单。如果您查看for循环,它将循环通过1-200,并在该区域内填充像素(200x200).但是如果你画它,图形会变得非常小。如果它真的画了,也就是说。如果它的大小只有200px,它会完全冻结,所以我想我正在做一些事情来减慢它。另外,只需关注绘图部分,因为我已经验证了模型的工作。toString返回图形应该是什么样子的正确图像好的。基本上,我画的图片是递增的。每次我运行“RunExperience”矩阵得到了一个新的值。所以我必须再次做循环,画出所有的东西。因此,应该有一点动画,人们可以看到图像变大…但我不需要计时器或类似的东西。我几乎100%确定这是某种预期的解决方案。这个循环肯定不属于那里。repaint将导致再次调用paintComponent,等等。您需要的只是该循环的内容,以及一个重复调用model.runExperiment(1)
和repaint()
的计时器。paintComponent()方法用于绘制组件的当前状态。如果要更改组件的状态,则可以使用其他方法。也就是说,可以使用计时器或其他方法调用更改组件状态的方法,然后该方法调用repaint()@Calle,查看Walter Lan的示例,该示例演示了如何使用计时器通过调用“addPoint()”方法来更改组件的状态:感谢您的努力,我非常感谢。不过,请尝试将drawCrystal中的代码替换为while(this.runExperiment(1)){System.out.println(this.toString());}在主程序中调用它,如下所示:
public void paintComponent(Graphics g)
{
while(!model.runExperiment(1))
{
for(int y=0; y<model.getIndexSize(); y++)
{
for(int x=0; x<model.getIndexSize(); x++)
{
if(model.getMatrixValue(x,y))
g.drawOval(x, y, 1, 1);
}
}
this.repaint();
}
}
import java.awt.Point;
import javax.swing.JFrame;
public class CrystalModel
{
private int radius;
private int index;
private boolean[][] crystal;
private Point concludingPoint;
private int escapeRadius;
/**
* Constructor. Initiates an electron bath of size 30x30.
*/
public CrystalModel()
{
radius = 30;
index = 30*2-1;
start();
}
/**
* Constructor. Initiates an electron bath of size r.
* @param r bath radius
*/
public CrystalModel(int r)
{
radius = r;
index = r*2-1;
start();
}
/**
* Initiates the experiment
*/
private void start()
{
crystal = new boolean[radius*2][radius*2];
crystal[radius][radius] = true; //The width is always even (2*r), this is as close to the center as one gets
escapeRadius = (int)(1.1*radius);
}
/**
* Determines if a given xy-coordinate is within radius
* @param x x-coordinate
* @param y y-coordinate
* @return whether the active ion is out of range
*/
private boolean outsideCircle(int r, int x, int y)
{
return (Math.pow(x,2)+Math.pow(y,2) >= Math.pow(r, 2));
}
/**
* Determines if the currently active ion has a neighbouring crystallized ion
* @param whether the is a neighbour
*/
private boolean anyNeighbours(int x, int y)
{
x = xBathToModel(x);
y = yBathToModel(y);
boolean left = (x-1 >= 0) && (x-1 <= index) && (y >= 0) && (y <= index) ? crystal[x-1][y] : false;
boolean right = (x+1 >= 0) && (x+1 <= index) && (y >= 0) && (y <= index) ? crystal[x+1][y] : false;
boolean up = (y-1 >= 0) && (y-1 <= index) && (x >= 0) && (x <= index) ? crystal[x][y-1] : false;
boolean down = (y+1 >= 0) && (y+1 <= index) && (x >= 0) && (x <= index) ? crystal[x][y+1] : false;
return ( left || right || up || down );
}
/**
* Determines an xy-coordinate at radius distance from the center
* @param radius radius of escape for ions
* @return Point object encapsulating x, y
*/
private Point dropNewIon()
{
double angle = (int)(Math.random()*2*Math.PI);
return new Point( (int)( Math.cos(angle)*(index/2) ), (int)( Math.sin(angle)*(index/2) ) );
}
/**
* Transform x-coordinate upon the moving of origo from center to top-left
* @ x x-coordinate
*/
public int xBathToModel(int x)
{
return radius+x;
}
/**
* Transform y-coordinate upon the moving of origo from center to top-left
* @param y y-coordinate
*/
public int yBathToModel(int y)
{
return radius+y;
}
/**
* Increments the number of ions in the crystal by one
* @return boolean indicating whether the experiment is done or not
*/
private Point crystallizeOneIon()
{
Point point = dropNewIon();
for( ; ; )
{
switch((int)(Math.random()*4+1))
{
case 1: point.x+=1;
break;
case 2: point.x-=1;
break;
case 3: point.y+=1;
break;
case 4: point.y-=1;
break;
}
if(outsideCircle(escapeRadius, point.x, point.y)) point = dropNewIon();
if(anyNeighbours(point.x, point.y)) break;
break;
}
try {
// TODO The logic is wrong here - calculated points sometimes are out of array. See console output
crystal[xBathToModel(point.x)][yBathToModel(point.y)] = true;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Oops, point (" + point.x + ", " + point.y + ") is out of array");
}
return point;
}
/**
* Let the algorithm (CrystalExperiment) simulate a number of steps
* @param steps how many steps
* @return boolean indiciating whether the experiment is concluded
*/
public synchronized boolean runExperiment(int steps)
{
for(int i=0; i<steps; i++)
{
concludingPoint = crystallizeOneIon();
if(outsideCircle((int)index/2, concludingPoint.x, concludingPoint.y))
{
concludingPoint.x = xBathToModel(concludingPoint.x);
concludingPoint.y = yBathToModel(concludingPoint.y);
return true;
}
else
{
concludingPoint.x = xBathToModel(concludingPoint.x);
concludingPoint.y = yBathToModel(concludingPoint.y);
}
}
return false;
}
/**
* Return a textual representation of the crystal
* @return String representing the crystal
*/
public String toString()
{
String output = "";
for(int y=-1; y<=index+1; y++)
{
for(int x=-1; x<=index+1; x++)
{
if(y == -1) output+="--";
else if(y == index+1) output+="--";
else
{
if(x == -1) output+="|";
else if(x == index+1) output+="|";
else
{
if(concludingPoint.equals(new Point(x,y))) output+="# ";
else if(crystal[x][y] == true) output+="* ";
else output+=" ";
}
}
}
output+="\n";
}
return output;
}
public int getIndexSize()
{
return index;
}
public boolean getMatrixValue(int x, int y)
{
return crystal[x][y];
}
private void drawCrystal()
{
JFrame frame = new JFrame("");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setBounds(0, 0, 600, 600);
CrystalView drawing = new CrystalView(this);
frame.add(drawing);
frame.validate();
}
public static void main(String[] args)
{
(new CrystalModel(200)).drawCrystal();
}
}
import java.awt.Graphics;
import javax.swing.JPanel;
public class CrystalView extends JPanel {
private static final long serialVersionUID = 1L;
CrystalModel model;
public CrystalView(CrystalModel m) {
model = m;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
while (!model.runExperiment(1)) {
for (int y = 0; y < model.getIndexSize(); y++) {
for (int x = 0; x < model.getIndexSize(); x++) {
if (model.getMatrixValue(x, y)) {
g.drawOval(x, y, 2, 2);
}
}
}
}
}
}