java - 我的 Mandelbrot 集不生成。我的方程式有什么问题?
问题描述
//Generator class
public class Generator {
double jump;
double sizeModifier;
int iterationRate,range;
ComplexNumber c;
public Generator(double jump) {
this.jump=jump;
this.sizeModifier=40;
this.iterationRate=10;
this.range=100;
c=new ComplexNumber();
}
public void generateSet(){
DrawSet ds = new DrawSet();
int ticker=0;
for(double i=-2*range;i<=range;i+=jump){
for(double j=-2*range;j<=range;j+=jump){
c= new ComplexNumber((i/range),(j/range));
double fz=c.square().mod()+c.mod();
//System.out.println("c mod is: "+c.mod());
//System.out.println("fz is: "+fz);
if (fz < 2) {
for(int k=0;k<=iterationRate;k++) {
//System.out.println("nc:"+nc);
ticker++;
//System.out.println("ticker:"+ticker);
if(ticker==iterationRate) {
ds.addPoint(i + 450, j + 450);
}
if(fz>=2){
break;
}
else {
fz = Math.pow(fz, 2) + 1;
}
}
}
ticker=0;
}
}
}
//Drawset class
public class DrawSet extends JPanel {
private ArrayList<Point> Points;
private ArrayList<Point> nPoints;
GraphicWindow gw;
public DrawSet(){
this.Points=new ArrayList<>();
this.nPoints=new ArrayList<>();
gw = new GraphicWindow(1000,1000);
gw.add(this);
}
public void addPoint(double x,double y){
int ix=(int)x;
int iy=(int)y;
//int iwidth=(int)width*sizeModifier;
//int iheight=(int)height*sizeModifier;
Point a=new Point(ix,iy);
Points.add(a);
//System.out.println(Points.size());
}
public void paintComponent(Graphics g) {
int pointSize = 1;
super.paintComponents(g);
System.out.println(Points.size());
for (int i = 0; i < Points.size(); i++) {
g.setColor(Color.BLACK);
g.drawOval((int) Points.get(i).getX(), (int) Points.get(i).getY(), pointSize, pointSize);
}
}
基本问题是 fz 在 10 次迭代后永远不会小于 2,因此没有绘制点。为什么是这样?我应该执行什么等式?
我正在使用复数来生成值。我使用的类可以在这里看到: https ://github.com/abdulfatir/jcomplexnumber/ (或者在堆栈溢出论坛上Java有一个复数类吗?阿卜杜勒·法蒂尔先生)
解决方案
好的,观察
Generator
不应该创建一个新的实例DrawSet
DrawSet
不应该创建一个新的实例GraphicWindow
这些是这些类或方法的职责。这会高度耦合您的代码并产生副作用。
相反,generate
应该传回它创建的点,然后这些点应该以你想要的任何方式应用,Generator
不应该关心。
因为我无法访问您的完整代码,所以我只是将一系列随机点拼凑在一起来说明这一点。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
DrawSet drawSet = new DrawSet();
Generator generator = new Generator(100);
drawSet.setPoints(generator.generateSet());
JFrame frame = new JFrame();
frame.add(drawSet);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawSet extends JPanel {
private ArrayList<Point> points;
private ArrayList<Point> nPoints;
public DrawSet() {
this.points = new ArrayList<>();
this.nPoints = new ArrayList<>();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
public void setPoints(ArrayList<Point> points) {
this.points = points;
repaint();
}
// public void addPoint(double x, double y) {
// int ix = (int) x;
// int iy = (int) y;
// //int iwidth=(int)width*sizeModifier;
// //int iheight=(int)height*sizeModifier;
// Point a = new Point(ix, iy);
// Points.add(a);
// //System.out.println(Points.size());
// }
@Override
protected void paintComponent(Graphics g) {
int pointSize = 5;
super.paintComponents(g);
for (int i = 0; i < points.size(); i++) {
g.setColor(Color.BLACK);
g.drawOval((int) points.get(i).getX(), (int) points.get(i).getY(), pointSize, pointSize);
}
}
}
public class Generator {
double jump;
double sizeModifier;
int iterationRate, range;
//ComplexNumber c;
public Generator(double jump) {
this.jump = jump;
this.sizeModifier = 40;
this.iterationRate = 10;
this.range = 100;
//c = new ComplexNumber();
}
public ArrayList<Point> generateSet() {
Random rnd = new Random();
ArrayList<Point> points = new ArrayList<>(range);
for (int index = 0; index < range; index++) {
int x = (int)(490 * rnd.nextDouble());
int y = (int)(490 * rnd.nextDouble());
points.add(new Point(x, y));
}
return points;
// DrawSet ds = new DrawSet();
// int ticker = 0;
// for (double i = -2 * range; i <= range; i += jump) {
// for (double j = -2 * range; j <= range; j += jump) {
// c = new ComplexNumber((i / range), (j / range));
// double fz = c.square().mod() + c.mod();
// //System.out.println("c mod is: "+c.mod());
// //System.out.println("fz is: "+fz);
// if (fz < 2) {
// for (int k = 0; k <= iterationRate; k++) {
// //System.out.println("nc:"+nc);
// ticker++;
// //System.out.println("ticker:"+ticker);
// if (ticker == iterationRate) {
// ds.addPoint(i + 450, j + 450);
//
// }
// if (fz >= 2) {
// break;
// } else {
// fz = Math.pow(fz, 2) + 1;
// }
// }
// }
// ticker = 0;
// }
// }
}
}
}
我也做了pointSize
更大的,所以你实际上可以看到结果,虽然我会考虑填充点。
如果Generator
is 需要很长时间来执行其计算,您可以考虑使用 aSwingWorker
来执行操作。这将允许将操作卸载到单独的线程,而不是阻塞主 UI 线程。然后,您可以使用SwingWorker
来在计算时反馈每个单独的点,或者在整个生成完成时反馈所有点,以安全的方式返回到主 UI 线程。
有关更多详细信息,请参阅工作线程和 SwingWorker
为什么是这样?
摇摆是懒惰的。除非它认为需要,否则它不会对 UI 进行重绘或更新。因此,如果您更改 UI 所依赖的某些状态,则需要轻推 Swing 以鼓励它进行新的绘制。用最简单的话来说,这意味着调用repaint
已更改的组件
推荐阅读
- .net - 如何使用 ITelemetryInitializer 为 ApplicationInsights 公开 HttpContext
- mysql - 将数据从一个 mysql 表发送到另一台服务器上的另一个 mysql 表
- javascript - 如何将不同的元素组合推入新数组?
- swift - SwiftUI 奇怪的动画行为
- python - 为什么在这个 SQL 表中找不到这个列,当表定义时包含它?
- r - 我正在尝试使用 dplyr 重命名 R 中的因子,但我得到:错误:“cbc$Gender <- recode_factor(cbc$Gender, c(0,1) =”中的意外'='
- sql - 从 SQL/Oracle 中的给定当前日期开始滚动总和超过 90 个日历日期(回溯)
- angular - 计算角度 Infragistics Ui 网格中按行分组的总价值
- deployment - 应用程序托管最佳方法
- javascript - 用户单击新的下拉选择选项后如何重置复选框值