Графическое представление множеств Мандельброта и Жюлиа в Java

Я работаю над проблемой, когда мне нужно графически представить набор Мандельброта с помощью OpenCL и сначала работать над своим последовательным кодом. Однако изображение, которое он создает, не очень хорошее, и я не уверен, что я что-то где-то пропустил, или это просто проблема с отсутствием разрешения (так сказать). Я разместил код ниже вместе со скриншотом того, что он производит - это то, чего мне следовало ожидать, или я где-то это испортил?

public class SequentialMandelbrot {

    private static int[] colorMap;
    private static int xSize = 200, ySize = 200;
    private static float yMin = -2f, yMax = 2f;
    private static float xMin = -2f, xMax = 2f;
    private static float xStep =  (xMax - xMin) / (float)xSize;
    private static float yStep =  (yMax - yMin) / (float)ySize;
    private static final int maxIter = 250;
    private static BufferedImage image;
    private static JComponent imageComponent;   

    public static void main(String[] args) {

        // Create the image and the component that will paint the image
        initColorMap(32, Color.RED, Color.GREEN, Color.BLUE);
        image = new BufferedImage(xSize, ySize, BufferedImage.TYPE_INT_RGB);
        imageComponent = new JPanel()
        {
            private static final long serialVersionUID = 1L;
            public void paintComponent(Graphics g)
            {
                super.paintComponent(g);
                g.drawImage(image, 0,0,this);
            }   
        };

        for (int j = 0; j < xSize; j++) {
            for (int k = 0; k < ySize; k++) {
                int iter = mandelbrot(j, k);
                if (iter == maxIter) {
                    image.setRGB(j, k, 0);                  
                } else {
                    int local_rgb = colorMap[iter%64];
                    image.setRGB(j, k, local_rgb);
                }
            }
        }

        JFrame frame = new JFrame("JOCL Simple Mandelbrot");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        imageComponent.setPreferredSize(new Dimension(xSize, ySize));
        frame.add(imageComponent, BorderLayout.CENTER);
        frame.pack();

        frame.setVisible(true);
    }

    private static int mandelbrot(float j, float k) {
        int t = 0;
        float norm = 0;
        float x = 0;
        float y = 0;
        float r = xMin + (j * xStep);
        float i = yMin + (k * yStep);
        while (t < maxIter && norm < 4) {
            x = (x*x) - (y*y) + r;
            y = (2*x*y) + i;
            norm = (x*x) + (y*y);
            t++;
        }
        return t;
    }

Множество Мандельброта

Я также изменил код для набора Джулии (с номера 0,45 + 0,1428i), и он дает что-то столь же сомнительное:
Julia Set


person Syzorr    schedule 24.05.2016    source источник


Ответы (1)


Это ваш итерационный цикл, который неверен.

while (t < maxIter && norm < 4) {
    x = (x*x) - (y*y) + r;
    y = (2*x*y) + i;
    norm = (x*x) + (y*y);
    t++;
}

Вы перезаписываете x перед повторным использованием для вычисления y. Я предлагаю использовать временную переменную, например

while (t < maxIter && norm < 4) {
    tempx = (x*x) - (y*y) + r;
    y = (2*x*y) + i;
    x = tempx;
    norm = (x*x) + (y*y);
    t++;
}

Кроме того: есть место для некоторой эффективности, так как вы вычисляете x*x и y*y дважды.

person Weather Vane    schedule 24.05.2016
comment
О, спасибо за вторую пару глаз. Боже, не могу поверить, что пропустил этот идиотизм. Кроме того, да, я знаю, что есть место для эффективности, потому что я собираюсь очистить его. Цель состоит в том, чтобы сделать его параллельным, но желать работающего последовательного кода :) - person Syzorr; 24.05.2016
comment
Хотел проверить. И это чудесно :) - person Syzorr; 24.05.2016