2014-11-19 4 views
0

Я пишу программу, которая рисует часть фрактала Мандельброта. Я почти уверен, что нахожусь в бесконечном цикле где-то вдоль линии. Это может быть что-то еще, но что бы это ни было, я не могу понять. Вот мой код:Я думаю, что я нахожусь в бесконечном цикле где-то в программе java 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; 
    } 
} 
+1

запускайте каждый цикл отдельно и смотрите, если он когда-либо заканчивается. Если это не так, это не так. –

+1

Попробуйте положить println() в подозрительные циклы, например, в 'computeIterCount()'. – mdnghtblue

+0

@mdnghtblue Я пытался это сделать, но в некоторых местах они просто не показывают из-за количества раз, когда он запускает цикл. – GravityCheck

ответ

0

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

Общие:

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

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

  • сначала создать функцию, которая может вычислить одну точку (пиксель) должным образом. Испытайте это в одиночку.
  • затем организует одиночную пиксельную функцию в цикле (желательно итерации, поэтому вам не нужно управлять циклом). Испытайте это также.
  • не беспокойтесь от ввода пользователем до тех пор, пока все это не будет работать. Макет входных данных.
  • Если код доступен для чтения и работает, вы можете начать оптимизацию и запросить ввод пользователя.
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()); 

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

+0

Хорошо, я сделал это, и это петля в MadelbrotTask внутри Run(), который не закончить, но я я все еще недоумеваю, почему. – GravityCheck

+0

Тогда следующий уровень в PDD (разработка, основанная на принтере), заключался бы в том, чтобы печатать внутри цикла с помощью i & j. – karatedog