Public
Edited
Dec 18, 2022
Importers
2 stars
Also listed in…
PlotX3D
Insert cell
Insert cell
function string_add(s1, s2) {
let v2 = s2.split(' ');
return s1.split(' ')
.map((v, i) => parseFloat(v) + parseFloat(v2[i]))
.join(' ');
}
Insert cell
function chop(x) {
return Math.abs(x) < 0.000001 ? 0 : x;
}
Insert cell
function cross([x1, y1, z1], [x2, y2, z2]) {
return [
y1 * z2 - z1 * y2,
z1 * x2 - x1 * z2,
x1 * y2 - y1 * x2
];
}
Insert cell
function dot([x1, y1, z1], [x2, y2, z2]) {
return x1 * x2 + y1 * y2 + z1 * z2;
}
Insert cell
function diff([x1, y1, z1], [x2, y2, z2]) {
return [x2 - x1, y2 - y1, z2 - z1];
}
Insert cell
function sum([x1, y1, z1], [x2, y2, z2]) {
return [x2 + x1, y2 + y1, z2 + z1];
}
Insert cell
function negate([x, y, z]) {
return [-x, -y, -z];
}
Insert cell
function norm([v0, v1, v2]) {
return Math.sqrt(v0 * v0 + v1 * v1 + v2 * v2);
}
Insert cell
function normalize(v) {
let [x, y, z] = v;
let n = norm(v);
return [x / n, y / n, z / n];
}
Insert cell
function scale(r, [x, y, z]) {
return [r * x, r * y, r * z];
}
Insert cell
function pt_toString([x, y, z]) {
return ` ${x} ${y} ${z}`;
}
Insert cell
function path_list_to_indexString(paths) {
let cnt = 0;
let individual_indices = paths.map(function(l) {
let result = d3.range(l.length).map(x => x + cnt);
cnt = cnt + l.length;
return result.toString();
});
return individual_indices
.map(s => s + ' -1')
.toString()
.replace(/,/g, ' ');
}
Insert cell
function pt_list_to_colorString(pt_list,f) {
return pt_list.map(pt_toString).toString();
}
Insert cell
function pt_list_to_coordString(pt_list) {
return pt_list.map(pt_toString).toString();
}
Insert cell
function path_list_to_coordString(paths) {
return paths.map(pt_list_to_coordString).toString();
}
Insert cell
// Rotate u1 so that it points in direction v1
function rotation_vector(u1, v1) {
let u = normalize(u1);
let v = normalize(v1);
let n = cross(u, v);
let t = Math.acos(dot(u, v));
return `${n[0]} ${n[1]} ${n[2]} ${t}`;
}
Insert cell
function normal_binormal(d) {
const [x, y, z] = d;
let n; // normal
if (x && y) n = normalize([-y, x, 0]);
else if (x && z) n = normalize([-z, 0, x]);
else if (y && z) n = normalize([0, -z, y]);
if(n !== undefined) {
return [n, normalize(cross(n, d))];
}
if (x) return [[0, 1, 0], [0, 0, 1]];
if (y) return [[1, 0, 0], [0, 0, 1]];
if (z) return [[1, 0, 0], [0, 1, 0]];
return [undefined, undefined];
}
Insert cell
function rotation_matrix(d, t) {
let c1, c2, c3;
let rotateX = (t) => [
[1, 0, 0],
[0, Math.cos(t), -Math.sin(t)],
[0, Math.sin(t), Math.cos(t)]
];
if (d[1] == 0 && d[2] == 0) {
return rotateX(t);
} else {
c1 = normalize(d);
c2 = normalize(cross(d, [1, 0, 0]));
c3 = cross(c1, c2);
let S = [
[c1[0], c2[0], c3[0]],
[c1[1], c2[1], c3[1]],
[c1[2], c2[2], c3[2]]
];
let result = math.multiply(S, rotateX(t), math.inv(S));
return result;
}
}
Insert cell
d3 = require('d3-array@2')
Insert cell
math = require("mathjs")
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