Public
Edited
Apr 17, 2023
1 fork
Importers
10 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
show_x3d([
create_surface((x, y) => [x, y, (x ** 2 + y ** 2) / 4], [-3, 3], [-3, 3])
])
Insert cell
Insert cell
show_x3d([
create_surface(
(r, t) => [r * Math.cos(t), r * Math.sin(t), r ** 2 / 4],
[0, 3],
[0, 2 * Math.PI]
)
])
Insert cell
Insert cell
show_x3d(
[
create_surface(
(phi, theta) => [
8 * Math.sin(phi) * Math.cos(theta),
5 * Math.sin(phi) * Math.sin(theta),
3 * Math.cos(phi)
],
[0, Math.PI],
[0, 2 * Math.PI]
)
],
{
show_axes: false,
viewpoint: {
position: '14 11 7',
orientation: '0.25 0.5 0.8,2.4'
}
}
)
Insert cell
Insert cell
Insert cell
function create_surface(p, [a, b], [c, d], opts = {}) {
let {
Nu = 100,
nu = 10,
Nv = 100,
nv = 10,
color = "#40bfbf",
transparency = 0,
show_mesh = true
} = opts;
let surface_strings = make_surface_strings(p, [a, b], [c, d], opts);
let surface_transform = d3.create("transform");
if (opts.id) {
surface_transform.attr("id", `${opts.id}`);
}
if (opts.class) {
surface_transform.attr("class", `${opts.class}`);
}
let surface_shape = surface_transform.append("shape");
let appearance = surface_shape.append("appearance");
if (opts.sortKey || opts.sortKey === 0) {
appearance.attr("sortKey", opts.sortKey);
}
let material = appearance
.append("material")
.attr("diffuseColor", color)
.attr("transparency", transparency);
let indexedFaceSet = surface_shape
.append("indexedFaceset")
.attr("coordIndex", surface_strings.face_index_string)
.attr("solid", "false")
.attr("creaseAngle", "3.14156");
indexedFaceSet
.append("coordinate")
.attr("point", surface_strings.coord_string);

if (show_mesh) {
let mesh = surface_transform.append("shape");
mesh
.append("appearance")
.append("material")
.attr("transparency", transparency);
mesh
.append("IndexedLineSet")
.attr("coordIndex", surface_strings.line_index_string)
.append("Coordinate")
.attr("point", surface_strings.coord_string);
}

let surface_node = surface_transform.node();
surface_node.extent = surface_strings.extent;

return surface_node;
}
Insert cell
function make_surface_strings(p, [a, b], [c, d], opts = {}) {
let { Nu = 100, nu = 10, Nv = 100, nv = 10 } = opts;

let Du = (b - a) / Nu;
let Dv = (d - c) / Nv;
let u_cut = Math.floor(Nu / nu);
let v_cut = Math.floor(Nv / nv);

let grid = [];
let k = 0;
let quads = [];
let lines = [];
for (let i = 0; i <= Nu; i++) {
for (let j = 0; j <= Nv; j++) {
let u = a + i * Du;
let v = c + j * Dv;
grid.push(p(u, v));
if (i < Nu && j < Nv) {
quads.push([k, k + 1, k + Nv + 2, k + Nv + 1]);
}
if (j % v_cut == 0 && i < Nu) {
lines.push([k, k + Nv + 1]);
}
if (i % u_cut == 0 && j < Nv) {
lines.push([k, k + 1]);
}
k++;
}
}
let coord_string = pt_list_to_coordString(grid);
let face_index_string = quads.map(a => a.toString() + ',-1').toString();
let line_index_string = lines.map(a => a.toString() + ',-1').toString();

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

return {
coord_string: coord_string,
face_index_string: face_index_string,
line_index_string: line_index_string,
extent: {
xmin: xmin,
xmax: xmax,
ymin: ymin,
ymax: ymax,
zmin: zmin,
zmax: zmax
}
};
}
Insert cell
function make_coord_string(p, [a, b], [c, d], opts = {}) {
let { Nu = 100, nu = 10, Nv = 100, nv = 10 } = opts;

let Du = (b - a) / Nu;
let Dv = (d - c) / Nv;
let grid = [];
let quads = [];
let lines = [];
for (let i = 0; i <= Nu; i++) {
for (let j = 0; j <= Nv; j++) {
let u = a + i * Du;
let v = c + j * Dv;
grid.push(p(u, v));
}
}
let coord_string = pt_list_to_coordString(grid);
return coord_string;
}
Insert cell
Insert cell
import { pt_list_to_coordString } from '@mcmcclur/x3dom-utilities'
Insert cell
import {
show_x3d,
create_sphere,
create_arrow
} from "@mcmcclur/x3dom-primitives"
Insert cell
d3 = require('d3-selection@2', 'd3-array@2')
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