Search code examples
javaswingmathawtpaintcomponent

Julia Set Rendering on JPanel in Java - colours only one Pixel


I am attempting to write a program that renders the Mandelbrot set, and then a Julia Set for a complex number in another panel, when the user clicks on a point on the Mandelbrot set panel.

However, my Julia's set rendering code for some reason does not work. It appears to only colour the top-left most pixel, and I cannot figure out why this might me. I don't know if the maths is wrong in the rendering method, or if the colouring is the issue. Any pointers or a solution would be fantastic - been scratching my head over this for awhile.

If anyone would find this easier to solve by having all of the code, please let me know - thanks.

Here is the code for just the Julia's Set Panel, everything else has been omitted.

  class juliaPanel extends JPanel {

        ComplexNumber fixedNumber = new ComplexNumber(0,0);
        double newReal, newImaginary, oldReal, oldImaginary;

        public void setFixedNumber(ComplexNumber fixedNumberIn) {
            fixedNumber = fixedNumberIn;
        }

        public void paintComponent(Graphics g){
            super.paintComponent(g);
            newReal = 0;
            newImaginary = 0;
            int i;
            for(int y = 0; y < height; y++) {
                for(int x = 0; x < width; x++) {
                    for (i=0; i< iterationsToDo; i++) {
                        oldReal = newReal;
                        oldImaginary = newImaginary;
                        newReal = oldReal * oldReal - oldImaginary * oldImaginary + fixedNumber.getReal();
                        newImaginary = 2 * oldReal * oldImaginary + fixedNumber.getImaginary();
                        if((newReal * newReal + newImaginary * newImaginary) > 4) break;
                    }
                    if(i == 255){
                        g.setColor(Color.BLACK);
                    }else{
                         g.setColor(Color.getHSBColor(i/100.0F,1F,1F));
                    }
                    g.fillRect(x, y, 1, 1);
                }
            }   
        }

Solution

  • Before starting the inner loop over i, i.e., after x and y have changed to the next pixel, you need to set the initial complex number according to this pixel, something like

    newReal = minReal + x*deltaReal;
    newImag = maxImag - y*deltaImag;
    

    where the min and max are -2.0 and 2.0 and the delta are 4.0/width and 4.0/height or the minimum of both to get 1:1 aspect ratio.