178 lines
4 KiB
Python
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()
|