Search code examples
javaalgorithmmathcolorsfractals

Rendering exponential and periodic Julia fractals


I've read how to render Julia fractals here. I'm pretty thorough with two-degree Julia sets with equations of form f(z)=z2+C but I don't know how to render complex Julia functions like f(z) = ez - 0.65 and other complex functions which involve sine and cosine. How do we render these type of functions? Also, what color mapping should be used in exponential functions?

For instance I want to achieve something like the following image and others given on Wikipedia page.

enter image description here

EDIT :

Here is what I tried:

ComplexNumber.java

package plane.complex;

/**
* code>ComplexNumber</code> is a class which implements complex numbers in Java. 
* It includes basic operations that can be performed on complex numbers such as,
* addition, subtraction, multiplication, conjugate, modulus and squaring. 
*
* @author      Abdul Fatir
* @version      1.0
* 
*/
public class ComplexNumber
{
/**
* The real, Re(z), part of the <code>ComplexNumber</code>.
*/
private double real;
/**
* The imaginary, Im(z), part of the <code>ComplexNumber</code>.
*/
private double imaginary;
/**
* Constructs a new <code>ComplexNumber</code> object with both real and imaginary parts 0 (z = 0 + 0i).
*/
public ComplexNumber()
{
    real = 0.0;
    imaginary = 0.0;
}

/**
* Constructs a new <code>ComplexNumber</code> object.
* @param real the real part, Re(z), of the complex number
* @param imaginary the imaginary part, Im(z), of the complex number
*/

public ComplexNumber(double real, double imaginary)
{
    this.real = real;
    this.imaginary = imaginary;
}

/**
* Adds another <code>ComplexNumber</code> to the current complex number.
* @param complex_number the complex number to be added to the current complex number
*/

public void add(ComplexNumber complex_number)
{
    this.real = this.real + complex_number.real;
    this.imaginary = this.imaginary + complex_number.imaginary;
}

/**
* The complex conjugate of the current complex number.
* @return a <code>ComplexNumber</code> object which is the conjugate of the current complex number
*/

public ComplexNumber conjugate()
{
    return new ComplexNumber(this.real,-this.imaginary);
}

/**
* The modulus, magnitude or the absolute value of current complex number.
* @return the magnitude or modulus of current complex number
*/

public double mod()
{
    return Math.sqrt(Math.pow(this.real,2) + Math.pow(this.imaginary,2));
}

/**
* The square of the current complex number.
* @return a <code>ComplexNumber</code> object which is the square of the current complex number
*/

public ComplexNumber square()
{
    double _real = this.real*this.real - this.imaginary*this.imaginary;
    double _imaginary = 2*this.real*this.imaginary;
    return new ComplexNumber(_real,_imaginary);
}

/**
* Multiplies another <code>ComplexNumber</code> to the current complex number.
* @param complex_number the complex number to be multiplied to the current complex number
*/

public void multiply(ComplexNumber complex_number)
{
    double _real = this.real*complex_number.real - this.imaginary*complex_number.imaginary;
    double _imaginary = this.real*complex_number.imaginary + this.imaginary*complex_number.real;

    this.real = _real;
    this.imaginary = _imaginary;
}

/**
* Prints the complex number in x + yi format
*/
@Override
public String toString()
{
    return this.real+" + "+this.imaginary+"i";
}
/**
* Calculates the exponential of the <code>ComplexNumber</code>
* @param complex_number The input complex number
* @return a <code>ComplexNumber</code> which is e^(input complex_number)
*/
public static ComplexNumber exp(ComplexNumber complex_number)
{
    double a = complex_number.real;
    double b = complex_number.imaginary;
    a = Math.exp(a)*Math.cos(b);
    b = Math.exp(a)*Math.sin(b);
    return new ComplexNumber(a,b);
}
}

Here is how I tried to render:

for(int X=0; X<WIDTH; X++)
    {
        for(int Y=0; Y<HEIGHT; Y++)
        {
            ComplexNumber oldz = new ComplexNumber();
            ComplexNumber newz = new ComplexNumber(2.0*(X-WIDTH/2)/(WIDTH/2), 1.33*(Y-HEIGHT/2)/(HEIGHT/2) );
            int i;
            for(i=0;i<max_iter; i++)
            {
                oldz = newz;
                newz=ComplexNumber.exp(newz);
                newz.add(constant);
                if(newz.mod() > 2)
                    break;
            }
            float Brightness = i < max_iter ? 1f : 0;
            float Hue = i%256 /255.0f;
            Color color = Color.getHSBColor(Hue, Saturation, Brightness);
            img.setRGB(X,Y, color);
        }
    }

Solution

  • In the exp function, you used the value a again after changing it, but requiring it in its unchanged version. Replace with

    public static ComplexNumber exp(ComplexNumber complex_number)
    {
        double a = complex_number.real;
        double b = complex_number.imaginary;
        double r = Math.exp(a);
        a = r*Math.cos(b);
        b = r*Math.sin(b);
        return new ComplexNumber(a,b);
    }