#!/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 wspeed = 0.01; 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, dw ) - 0.95; var m = fractalNoise( x * scale + dx, y * scale, z * scale + dz, dw + 10.0 ) - 0.75; return OPC.hsv( hue + 0.2 * m, saturation, min(max(pow(3.0 * n, 1.5), 0), 0.9) ); } client.mapPixels(shader, model); } setInterval(draw, 10);