Published
Edited
Jun 3, 2021
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Reset to the initial position
{
reset;
let arrow = d3.select(klein_pic).selectAll(".arrow");
let rot = rotation_vector([0, 1, 0], N(Math.PI / 2, 0));
arrow.attr("rotation", rot).attr("translation", p(Math.PI / 2, 0));
}
Insert cell
// A parameterization of the Klein bottle
p = (u, v) => [
(-2 *
Math.cos(u) *
(3 * Math.cos(v) -
30 * Math.sin(u) +
90 * Math.pow(Math.cos(u), 4) * Math.sin(u) -
60 * Math.pow(Math.cos(u), 6) * Math.sin(u) +
5 * Math.cos(u) * Math.cos(v) * Math.sin(u))) /
15.,
(-1 / 15) *
(Math.sin(u) *
(3 * Math.cos(v) -
3 * Math.pow(Math.cos(u), 2) * Math.cos(v) -
48 * Math.pow(Math.cos(u), 4) * Math.cos(v) +
48 * Math.pow(Math.cos(u), 6) * Math.cos(v) -
60 * Math.sin(u) +
5 * Math.cos(u) * Math.cos(v) * Math.sin(u) -
5 * Math.pow(Math.cos(u), 3) * Math.cos(v) * Math.sin(u) -
80 * Math.pow(Math.cos(u), 5) * Math.cos(v) * Math.sin(u) +
80 * Math.pow(Math.cos(u), 7) * Math.cos(v) * Math.sin(u))),
(2 * (3 + 5 * Math.cos(u) * Math.sin(u)) * Math.sin(v)) / 15.
]
Insert cell
// The vector perpendicular to the Klein bottle at p(u,v)
N = (u, v) => [
-(
(5 * Math.cos(u) - 5 * Math.cos(3 * u) + 12 * Math.sin(u)) *
(80 +
120 * Math.cos(2 * u) +
110 * Math.cos(4 * u) -
200 * Math.cos(6 * u) -
110 * Math.cos(8 * u) +
60 * Math.cos(2 * u - 2 * v) +
35 * Math.cos(4 * u - 2 * v) -
60 * Math.cos(6 * u - 2 * v) -
35 * Math.cos(8 * u - 2 * v) +
1920 * Math.cos(u - v) +
1920 * Math.cos(u + v) +
60 * Math.cos(2 * (u + v)) +
35 * Math.cos(4 * u + 2 * v) -
60 * Math.cos(6 * u + 2 * v) -
35 * Math.cos(8 * u + 2 * v) +
288 * Math.sin(4 * u) +
168 * Math.sin(6 * u) +
144 * Math.sin(4 * u - 2 * v) +
84 * Math.sin(6 * u - 2 * v) +
144 * Math.sin(4 * u + 2 * v) +
84 * Math.sin(6 * u + 2 * v))
) / 14400,
-(
(6 + 5 * Math.sin(2 * u)) *
(15 * Math.cos(u) +
25 * Math.cos(3 * u) -
Math.sin(u) *
(12 +
12 * Math.cos(2 * v) +
5 * Math.sin(2 * u - 2 * v) +
120 * Math.sin(3 * u - v) -
30 * Math.sin(5 * u - v) -
30 * Math.sin(7 * u - v) +
5 * Math.sin(2 * (u + v)) +
120 * Math.sin(3 * u + v) -
30 * Math.sin(5 * u + v) -
30 * Math.sin(7 * u + v)))
) / 900,
(1 / 14400) *
((5 * Math.cos(u) - 5 * Math.cos(3 * u) + 12 * Math.sin(u)) *
(96 * Math.cos(3 * u - 2 * v) +
108 * Math.cos(5 * u - 2 * v) +
36 * Math.cos(7 * u - 2 * v) -
96 * Math.cos(3 * u + 2 * v) -
108 * Math.cos(5 * u + 2 * v) -
36 * Math.cos(7 * u + 2 * v) -
40 * Math.sin(u - 2 * v) -
45 * Math.sin(3 * u - 2 * v) +
25 * Math.sin(5 * u - 2 * v) +
45 * Math.sin(7 * u - 2 * v) +
15 * Math.sin(9 * u - 2 * v) -
870 * Math.sin(2 * u - v) +
120 * Math.sin(4 * u - v) +
240 * Math.sin(6 * u - v) -
120 * Math.sin(8 * u - v) -
105 * Math.sin(10 * u - v) +
30 * Math.sin(12 * u - v) +
15 * Math.sin(14 * u - v) +
2460 * Math.sin(v) +
870 * Math.sin(2 * u + v) -
120 * Math.sin(4 * u + v) -
240 * Math.sin(6 * u + v) +
120 * Math.sin(8 * u + v) +
105 * Math.sin(10 * u + v) -
30 * Math.sin(12 * u + v) -
15 * Math.sin(14 * u + v) +
40 * Math.sin(u + 2 * v) +
45 * Math.sin(3 * u + 2 * v) -
25 * Math.sin(5 * u + 2 * v) -
45 * Math.sin(7 * u + 2 * v) -
15 * Math.sin(9 * u + 2 * v)))
]
Insert cell
html`
<style>
canvas {
outline: none;
}
</style>
`
Insert cell
Insert cell
import {
show_x3d,
create_sphere,
create_arrow
} from "@mcmcclur/x3dom-primitives"
Insert cell
import { rotation_vector } from "@mcmcclur/x3dom-utilities"
Insert cell
import { create_surface } from "@mcmcclur/parametric-surfaces"
Insert cell
import { xySlider } from '@mootari/2d-slider'
Insert cell
import { Button } from '@observablehq/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