Published
Edited
Mar 23, 2021
1 fork
Importers
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md`Z-order curve for comparison`
Insert cell
Insert cell
Insert cell
Insert cell
z_position = glsl`
vec2 zposition(float a, inout mat2 rot) {
// for a quadrant in 0., 1., 2., 3.
// return the position of the quadrant (in xy)

// And flip the rotation matrix for the children of this point.

vec2 p;

if (a < 0.5) {
p = vec2(-.5, .5);
}
else if (a < 1.5) {
p = vec2(.5, .5);
}
else if (a <= 2.5) {
p = vec2(-.5, -.5);
} else {
p = vec2(.5, -.5);
}
// Flip all points below here.
return p;

}
`

Insert cell
Insert cell
Hilbert_Curve = glsl`

${rotation_logic.value}
${hilbert_position.value}


vec2 Hilbert_Curve(in float ix) {
// Start at the origin with an identity transform;
vec2 xy = vec2(0.5, 0.5);
mat2 rotation = mat2(
1., 0.,
0., 1.
);
float MAX_ITER = 14.;
for (float i = 14.; i > -.5; i -= 1.) {
float rank_in_layer = floor((ix + .05) / (pow(4., i)));
float a = modI(rank_in_layer, 4.);
vec2 p = position(a, rotation);
xy += p * pow(2., i - 1.);
}
return xy + vec2(pow(2., 13.), pow(2., 13.));
}
`
Insert cell
Insert cell
vertex_shader = glsl`
precision highp float;

attribute float ix;

uniform float u_time;
uniform float u_boust;
uniform float u_max_ix;
uniform float tick;
uniform sampler2D u_color_buffer;
uniform float u_separation;
uniform float u_base;
varying vec4 fill;

vec2 positioner(vec2 fracts) {
return 1.5 * vec2(fracts.x - .5, fracts.y - .5) - vec2(.23, .23);
}
float modI(float a,float b) {
float m=a-floor((a+0.5)/b)*b;
return floor(m+0.5);
}
${Hilbert_Curve.value}

void main() {

vec2 p_null = vec2(0., 0.);
gl_PointSize = 2.;
float scale = 1.;
scale = 1. / sqrt(u_max_ix) * 1.8;
vec2 pos = (Hilbert_Curve(ix) - p_null) * scale + vec2(-.99, -.99);
gl_Position = vec4(pos.x, -pos.y, 0., 1.);

float prop_through = ix / u_max_ix;
float offset = -fract(u_time / 5.);
fill = texture2D(u_color_buffer, vec2(fract(offset + ix/u_max_ix), 0.5));
}
`
Insert cell
mutable n_points_visible = 0
Insert cell
{
const numbers = []
const fives = 0;
const threes = 0;
const sevens = 0;
for (let i of d3.range(10)) {
const i_ = 3 ** i
for (let j of d3.range(8)) {
const j_ = 5 ** j
for (let k of d3.range(6)) {
const k_ = 7 ** k
numbers.push([i_ * j_ * k_, [i, j, k]])
}
}
}
numbers.sort((a, b) => a[0] - b[0])
return numbers
}
Insert cell
draw_tick = {
const tick = regl.frame(({time}) => {
// clear contents of the drawing buffer
regl.clear({
color: [0, 0, 0, 0],
depth: 1
})
mutable n_points_visible = Math.round(z.points)
drawPoints({points: z.points, rounded_points: Math.round(z.points), primitive: z.primitive})
// draw a triangle using the command defined above
})
invalidation.then(() => tick.cancel())
}
Insert cell
2 ** 2
Insert cell
2 + 1 * 7
Insert cell
p = {
while (true) {
if (animate.length) {
z.points = 2 ** ((2 + Math.sin(now/10000)) * 7) / 2
} else {
z.points = (Math.pow(2, n_points))
}
z.primitive = primitive
yield z.points
}
}

Insert cell
fragment_shader = glsl`
precision mediump float;
varying vec4 fill;

void main() {
gl_FragColor = fill;
}
`
Insert cell
z = ({
rounded_points: 16,
primitive: "line"
})
Insert cell
z
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
drawPoints = {
const regl_params = {
depth: { enable: false },
stencil: { enable: false },
blend: {
enable: true,
func: {
srcRGB: 'one',
srcAlpha: 'one',
dstRGB: 'one minus src alpha',
dstAlpha: 'one minus src alpha',
},
},
frag: fragment_shader.value,
vert: vertex_shader.value,
attributes: {
ix: {
buffer: points,
stride: 4,
offset: 0
},
},
uniforms: {
tick: ({ tick }) => tick,
u_max_ix: regl.prop("points"),
u_boust: curve_type == "Hilbert" ? 1 : 0,
u_time: regl.context("time"),
u_aspect_ratio: 1,
u_color_buffer: colorscheme,
u_separation: 0,
u_base: 2,
},
// specify the number of points to draw
count: regl.prop("rounded_points"),

// specify that each vertex is a point (not part of a mesh)
primitive: regl.prop("primitive")
}

return regl(regl_params)
}
Insert cell
md`# Create a colorscheme`
Insert cell
load_time = Date.now()
Insert cell
points = regl.buffer(vals)
Insert cell
vals = {
return d3.range(0, 2 ** 24)
}
Insert cell
colorscheme = regl.texture(canvas)
Insert cell
wrapREGL = require('regl')
Insert cell
import { glsl } from "@stwind/glsl-chunk-tag";
Insert cell
d3 = require("d3@v6")
Insert cell
import {Button, Checkbox, Toggle, Radio, Range, Select, Text, Textarea, Search, Table} from "@observablehq/inputs"

Insert cell
import { set } from "@observablehq/synchronized-inputs"
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