Published
Edited
Sep 23, 2022
Importers
1 star
Also listed in…
Teaching Calculus
PlotX3D
Insert cell
Insert cell
show_x3d([
create_level_surface(
(x, y, z) => x ** 2 + y ** 2 + z ** 2 - 4,
[
[-2, 2],
[-2, 2],
[-2, 2]
]
)
])
Insert cell
Insert cell
show_x3d([
// A scarlet hyperboloid
create_level_surface(
(x, y, z) => x ** 2 - y ** 2 + z ** 2 - 1,
[
[-2, 2],
[-2, 2],
[-2, 2]
],
{ color: d3.color("red").darker(2) }
),
// A gray sphere
create_level_surface(
(x, y, z) => x ** 2 + y ** 2 + z ** 2 - 2,
[
[-1.5, 1.5],
[-1.5, 1.5],
[-1.5, 1.5]
],
{ color: "gray" }
)
])
Insert cell
Insert cell
show_x3d([
create_level_surface(
(x, y, z) => x ** 6 + y ** 6 + z ** 6 - 1,
[
[-1, 1],
[-1, 1],
[-1, 1]
],
{ show_surface_mesh: true }
)
])
Insert cell
Insert cell
// (x, y, z) => (x ** 4 - x ** 2 + y ** 2) ** 2 + z ** 2 - 1 / 25

show_x3d(
[
create_level_surface(
(x, y, z) => (x ** 4 - x ** 2 + y ** 2) ** 2 + z ** 2 - 1 / 25,
[
[-1.2, 1.2],
[-0.7, 0.7],
[-0.2, 0.2]
],
{ show_surface_mesh: true, Nx: 32, Ny: 16, Nz: 8 }
)
],
{
viewpoint: {
position: "2.411474665489146 1.379943295458121 2.0661348794365195",
orientation:
"0.2632114701336716 0.419218026686788 0.8688935309293689,2.272917153903575"
}
}
)
Insert cell
Insert cell
Insert cell
function create_level_surface(f, domain, opts = {}) {
let {
Nx = 30,
Ny = 30,
Nz = 30,
color = "#40bfbf",
transparency = 0,
show_surface_mesh = false
} = opts;

// The following use of surfaceNets was entirely inspired by Ricky Reusser's notebook:
// https://observablehq.com/@rreusser/mathematical-easter-egg-coloring
let resolution = [Nx, Ny, Nz];
let b = domain.map((b, i) => [b[0], (b[1] - b[0]) / (resolution[i] - 1)]);
let gridValues = ndarrayProxy(resolution, (i, j, k) =>
f(b[0][0] + i * b[0][1], b[1][0] + j * b[1][1], b[2][0] + k * b[2][1])
);
let mesh = surfaceNets(gridValues);
for (var i = 0; i < mesh.positions.length; i++) {
const p = mesh.positions[i];
p[0] = b[0][0] + b[0][1] * p[0];
p[1] = b[1][0] + b[1][1] * p[1];
p[2] = b[2][0] + b[2][1] * p[2];
}

let container = d3.create("transform");
if (opts.id) {
container.attr("id", opts.id);
}
if (opts.class) {
container.attr("class", opts.class);
}

mesh.cells.forEach((pt) => pt.push(pt[0]));

let face_index_string = mesh.cells.join(" -1 ").toString();
let coord_string = mesh.positions.toString();

let shape = container.append("shape");
let appearance = shape.append("appearance");
if (opts.sortKey || opts.sortKey === 0) {
appearance.attr("sortKey", opts.sortKey);
}
let material = appearance.append("material");
material.attr("diffuseColor", color);
if (opts.transparency) {
material.attr("transparency", opts.transparency);
}
let indexedFaceSet = shape
.append("indexedFaceset")
.attr("solid", false)
.attr("coordIndex", face_index_string)
.attr("creaseAngle", 3.14);
indexedFaceSet.append("coordinate").attr("point", coord_string);

if (show_surface_mesh) {
let surface_mesh = container.append("shape");
surface_mesh
.append("appearance")
.append("material")
.attr("transparency", 0.4);
surface_mesh
.append("IndexedLineSet")
.attr("coordIndex", face_index_string)
.append("Coordinate")
.attr("point", coord_string);
}

let xs = mesh.positions.map((pt) => pt[0]);
let xmin = d3.min(xs);
let xmax = d3.max(xs);
let ys = mesh.positions.map((pt) => pt[1]);
let ymin = d3.min(ys);
let ymax = d3.max(ys);
let zs = mesh.positions.map((pt) => pt[2]);
let zmin = d3.min(zs);
let zmax = d3.max(zs);

let node = container.node();
node.extent = { xmin, xmax, ymin, ymax, zmin, zmax };

return node;
}
Insert cell
Insert cell
surfaceNets = require("https://bundle.run/surface-nets@1.0.2")
Insert cell
ndarrayProxy = require("https://bundle.run/ndarray-proxy@1.0.0")
Insert cell
import { show_x3d, style } from "@mcmcclur/plotx3d"
Insert cell
import {
rotation_vector,
normalize,
path_list_to_indexString,
path_list_to_coordString
} from '@mcmcclur/x3dom-utilities'
Insert cell
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