我想我在java Mandelbrot程序中遇到了一个无限循环

时间:2014-11-19 03:15:31

标签: java loops fractals

我正在编写一个绘制Mandelbrot分形的一部分的程序。我很确定我在这里的某个地方遇到无限循环。它很可能是别的东西,但无论如何,我无法弄明白。这是我的代码:

Mandelbrot.java

package edu.ycp.cs201.mandelbrot;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Scanner;

import javax.imageio.ImageIO;

public class Mandelbrot {
    private static final int HEIGHT = 600;

    private static final int WIDTH = 600;



    public static void main(String[] args) throws IOException {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Please enter coordinates of region to render:");
        System.out.print("  x1: ");
        double x1 = keyboard.nextDouble();
        System.out.print("  y1: ");
        double y1 = keyboard.nextDouble();
        System.out.print("  x2: ");
        double x2 = keyboard.nextDouble();
        System.out.print("  y2: ");
        double y2 = keyboard.nextDouble();

        System.out.print("Output filename: ");
        String fileName = keyboard.next();

        keyboard.close();

        int[][] iterCounts = new int[HEIGHT][WIDTH];
        MandelbrotTask task = new MandelbrotTask(x1, y1, x2, y2, 0, WIDTH, 0, HEIGHT, iterCounts);  
        task.run();


        // TODO: create the rendering, save it to a file
        BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
        Graphics g = bufferedImage.getGraphics();
        System.out.print("things are happening");
        for (int i = 0; i < WIDTH; i++)
        {
            for (int j = 0; j < HEIGHT; j++)
            {

                if (iterCounts[i][j] < 10)
                {
                g.setColor(Color.BLACK);
                g.fillRect(i,j,1,1);
                }
                else 
                    g.setColor(Color.BLUE);
                    g.fillR

ect(i,j,1,1);
            }

    }
    g.dispose();



    OutputStream os = new BufferedOutputStream(new FileOutputStream(fileName));

    try {
        ImageIO.write(bufferedImage, "PNG", os);
    } finally {
        os.close();
    }
}

Complex.java

package edu.ycp.cs201.mandelbrot;

public class Complex {
    double x;
    double y;

    // Constructor
    public Complex(double real, double imag) {
        this.x = real;
        this.y = imag;
    }

    // add given complex number to this one, returning the Complex result
    public Complex add(Complex other) {
        return new Complex((this.x + other.x), (this.y + other.y));
    }

    // multiply given complex number by this one, returning the Complex result
    public Complex multiply(Complex other) {
        double real = (this.x*other.x) - (this.y*other.y);
        double imag = (this.x*other.y) + (this.y*other.x);
        return new Complex(real, imag);
    }

    // get the magnitude of this complex number
    public double getMagnitude() {
        return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
    }
}

MandelbrotTask.java

package edu.ycp.cs201.mandelbrot;


public class MandelbrotTask implements Runnable {
    private double x1, y1, x2, y2;
    private int startCol, endCol, startRow, endRow;
    private int[][] iterCounts;


    public MandelbrotTask(double x1, double y1, double x2, double y2,
                          int startCol, int endCol, int startRow, int endRow,
                          int[][] iterCounts) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.startCol = startCol;
        this.endCol = endCol;
        this.startRow = startRow;
        this.endRow = endRow;
        this.iterCounts = iterCounts;

    }

    public void run() {
        System.out.print("Working...");
        for (int i = startRow; i < endRow; i++) {
            for (int j = startCol; j < endCol; j++) {
                  Complex c = getComplex(i, j);
                  int iterCount = computeIterCount(c);
                  iterCounts[i][j] = iterCount;
            }
        }
        System.out.print("donarino");

    }

    // TODO: implement getComplex and computeIterCount methods

    public Complex getComplex(double i, double j)
    {
        double k ,l;

         k = ((x2 - x1)/600)*i + x1;
         l = ((y2 - y1)/600)*j + y1;
        //System.out.println(" k :" + k + " l: " + l);

        return new Complex(k,l);
    }

    public int computeIterCount(Complex c)
    {
        Complex z = new Complex(0,0);
        int count = 0;
        while (z.getMagnitude() < 2 || count <= 11)
        {
            z = z.multiply(z).add(c);
            count++;
        }
        return count;
    }
}

2 个答案:

答案 0 :(得分:0)

您可以在每组for循环之前和之后进行行调试,例如,您可以这样做:

System.out.println("starting for loop on line: " + Thread.currentThread().getStackTrace()[1].getLineNumber());
for (int i = 0; i < WIDTH; i++)
{
    for (int j = 0; j < HEIGHT; j++)
    {
        // Your Code is here
    }
}
System.out.println("I am at line: " + Thread.currentThread().getStackTrace()[1].getLineNumber());

当其中一个输出没有显示您将知道什么不能完成时。

答案 1 :(得分:0)

我有几点建议。

一般:

  • 仅使用作为参数提供的函数中的数据(而不是像从getComplex()内部引用x1,x2)。这两种解决方案都可以工作,但是当您向函数提供所有数据时,这使得函数可以独立调试。

曼德尔布罗明智:

  • 首先创建一个可以正确计算单个点(像素)的函数。单独测试。
  • 然后将单个像素函数组织成循环(最好是迭代,因此您不必管理循环)。也可以测试一下。
  • 在整个工作完成之前不要打扰用户输入。模拟输入数据。
  • 如果代码可读且有效,您可以开始优化并要求用户输入。