Last active
January 12, 2017 23:19
-
-
Save clawtros/b682fc49e4f050488cb593ebbdec8914 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use strict'; | |
| function convolve(arr, vs, size, x, y) { | |
| const hl = parseInt(arr.length / 2); | |
| return arr.map((row, offY)=>row.map((m, offX)=>vs[indexOf(x + offX - hl, y + offY - hl, size)] * m)) | |
| } | |
| function position(index, size) { | |
| return [Math.floor(index % size), Math.floor(index / size)] | |
| } | |
| function indexOf(x, y, size) { | |
| var lookupX = toroidClamp(x, size), | |
| lookupY = toroidClamp(y, size); | |
| return lookupX + lookupY * size; | |
| } | |
| function toroidClamp(n, maxN) { | |
| if (n < 0) return maxN + n; | |
| if (n >= maxN) return n - maxN; | |
| return n; | |
| } | |
| function flatten(arr) { | |
| return arr.reduce((a, b) => a.concat(b), []); | |
| } | |
| const ToroidVectorField = function(size, A, B) { | |
| const da = 1, | |
| db = 2, | |
| f = 0.55, | |
| k = 0.062, | |
| laplacianConvolution = [ | |
| [0.05, 0.2, 0.05], | |
| [0.2, -1, 0.2], | |
| [0.05, 0.2, 0.05]]; | |
| let d = []; | |
| function flatConvolve(idx, arr) { | |
| const p = position(idx, size); | |
| return flatten(convolve(laplacianConvolution, arr, size, p[0], p[1])) | |
| } | |
| function applyConvolve(arr, func) { | |
| return arr.map((v, idx) => func(v, flatConvolve(idx, arr).reduce((a, b) => a + b, 0) / 9, idx)) | |
| } | |
| function step(t) { | |
| let last = []; | |
| const nextA = applyConvolve(A, (val, cval, idx) => val + da * ((cval - cval * B[idx] * B[idx]) + f * (1 - cval)) * t), | |
| nextB = applyConvolve(B, (val, cval, idx) => val + (db * (cval + cval * B[idx] * B[idx]) - (k + f)) * t); | |
| return ToroidVectorField(size, nextA, nextB) | |
| } | |
| return { step, size, A, B } | |
| } | |
| var CanvasVisualizer = function(canvas, size) { | |
| var context = canvas.getContext('2d'), | |
| canvasWidth = size, | |
| canvasHeight = size; | |
| canvas.width = canvasWidth; | |
| canvas.height = canvasHeight; | |
| return { | |
| draw: function(vectorField) { | |
| vectorField.B.map((v, idx)=>{ | |
| const p = position(idx, vectorField.size), | |
| color = parseInt(((v + vectorField.B[idx]) / 2) * 255); | |
| context.fillStyle = `rgb(${color}, ${color}, 0)`; | |
| // context.fillStyle = `hsl(${color % 360}, 70%, 40%)`; | |
| context.fillRect.apply(context, p.concat([1, 1])) | |
| }) | |
| } | |
| } | |
| } | |
| function distance(x1, y1, x2, y2) { | |
| let dx = x1 - x2, | |
| dy = y1 - y2; | |
| return Math.sqrt(dx * dx + dy * dy); | |
| } | |
| function randomField(size) { | |
| const A = new Float32Array(size*size).map(_ => 0), | |
| B = new Float32Array(size*size).map((_, idx) => { | |
| const p = position(idx, size), | |
| d = distance(p[0], p[1], size / 2, size / 2); | |
| return d > 40 || d < 30 || Math.random() < 0.5 ? 1 : 0; | |
| }); | |
| return new ToroidVectorField(size, A, B); | |
| } | |
| var canvas = document.createElement('canvas'), | |
| size = 200, | |
| vf = randomField(size), | |
| viz = CanvasVisualizer(canvas, size); | |
| document.body.appendChild(canvas); | |
| function go() { | |
| requestAnimationFrame(go); | |
| viz.draw(vf); | |
| vf = vf.step(0.005) | |
| //viz.draw(vf); | |
| }; | |
| go(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment