Я думаю, что я нахожусь в бесконечном цикле где-то в моей программе Java Мандельброта

Я пишу программу, которая рисует часть фрактала Мандельброта. Я почти уверен, что я попал в бесконечный цикл где-то вдоль линии здесь. Вполне возможно, что-то еще, но что бы ни случилось, я не могу понять это. Вот мой код:

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 ответа

Решение

У меня есть несколько предложений.

Генеральный:

  • используйте только те данные в функции, которые были предоставлены в качестве аргумента (и не похожи на ссылку на x1, x2 из getComplex()). Оба решения работают, но это делает функцию автономной отладочной, поскольку вы предоставляете все данные для функции.

Мандельброт-накрест:

  • Сначала создайте функцию, которая может правильно рассчитать одну точку (пиксель). Проверьте это в одиночку.
  • затем организуйте однопиксельную функцию в цикл (желательно итерацию, чтобы вам не пришлось управлять циклом). Проверьте это также.
  • не беспокойтесь о пользовательском вводе, пока все не сработает. Макет входных данных.
  • если код читабелен и работает, вы можете начать оптимизацию и запросить ввод данных пользователем.

Вы можете поставить отладку строки до и после каждого набора 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());

Когда один из выходных данных не отображается, вы узнаете, что не заканчивается.

Другие вопросы по тегам