www.xbdev.net
xbdev - software development
Thursday May 8, 2025
Home | Contact | Support | Fractals Natures pattern... | Fractals Natures pattern...
     
 

Fractals

Natures pattern...

 


Fractals > Fractal Patterns (Images)


Fractal patterns, including XOR and plasma, are captivating visual phenomena that emerge from the iterative application of simple mathematical rules. These patterns exhibit self-similarity, meaning that they appear similar at different scales, offering intricate and mesmerizing detail when zoomed in or out. Fractals have found applications in various fields, from art and design to science and engineering, owing to their aesthetic appeal and underlying mathematical elegance.


XOR Fractal Pattern


<html lang="en">
<
head>
<
meta charset="UTF-8">
<
meta name="viewport" content="width=device-width, initial-scale=1.0">
<
title>Fractal XOR Image</title>
<
style>
    
canvas {
        
border1px solid black;
    }
</
style>
</
head>
<
body>
<
canvas id="fractalCanvas" width="400" height="400"></canvas>

<
script>
// Function to generate an XOR pattern
function generateXORPattern(widthheightxx) {
    
let xorPattern = [];
    for (
let y 0heighty++) {
        
let row = [];
        for (
let x 0widthx++) {
            
let cc = ((xx) ^ y) & 0xFF;
            
let r = (cc >> 16) & 0xFF;
            
let g = (cc >> 8) & 0xFF;
            
let b cc 0xFF;
            
row.push(0xff << 24 << 16 << b);
        }
        
xorPattern.push(row);
    }
    return 
xorPattern;
}

// Get canvas and its context
let canvas document.getElementById('fractalCanvas');
let ctx canvas.getContext('2d');

// Generate XOR pattern
let width canvas.width;
let height canvas.height;
let xx 0;
let xorPattern generateXORPattern(widthheightxx);

// Draw XOR pattern on canvas
for (let y 0heighty++) {
    for (
let x 0widthx++) {
        
let pixelValue xorPattern[y][x];
        
ctx.fillStyle 'rgb(' + (pixelValue >> 16 0xFF) + ',' + (pixelValue >> 0xFF) + ',' + (pixelValue 0xFF) + ')';
        
ctx.fillRect(xy11);
    }
}
</
script>
</
body>
</
html>


Example output would look something like:





Things to Try

• Different colors (instead of just 2 colors - try and use gradient/more complex patterns)
• Animate the pattern so it scrolls
• Mix in a rotational effect so it has a 'swirl'
• Random - add tiny bit of randomness into the algorithm to make the pattern more unique and interesting




Plasma Fractal Pattern


<html lang="en">
<
head>
<
meta charset="UTF-8">
<
meta name="viewport" content="width=device-width, initial-scale=1.0">
<
title>Plasma Image</title>
<
style>
    
canvas {
        
border1px solid black;
    }
</
style>
</
head>
<
body>
<
canvas id="plasmaCanvas" width="320" height="320"></canvas>

