chadbook/cube.py

178 lines
4 KiB
Python

# pyright: reportUnusedExpression=false
# marimo displays the expression before `return` as cell output
import marimo
__generated_with = "0.18.4"
app = marimo.App()
@app.cell
def _():
import marimo as mo
import anywidget
import traitlets
return anywidget, mo, traitlets
@app.cell
def _():
return
@app.cell
def _():
vertices = [
(-1, -1, -1),
( 1, -1, -1),
( 1, 1, -1),
(-1, 1, -1),
(-1, -1, 1),
( 1, -1, 1),
( 1, 1, 1),
(-1, 1, 1),
]
edges = [
(0, 1), (1, 2), (2, 3), (3, 0),
(4, 5), (5, 6), (6, 7), (7, 4),
(0, 4), (1, 5), (2, 6), (3, 7),
]
print(f"{len(vertices)} vertices, {len(edges)} edges")
return
@app.cell
def _():
def project(x, y, z):
return (x / z, y / z)
x, y, z = 2, 1, 4
x_proj, y_proj = project(x, y, z)
print(f"3d point: ({x}, {y}, {z})")
print(f"2d projection: ({x_proj}, {y_proj})")
print("\nfarther away = smaller on screen")
return
@app.cell
def _(anywidget, mo, traitlets):
class StaticCubeWidget(anywidget.AnyWidget):
_esm = """
function render({ model, el }) {
const canvas = document.createElement('canvas');
canvas.width = 300;
canvas.height = 300;
canvas.style.background = '#111';
el.appendChild(canvas);
const ctx = canvas.getContext('2d');
const w = canvas.width, h = canvas.height;
const vertices = [
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
[-1,-1, 1], [1,-1, 1], [1,1, 1], [-1,1, 1]
];
const edges = [
[0,1],[1,2],[2,3],[3,0],
[4,5],[5,6],[6,7],[7,4],
[0,4],[1,5],[2,6],[3,7]
];
function project(x, y, z) {
z += 4;
return [x/z * 100 + w/2, y/z * 100 + h/2];
}
ctx.strokeStyle = '#0f0';
ctx.lineWidth = 2;
for (const [i, j] of edges) {
const [x1, y1] = project(...vertices[i]);
const [x2, y2] = project(...vertices[j]);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
}
export default { render };
"""
_css = ""
value = traitlets.Int(0).tag(sync=True)
static_cube = mo.ui.anywidget(StaticCubeWidget())
static_cube
return
@app.cell
def _(anywidget, mo, traitlets):
class SpinningCubeWidget(anywidget.AnyWidget):
_esm = """
function render({ model, el }) {
const canvas = document.createElement('canvas');
canvas.width = 300;
canvas.height = 300;
canvas.style.background = '#111';
el.appendChild(canvas);
const ctx = canvas.getContext('2d');
const w = canvas.width, h = canvas.height;
const vertices = [
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
[-1,-1, 1], [1,-1, 1], [1,1, 1], [-1,1, 1]
];
const edges = [
[0,1],[1,2],[2,3],[3,0],
[4,5],[5,6],[6,7],[7,4],
[0,4],[1,5],[2,6],[3,7]
];
function rotateY(x, y, z, a) {
const c = Math.cos(a), s = Math.sin(a);
return [x*c - z*s, y, x*s + z*c];
}
function project(x, y, z) {
z += 4;
return [x/z * 100 + w/2, y/z * 100 + h/2];
}
let angle = 0;
function draw() {
ctx.fillStyle = '#111';
ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = '#0f0';
ctx.lineWidth = 2;
for (const [i, j] of edges) {
const a = rotateY(...vertices[i], angle);
const b = rotateY(...vertices[j], angle);
const [x1, y1] = project(...a);
const [x2, y2] = project(...b);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
angle += 0.02;
requestAnimationFrame(draw);
}
draw();
}
export default { render };
"""
_css = ""
value = traitlets.Int(0).tag(sync=True)
spinning_cube = mo.ui.anywidget(SpinningCubeWidget())
spinning_cube
return
if __name__ == "__main__":
app.run()