Bellaard.com

Donuts fractal

By: Gijs Bellaard

Donut Fractal

Description

The Donuts Fractal is created by repeatedly placing 8 equidistant donuts around all the donuts.

GLSL Code


// the amount of iterations
const int ITERATIONS = 15;

// the scaling factor between iterations
const float SCALE = 3.0;

// the major radius of the donut
const float MAJOR_RADIUS = 1.0;

// the minor radius of the donut
const float MINOR_RADIUS = 0.1;
    
// fold normals
const vec3 N1 = normalize(vec3(1, 0, -1));
const vec3 N2 = normalize(vec3(0.38268343236, 0, -0.92387953251));

// returns the distance to a donut with a specified major and minor radius
float distanceDonut(vec3 p, float major, float minor)
{
    vec2 q = vec2(length(p.xz) - major, p.y);
    return length(q) - minor;
}

float distanceDonutsFractal(vec3 p)
{
    float dis = INFINITY;
    float s = 1.0;
    
    for(int i=0; i<ITERATIONS; i++)
    {
        // distance to a donut
        dis = min(dis, distanceDonut(p,MAJOR_RADIUS, MINOR_RADIUS) / s);  
        
        // fold everything towards positive x axis
        p.xz = abs(p.xz);
        p -= 2.0 * min(0.0, dot(p, N1)) * N1;   
        p -= 2.0 * min(0.0, dot(p, N2)) * N2; 

        // rotate 90 degrees about the x axis
        p  = vec3(p.x, p.z, -p.y);

        // offset
        p.x -= MAJOR_RADIUS;    

        // scaling
        p *= SCALE;
        s *= SCALE;
    }

    return dis; 
}