<
script>
class 
Plasma {
    
unitRand() {
        return 
Math.random();
    }

    
displace(numwidthheight) {
        
let max num / (width height) * 0.5;
        
let r this.unitRand();
        return (
0.5) * max;
    }

    
computeColor(c) {
        
let redgreenblue;

        if (
0.5) {
            
red 2;
        } else {
            
red = (c) * 2;
        }

        if (
>= 0.3 && 0.8) {
            
green = (0.3) * 2;
        } else if (
0.3) {
            
green = (0.3 c) * 2;
        } else {
            
green = (1.3 c) * 2;
        }

        if (
>= 0.5) {
            
blue = (0.5) * 2;
        } else {
            
blue = (0.5 c) * 2;
        }

        
// Convert to RGB values between 0 and 255
        
let r Math.round(red 255);
        
let g Math.round(green 255);
        
let b Math.round(blue 255);

        return `
rgb(${r}${g}${b})`;
    }

    
divideGrid(ctxxywidthheightc1c2c3c4) {
        
let newWidth width 2;
        
let newHeight height 2;

        if (
width || height 2) {
            
let middle = (c1 c2 c3 c4) / this.displace(newWidth newHeightwidthheight);

            
let edge1 = (c1 c2) / 2;
            
let edge2 = (c2 c3) / 2;
            
let edge3 = (c3 c4) / 2;
            
let edge4 = (c4 c1) / 2;

            
this.divideGrid(ctxxynewWidthnewHeightc1edge1middleedge4);
            
this.divideGrid(ctxnewWidthynewWidthnewHeightedge1c2edge2middle);
            
this.divideGrid(ctxnewWidthnewHeightnewWidthnewHeightmiddleedge2c3edge3);
            
this.divideGrid(ctxxnewHeightnewWidthnewHeightedge4middleedge3c4);
        } else {
            
let c = (c1 c2 c3 c4) / 4;
            
let color this.computeColor(c);
            
ctx.fillStyle color;
            
ctx.fillRect(xy11);
        }
    }

    
drawPlasma(ctxwidthheight) {
        
let c1 this.unitRand();
        
let c2 this.unitRand();
        
let c3 this.unitRand();
        
let c4 this.unitRand();

        
this.divideGrid(ctx00widthheightc1c2c3c4);
    }
}

// Get canvas and its context
let canvas document.getElementById('plasmaCanvas');
let ctx canvas.getContext('2d');

// Create Plasma instance and draw plasma on canvas
let plasma = new Plasma();
plasma.drawPlasma(ctxcanvas.widthcanvas.height);
</
script>
</
body>
</
html>


Example output would look something like:






Things to Try

