Skip to content
Snippets Groups Projects
rings.js 2.76 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/usr/bin/env node
    
    /*
     * Three dimensional Node.js pattern based on the "Rings" Processing example.
     *
     * Uses noise functions modulated by sinusoidal rings, which themselves
     * wander and shift according to some noise functions.
     *
     * 2014 Micah Elizabeth Scott
     */
    
    var SimplexNoise = require('simplex-noise');
    var simplex = new SimplexNoise(Math.random);
    
    var OPC = new require('./opc');
    var model = OPC.loadModel(process.argv[2] || '../layouts/grid32x16z.json');
    var client = new OPC('localhost', 7890);
    
    var noiseScale = 0.02;
    var speed = 0.002;
    
    var scale = 0.1;
    var ringScale = 3.0;
    var wanderSpeed = 0.00005;
    
    var dx = 0, dz = 0, dw = 0;
    
    var min = Math.min;
    var max = Math.max;
    var sin = Math.sin;
    var cos = Math.cos;
    var pow = Math.pow;
    var sqrt = Math.sqrt;
    
    function fractalNoise(x, y, z, w)
    {
        // 4D fractal noise (fractional brownian motion)
    
        var r = 0;
        var amp = 0.5;
        for (var octave = 0; octave < 4; octave++) {
            r += (simplex.noise4D(x, y, z, w) + 1) * amp;
            amp /= 2;
            x *= 2;
            y *= 2;
            z *= 2;
            w *= 2;
        }
        return r;
    }
    
    
    function noise(x, spin)
    
    {
        // 1-dimensional noise. Cut a zig-zag path through
        // the simplex 2D noise space, so we repeat much less often.
    
        spin = spin || 0.01;
        return simplex.noise2D(x, x * spin) * 0.5 + 0.5;
    
    }
    
    function draw()
    {
        var now = new Date().getTime();
    
        var angle = sin(now * 0.001);
        var hue = now * 1.0;
    
        var saturation = min(max(pow(1.15 * noise(now * 0.000122), 2.5), 0), 1);
        var spacing = noise(now * 0.000124) * ringScale;
    
        // Rotate movement in the XZ plane
        dx += cos(angle) * speed;
        dz += sin(angle) * speed;
    
        // Random wander along the W axis
    
        dw += (noise(now * 0.00002) - 0.5) * wspeed;
    
        var centerx = (noise(now * wanderSpeed, 0.9) - 0.5) * 1.25;
        var centery = (noise(now * wanderSpeed, 1.4) - 0.5) * 1.25;
        var centerz = (noise(now * wanderSpeed, 1.7) - 0.5) * 1.25;
    
    
        function shader(p)
        {
            var x = p.point[0];
            var y = p.point[1];
            var z = p.point[2];
    
            var distx = x - centerx;
            var disty = y - centery;
            var distz = z - centerz;
    
            var dist = sqrt(distx*distx + disty*disty + distz*distz);
            var pulse = (sin(dz + dist * spacing) - 0.3) * 0.3;
          
            var n = fractalNoise(
                x * scale + dx + pulse,
                y * scale,
                z * scale + dz,
    
    
            var m = fractalNoise(
                x * scale + dx,
                y * scale,
                z * scale + dz,
    
            ) - 0.75;
    
            return OPC.hsv(
    
                saturation,
                min(max(pow(3.0 * n, 1.5), 0), 0.9)
            );
        }
    
        client.mapPixels(shader, model);
    }
    
    setInterval(draw, 10);