# 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()