我已经编写了一个程序,我认为它应该可以完美地工作。由于某种原因,事实并非如此。我将提供代码并希望有人能够找出问题所在。我已经坐了好几个小时了,但我无法继续下去。
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();
}
}
这是我的观点,它不起作用(尽管 toString 方法起作用,并且这是类似的):
import javax.swing.*;
import java.awt.*;
public class CrystalView extends JPanel
{
CrystalModel model;
public CrystalView(CrystalModel m)
{
model = m;
}
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();
}
}
}
图中有错误。它 (1) 在终端中产生错误,并且 (2) 不绘制完整尺寸。请运行该程序,您就会明白我的意思。
最佳答案
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();
}
}
我不知道代码应该做什么,但你永远不应该有一个像这样调用 repaint() 的循环。这是导致无限循环的一种方法。
如果您尝试制作动画,那么您需要使用线程或 Swing 计时器来制作动画。
关于java - 奇怪的随机错误,java绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4356322/