• Try other colors
• Try different resolutions
• Modify the random number generator (less random or uses a trig function instead)
• Animate the effect (seed the random number, create two images and interpolate between them, so it's smooth and not a crazy set of flashing patterns)


Perlin Noise Pattern


<html>
<
head></head>
<
body>
<
script>
// Define the PerlinNoise class
class PerlinNoise {
  
constructor(seed) {
    
this.seed seed || 0;
    
this.= [];
    
this.g2 = [];
    
this.g1 = [];
    
this.init();
  }

  
init() {
    
let r Math.random// new Math.seedrandom(this.seed);
    
for (let i 0256i++) {
      
this.p[i] = Math.floor(r() * 256);
      
this.g1[i] = (r() * 2) - 1;
      
this.g2[i] = [(r() * 2) - 1, (r() * 2) - 1];
      
let len Math.sqrt(this.g2[i][0] * this.g2[i][0] + this.g2[i][1] * this.g2[i][1]);
      
this.g2[i][0] /= len;
      
this.g2[i][1] /= len;
    }

    
// Duplicate the permutation array to avoid boundary cases
    
for (let i 0256i++) {
      
this.p[256 i] = this.p[i];
      
this.g1[256 i] = this.g1[i];
      
this.g2[256 i] = this.g2[i];
    }
  }

  
noise(xy) {
    
let X Math.floor(x) & 255,
      
Math.floor(y) & 255;
    
-= Math.floor(x);
    
-= Math.floor(y);
    
let u this.fade(x),
      
this.fade(y);
    
let A this.p[X] + Y,
      
AA this.p[A],
      
AB this.p[1],
      
this.p[1] + Y,
      
BA this.p[B],
      
BB this.p[1];

    return 
this.lerp(vthis.lerp(uthis.grad(this.p[AA], xy), this.grad(this.p[BA], 1y)),
      
this.lerp(uthis.grad(this.p[AB], x1), this.grad(this.p[BB], 11)));
  }

  
fade(t) {
    return 
* (* (15) + 10);
  }

  
lerp(tab) {
    return 
* (a);
  }

  
grad(hashxy) {
    
let h hash 7;
    
let u y,
      
x;
    return ((
1) ? -u) + ((2) ? -2.0 2.0 v);
  }
}

// Main function to generate Perlin noise pattern
function PerlinNoisePattern(widthheightseed) {
  
let noise = new PerlinNoise(seed);
  
let pixels = new Uint8ClampedArray(width height 4);

  
let index 0;
  for (
let y 0heighty++) {
    for (
let x 0widthx++) {
      
let value noise.noise(100100);
      
let color Math.abs(value) * 255// Scale noise value to 0-255
      
pixels[index++] = color// Red
      
pixels[index++] = color// Green
      
pixels[index++] = color// Blue
      
pixels[index++] = 255// Alpha
    
}
  }

  return new 
ImageData(pixelswidthheight);
}

// Example usage
let canvas document.createElement('canvas');
let ctx canvas.getContext('2d');
let width 320height 320;
canvas.width width;
canvas.height height;
let imageData PerlinNoisePattern(widthheight100); // Seed = 100
ctx.putImageData(imageData00);
document.body.appendChild(canvas);
</
script>
</
body>
</
html>


Example output would look something like:





Things to Try

• Add colors (not just black and white)
• Modify the resolution (different size bubbles and distributions)


Fire Fractal Effect (Animated)


<html>
<
head></head>
<
body>
<
script>
// Define canvas properties
const canvas document.createElement('canvas');
const 
ctx canvas.getContext('2d');
const 
width 400;
const 
height 200;
canvas.width width;
canvas.height height;
document.body.appendChild(canvas);

// Define fire properties
const fireWidth width
const 
fireHeight height
const 
fireColors = ['#070707''#1F0707''#2F0F07''#470F07''#571707''#671F07''#771F07''#8F2707''#9F2F07''#AF3F07''#BF4707''#C74707''#DF4F07''#DF5707''#DF5707''#D75F07''#D75F07''#D7670F''#CF6F0F''#CF770F''#CF7F0F''#CF8717''#C78717''#C78F17''#C7971F''#BF9F1F''#BF9F1F''#BF-A727''#BF-A727''#BF-AF2F''#B7-AF2F''#B7-B72F''#B7-B737''#CFCF6F''#DFDF9F''#EFEFC7''#FFFFFF'];

// Create fire array and initialize it
let firePixels = new Array(fireWidth fireHeight).fill(0);

// Function to initialize fire
function initFire() {
  for (
let x 0fireWidthx++) {
    
firePixels[(fireHeight 1) * fireWidth x] = 36// Set bottom row to maximum intensity
  
}
}

// Function to update fire
function updateFire() {
  for (
let x 0fireWidthx++) {
    for (
let y 0fireHeight 1y++) {
      
let index fireWidth x;
      
let belowIndex = (1) * fireWidth x;
      
let decay Math.floor(Math.random() * 3); // Random decay to create flickering effect
      
let newIntensity firePixels[belowIndex] - decay;
      if (
newIntensity 0newIntensity 0// Ensure intensity does not go below zero
      
firePixels[index] = newIntensity;
    }
  }
}

// Function to render fire
function renderFire() {
  for (
let x 0fireWidthx++) {
    for (
let y 0fireHeighty++) {
      
let index fireWidth x;
      
let intensity firePixels[index];
      
let color fireColors[intensity];
      
ctx.fillStyle color;
      
ctx.fillRect(x, (1), 11);
    }
  }
}

// Main loop to update and render fire
function loop() {
  
updateFire();
  
renderFire();
  
requestAnimationFrame(loop);
}

// Initialize and start the fire effect
initFire();
loop();

</
script>
</
body>
</
html>







Things to Try

• Try other colors (e.g., blue or green fire)
• Scale the fire (so it's larger)
• Mix in some randomness so it's not so even
• Try generating a small fire, stretch (scale it up) and blur it
• Modify the speed of the animation






























 
Advert (Support Website)

 
 Visitor:
Copyright (c) 2002-2025 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.