Published
Edited
Feb 12, 2020
2 stars
Insert cell
Insert cell
Insert cell
kernel = {
// Created by Daniel Burke - burito/2014
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

// Inspiration from Dr Who (2005) S7E13 - The Name of the Doctor

const gpu = new GPU.GPU({ mode: 'gpu' });

function _clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
gpu.addFunction(_clamp);
function circle(pos, radius) {
return _clamp(((1.0-Math.abs(_length(pos) - radius)) - 0.99) * 100, 0, 1);
}
gpu.addFunction(circle);
function _length(point) {
return Math.sqrt(point[0] * point[0] + point[1] * point[1]);
}
gpu.addFunction(_length);
function circleFill(pos, radius) {
return _clamp(((1.0 - (_length(pos) - radius)) - 0.99) * 100, 0, 1);
}
gpu.addFunction(circleFill);

function _dot(left, right) {
return left[0] * right[0] + left[1] * right[1];
}
gpu.addFunction(_dot);
function subtractArray2(left, right) {
return [left[0] - right[0], left[1] - right[1]];
}
gpu.addFunction(subtractArray2);
function addArray2(left, right) {
return [left[0] + right[0], left[1] + right[1]];
}
gpu.addFunction(addArray2);
function negativeArray2(value) {
return [-value[0], -value[1]];
}
gpu.addFunction(negativeArray2);
function multiplyArray2(left, right) {
return [left[0] * right[0], left[1] * right[1]];
}
gpu.addFunction(multiplyArray2);
// Thanks Iñigo Quilez!
function line(p, a, b) {
const pa = subtractArray2(negativeArray2(p), a);
const ba = subtractArray2(b, a);
const h = _clamp(_dot(pa,ba) / _dot(ba,ba), 0, 1);
const d = _length(subtractArray2(pa, multiplyArray2(ba, [h, h])));

return _clamp(((1 - d) - 0.99) * 100, 0, 1);
}
gpu.addFunction(line);
return gpu.createKernel(function(t) {
const uv = [this.thread.x / this.output.x, this.thread.y / this.output.y];
const p = [-1 + 2 * uv[0], -1 + 2 * uv[1]];
p[0] *= this.output.x / this.output.y;
let colour = [0, 0, 0];
const white = [1, 1, 1];

let c = circle(p, 0.2);
c += circle(p, 0.1);
c += circle(p, 0.18);
c += circleFill(p, 0.005);

// c += circle(p, 1.3);
c += circle(p, 1);
if (p[0] > 0) c += circle(p, 0.4);
if (p[0] > 0) c += circle(p, 0.42);
if (p[0] < 0) c += circle(p, 0.47);
c += circleFill(addArray2(p, [0.47, 0.0]), 0.02);
c += circleFill(addArray2(p, [0.84147 * 0.47, 0.54030 * 0.47]), 0.02);
c += circleFill(addArray2(p, [0.84147 * 0.47, -0.54030 * 0.47]), 0.02);
c += circleFill(addArray2(p, [0.41614 * 0.47, 0.90929 * 0.47]), 0.02);
c += circleFill(addArray2(p, [0.41614 * 0.47, -0.90929 * 0.47]), 0.02);
const t2 = t * -0.01;
const t3 = t * 0.03;
const angle1 = [Math.sin(t), Math.cos(t)];
const a = [angle1[0] * 0.7, angle1[1] * 0.7];
const t0 = t * 0.5;
const angle2 = [Math.sin(t0), Math.cos(t0)];
const b = [angle2[0] * 0.8, angle2[1] * 0.08];
const angle3 = [Math.sin(t2), Math.cos(t2)];
const d = [b[0] + angle3[0] * 0.4, b[1] + angle3[1] * 0.4];

const angle4 = [Math.sin(t3), Math.cos(t3)];
const e = [angle4[0] * 0.9, angle4[1] * 0.9];

const angle5 = [Math.sin(t3 + 4), Math.cos(t3 + 4)];
const f = [angle5[0] * 0.8, angle5[1] * 0.8];
const angle6 = [Math.sin(t0 * -0.1 + 5), Math.cos(t0 * -0.1 + 5)];
const h = [angle6[0] * 0.8, angle6[1] * 0.8];



let tt = t0 * 1.4;
let tm = tt % 0.5;
let tmt = tt - tm;
if (tm > 0.4) tmt += (tm - 0.4) * 5;
const tangle1 = [Math.sin(tmt), Math.cos(tmt)];

tt *= 0.8;
tm = tt % 0.6;
let tmt2 = tt - tm;
if (tm > 0.2) tmt2 += (tm - 0.2) * 1.5;
const tangle2 = [Math.sin(tmt2 * -4.0), Math.cos(tmt2 * -4.0)];
const tangle3 = [Math.sin(tmt2), Math.cos(tmt2)];
tt = t + 3;
tm = tt % 0.2;
tmt = tt - tm;
if (tm > 0.1) tmt += (tm - 0.1) * 2;
const tangle4 = [Math.sin(-tmt), Math.cos(-tmt)]; tmt += 0.9;
const tangle41 = [Math.sin(-tmt), Math.cos(-tmt)]; tmt += 0.5;
const tangle42 = [Math.sin(-tmt), Math.cos(-tmt)]; tmt += 0.5;
const tangle43 = [Math.sin(-tmt), Math.cos(-tmt)]; tmt += 0.5;
const tangle44 = [Math.sin(-tmt), Math.cos(-tmt)]; tmt += 0.5;
const tangle45 = [Math.sin(-tmt), Math.cos(-tmt)];

tt = t + 0.001;
tm = tt % 1;
tmt = tt - tm;
if (tm > 0.9) tmt += (tm - 0.9) * 10;

const tangle51 = [0.17 * Math.sin(-tmt), 0.17 * Math.cos(-tmt)]; tmt += 1.0471975511965976;
const tangle52 = [0.17 * Math.sin(-tmt), 0.17 * Math.cos(-tmt)]; tmt += 1.0471975511965976;
const tangle53 = [0.17 * Math.sin(-tmt), 0.17 * Math.cos(-tmt)];
c += line(p, tangle51, negativeArray2(tangle53));
c += line(p, tangle52, tangle51);
c += line(p, tangle53, tangle52);
c += line(p, negativeArray2(tangle51), tangle53);
c += line(p, negativeArray2(tangle52), negativeArray2(tangle51));
c += line(p, negativeArray2(tangle53), negativeArray2(tangle52));

c += circleFill(addArray2(p, tangle51), 0.01);
c += circleFill(addArray2(p, tangle52), 0.01);
c += circleFill(addArray2(p, tangle53), 0.01);
c += circleFill(subtractArray2(p, tangle51), 0.01);
c += circleFill(subtractArray2(p, tangle52), 0.01);
c += circleFill(subtractArray2(p, tangle53), 0.01);
c += circle(addArray2(p, a), 0.2);
c += circle(addArray2(p, a), 0.14);
c += circle(addArray2(p, a), 0.1);
c += circleFill(addArray2(p, a), 0.04);
c += circleFill(addArray2(addArray2(p, a), multiplyArray2(tangle3, [0.2, 0.2])), 0.025);
c += circle(addArray2(p, a), 0.14);


c += circle(addArray2(p, b), 0.2);
c += circle(addArray2(p, b), 0.03);
c += circle(addArray2(p, b), 0.15);
c += circle(addArray2(p, b), 0.45);
c += circleFill(addArray2(addArray2(p, b), multiplyArray2(tangle1, [0.05, 0.05])), 0.01);
c += circleFill(addArray2(addArray2(p, b), multiplyArray2(tangle1, [0.09, 0.09])), 0.02);
c += circleFill(addArray2(addArray2(p, b), multiplyArray2(tangle1, [0.15, 0.15])), 0.03);
c += circle(addArray2(addArray2(p, b), multiplyArray2(tangle1, [-0.15, -0.15])), 0.03);
c += circle(addArray2(addArray2(p, b), multiplyArray2(tangle1, [-0.07, -0.07])), 0.015);

c += circle(addArray2(p, d), 0.08);


c += circle(addArray2(p, e), 0.08);

c += circle(addArray2(p, f), 0.12);
c += circle(addArray2(p, f), 0.10);
c += circleFill(addArray2(addArray2(p, f), multiplyArray2(tangle2, [0.05, 0.05])), 0.01);
c += circleFill(addArray2(addArray2(p, f), multiplyArray2(tangle2, [0.10, 0.10])), 0.01);
c += circle(subtractArray2(addArray2(p, f), multiplyArray2(tangle2, [0.03, 0.03])), 0.01);
c += circleFill(addArray2(addArray2(p, f), [0.085, 0.085]), 0.005);
c += circleFill(addArray2(p, f), 0.005);

const g = multiplyArray2(tangle4, [0.16, 0.16]);
c += circle(addArray2(p, h), 0.05);
c += circle(addArray2(p, h), 0.1);
c += circle(addArray2(p, h), 0.17);
c += circle(addArray2(p, h), 0.2);
c += circleFill(addArray2(addArray2(p, h), multiplyArray2(tangle41, [0.16, 0.16])), 0.01);
c += circleFill(addArray2(addArray2(p, h), multiplyArray2(tangle42, [0.16, 0.16])), 0.01);
c += circleFill(addArray2(addArray2(p, h), multiplyArray2(tangle43, [0.16, 0.16])), 0.01);
c += circleFill(addArray2(addArray2(p, h), multiplyArray2(tangle44, [0.16, 0.16])), 0.01);
c += circleFill(addArray2(addArray2(p, h), multiplyArray2(tangle45, [0.16, 0.16])), 0.01);
c += circleFill(addArray2(addArray2(p, h), multiplyArray2(angle1, [0.06, 0.06])), 0.02);
c += circleFill(addArray2(addArray2(p, h), multiplyArray2(tangle43, [-0.16, -0.16])), 0.01);
c += line(p, [0, 0], a);
c += circleFill(addArray2(p, b), 0.005);
c += circleFill(addArray2(p, d), 0.005);
c += circleFill(addArray2(p, e), 0.005);

c += line(p, b, a);
c += line(p, d, e);
c += line(p, addArray2(b, multiplyArray2(tangle1, [0.15, 0.15])), e);
c += line(p, e, addArray2(f, [0.085, 0.085]));

c += line(p, addArray2(h, multiplyArray2(angle1, [0.06, 0.06])), f);
c += line(p, addArray2(h, multiplyArray2(tangle43, [-0.16, -0.16])), d);
c += line(p, addArray2(h, multiplyArray2(tangle42, [0.16, 0.16])), e);
// of course I'd write a line function that
// doesn't handle perfectly vertical lines
c += line(p, [0.001, -0.5], [0.0001, 0.5]);
c += circleFill(addArray2(p, [0.001, -0.5]), 0.005);
c += circleFill(addArray2(p, [0.001, 0.5]), 0.005);
c = _clamp(c, 0, 1);
colour = [white[0] * c, white[1] * c, white[2] * c];

this.color(colour[0], colour[1], colour[2], 1);
}, {
output: [400, 400],
graphical: true,
});
}
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more