Published unlisted
Edited
Nov 20, 2019
Insert cell
Insert cell
mything = {
math;
x3dom;
d3;
const width = 800;
const height = 500;
let container = d3
.create('div')
.style('width', width.toString() + 'px')
.style('height', height.toString() + 'px');

let scene = container
.append('x3d')
.attr('width', width.toString() + 'px')
.attr('height', height.toString() + 'px')
.append('scene');
scene
.append("viewpoint")
.attr("centerOfRotation", "0 0 0")
.attr("position", "8.57023 3.32838 8.53848")
.attr("orientation", "-0.28794 0.94292 0.16732 0.83483");

// Allow rotation with no zoom
scene
.append("NavigationInfo")
.attr("type", "turntable")
.attr('speed', '0');

let yaxis_transform = scene.append('transform').attr('translation', '0 0 0').attr('DEF','axis');
let yaxis_shape = yaxis_transform.append('shape');
yaxis_shape
.append('appearance')
.append('material')
.attr('diffuseColor', '0 0 0') //'0.828 0.683 0.2148')
.attr('transparency', 0.2);
yaxis_shape
.append('cylinder')
.attr('radius', 0.01)
.attr('subdivision', '32')
.attr('height', '8');

let xaxis_transform = scene
.append('transform')
.attr('rotation', '0,0,1,1.570796')
.attr('translation', '-2,0,0')
.attr('scale', '1,2,1')
.append('transform').attr('USE','axis');
// let xaxis_shape = xaxis_transform.append('shape');
// xaxis_shape
// .append('appearance')
// .append('material')
// .attr('diffuseColor', '0 0 0') // '0.828 0.683 0.2148')
// .attr('transparency', 0.2);
// xaxis_shape
// .append('cylinder')
// .attr('radius', 0.02)
// .attr('subdivision', '32')
// .attr('height', '16');

let zaxis_transform = scene
.append('transform')
.attr('rotation', '1,0,0,1.570796')
.attr('scale','1,1.333,1')
.append('transform').attr('USE','axis');;
// let zaxis_shape = zaxis_transform.append('shape');
// zaxis_shape
// .append('appearance')
// .append('material')
// .attr('diffuseColor', '0 0 0') //'0.828 0.683 0.2148')
// .attr('transparency', 0.2);
// zaxis_shape
// .append('cylinder')
// .attr('radius', 0.01)
// .attr('subdivision', '32')
// .attr('height', '12');

const transparency = 1.05;
let bundle = scene.append('Group').attr('id', 'the_bundle');
for (let k = -8; k <= 8; k++) {
let col = d3.color(d3.interpolateViridis((k+8)/16)).rgb();
let bundle_shape = bundle.append('Shape');
bundle_shape
.attr('id', 'thread' + k.toString())
.append("appearance")
.append('material')
.attr('emissiveColor', [col.r, col.g, col.b].map( v => v / 255 ).join())
.attr('transparency', 1 - math.pow(transparency, -math.abs(4 * k)));
let bundle_lineset = bundle_shape.append('IndexedLineSet');
let coord_string = spindle_string(k);
bundle_lineset.attr(
"coordIndex",
d3.range(coord_string.match(/,/g).length)
);
bundle_lineset.append('Coordinate').attr('point', coord_string);
}

yield container.node();

x3dom.reload();
}
Insert cell
function x2x(x, k) {
if (math.abs(x) < 0.000001) {
return math.complex(1, 0);
} else {
var z = math.complex(x);
var twoPiI = math.complex(0, 1).mul(2 * math.pi);
return math.exp(z.mul(z.log().add(twoPiI.mul(k))));
}
}
Insert cell
function spindle_string(k) {
var result = '';
d3.range(-4, 2, 0.001).map(function(x) {
result = result + 2 * x.toString() + ' ';
var value = x2x(x, k);
var vre = value.re;
if (math.abs(vre) < 0.001) {
vre = 0.0;
}
var vim = value.im;
if (math.abs(vim) < 0.001) {
vim = 0.0;
}
result = result + vre.toString() + ' ' + vim.toString() + ', ';
});
result = result.slice(0, -2);
return result;
}
Insert cell
math = require('mathjs')
Insert cell
// x3dom is tricky. The require debugger suggests the following:
// https://observablehq.com/@tmcw/module-require-debugger
x3dom = require('x3dom').catch(() => window['x3dom'])
Insert cell
// d3 = require('d3@4')
Insert cell
d3 = require('d3')
Insert cell
html`<style>
canvas {
outline: none;
}
</style>`
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