Jump to content

Advanced Julia Fractal


Recommended Posts

This plugin can be used to render Julia set fractals using a variety of settings. Adding color options would have made the UI too big, but it can be achieved using my Duotone Gradient Mapping plugin.

I hope you enjoy this one!

 

Download:

 Advanced Julia Fractal.zip

Can be found in Effects > Render > Advanced Julia Fractal

 

Previews:

1135822739_ajfdemo3.jpg.bfd546537346501184ebcc9428c2e8c8.jpg

 510867675_ajfdemo.jpg.07ed616f59e563f0ddb5eed18490d125.jpg17228949_ajfdemo2.jpg.9e20193e9e7c9b761de0a86cb04ad033.jpg

Code:

(Made in a few hours, so there is probably a lot to improve)

// Name: Advanced Julia Fractal
// Submenu: Render
// Author: Pascal
// Title: Advanced Julia Fractal
// Version: 1.0.0
// Desc:
// Keywords:
// URL:
// Help:
#region UICode
IntSliderControl ca = 0; //[-300,300] Real part of constant
IntSliderControl cb = 0; //[-300,300] Imaginary part of constant
IntSliderControl zoom = 5000; // [1,100000] Zoom
IntSliderControl xoff = 0; // [-10000,10000] Offset X
IntSliderControl yoff = 0; // [-10000,10000] Offset Y
IntSliderControl iterations = 50; //[1,200] Iterations
IntSliderControl type = 0; //[0,3] Render type
CheckboxControl innerCol = false; //Inner color
CheckboxControl invert = false; //Invert
CheckboxControl trans = false; //Transparency
CheckboxControl invertTrans = false; //Invert Transparency
IntSliderControl thresh = 0; //[0,1000] Clean
IntSliderControl bright = 0; //[-100,100] Brightness
IntSliderControl contr = 0; //[0,100] Contrast
CheckboxControl alpha = false; //Preserve alpha
#endregion

public void Render(Surface dst, Surface src, Rectangle rect)
{
    Rectangle selection = EnvironmentParameters.SelectionBounds;
    int sw = selection.Right-selection.Left;
    int sh = selection.Bottom-selection.Top;
    int dw = selection.Left;
    int dh = selection.Top;

    ColorBgra CurrentPixel;
    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        if (IsCancelRequested) return;
        for (int x = rect.Left; x < rect.Right; x++)
        {
            if (IsCancelRequested) return;
            CurrentPixel = src[x,y];
            
            double a = x-dw;
            double b = y-dh;
            double ca = this.ca/100f;
            double cb = this.cb/200f;
            double dx = (double)xoff;
            double dy = (double)yoff;
            double zoom = Math.Pow(this.zoom/100000f,2)*100000f;
            float val = fractal(
                (a-sw/2)/zoom + dx/10000f,
                (b-sh/2)/zoom + dy/10000f,
                ca,
                cb,
                iterations,
                type
            );

            double thresh = this.thresh/1000f;
            if(val<thresh || innerCol && val >= (iterations-1)/(float)iterations){
                val=0;
            }

            if(invert){
                val = 1-val;
            }

            val+= bright/100f;
            val = limit(val,0,1);
            val = contrast(val,contr);
            val = limit(val,0,1);

            CurrentPixel.R = (byte)limit(val*255,0,255);
            CurrentPixel.G = (byte)limit(val*255,0,255);
            CurrentPixel.B = (byte)limit(val*255,0,255);

            byte A = CurrentPixel.A;
            CurrentPixel.A = 255;
            if(trans){
                if(!invert^invertTrans){
                    CurrentPixel.A = CurrentPixel.R;
                }
                else{
                    CurrentPixel.A = (byte)(255-CurrentPixel.R);
                }
            }
            if(alpha){
                CurrentPixel.A = (byte)(CurrentPixel.A*A/255);
            }

            dst[x,y] = CurrentPixel;
        }
    }
}

private float fractal(double x, double y,double ca, double cb, int n, int type){
    if(type == 0 && x*x+y*y<n && n>0){
        return fractal(x*x-y*y+ca,2*x*y+cb,ca,cb,--n,type);
        }
    if(type == 1 && Math.Abs(x+y)<2 && n>0){
        return fractal(x*x-y*y+ca,2*x*y+cb,ca,cb,--n,type);
        }
    if(type == 2 && y<2 && n>0){
        return fractal(x*x-y*y+ca,2*x*y+cb,ca,cb,--n,type);
    }
    if(type == 3 && x<2 && n>0){
        return fractal(x*x-y*y+ca,2*x*y+cb,ca,cb,--n,type);
    }
    else{
        return 1-n/(float)iterations;
    }
}

private float limit(float v, int min, int max){
    if(v>max)v=max;
    else if(v<min)v=min;
    return v;
}

private float contrast(float x, double c){
    double y;
    c = Math.Pow(c/2,3);
    if(x <= .5f){
        y = .5f * Math.Pow(2*x, (c/500)+1);
    }
    else{
        y = 1 - .5f * Math.Pow(2 - 2*x, (c/500)+1);
    }
    return (float)y;
}

 

Edited by pascal
  • Like 3
  • Upvote 6
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...