{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "cd6024a5-fdf9-4f14-986a-f9b590b5fa2b", "metadata": {}, "outputs": [], "source": [ "# File: five-twist.ipynb\n", "# Code: Claude Code and Codex\n", "# Review: Ryoichi Ando (ryoichi.ando@zozo.com)\n", "# License: Apache v2.0" ] }, { "cell_type": "code", "execution_count": null, "id": "2eb84f3d-b318-4313-9004-d661aa55d39a", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from frontend import App\n", "\n", "# create an app\n", "app = App.create(\"five-twist\")\n", "\n", "# create a cylinder mesh with specified radius and length\n", "half_length = 2.6\n", "V, F = app.mesh.cylinder(r=0.55, min_x=-half_length, max_x=half_length, n=180)\n", "app.asset.add.tri(\"cylinder\", V, F)\n", "\n", "# create a scene\n", "scene = app.scene.create()\n", "objs = []\n", "\n", "# arrange 5 cylinders in a circular pattern\n", "n, r = 5, 1\n", "for i in range(5):\n", " t = 2 * i / n * np.pi\n", " x, y = r * np.cos(t), r * np.sin(t)\n", " objs.append(scene.add(\"cylinder\").at(0, x, y).jitter())\n", "\n", "# configure material properties and animations for each cylinder\n", "for obj in objs:\n", "\n", " # set bending stiffness, contact gap, Young's modulus, Poisson's ratio and density\n", " (\n", " obj.param.set(\"bend\", 500.0)\n", " .set(\"contact-gap\", 4e-3)\n", " .set(\"young-mod\", 1e4)\n", " .set(\"poiss-rat\", 0.25)\n", " .set(\"density\", 3.5)\n", " )\n", "\n", " # define animation parameters for twisting motion\n", " angular_vel, move_delta, scale, t_end, t_wait = 360, 1, 0.75, 25, 5\n", " x, y, z = obj.position\n", "\n", " # pin and animate left end - spin, scale and move\n", " left_pin = obj.pin(obj.grab([-1, 0, 0]))\n", " left_pin.spin(axis=[1, 0, 0], angular_velocity=angular_vel, t_end=t_wait).move_by(\n", " [move_delta, 0, 0], 0.0, t_end\n", " )\n", " left_pin.scale(scale, 0.0, t_wait, center=[-x-half_length, -y, -z])\n", "\n", " # pin and animate right end - spin in opposite direction, scale and move\n", " right_pin = obj.pin(obj.grab([1, 0, 0]))\n", " right_pin.spin(axis=[-1, 0, 0], angular_velocity=angular_vel, t_end=t_wait).move_by(\n", " [-move_delta, 0, 0], 0.0, t_end\n", " )\n", " right_pin.scale(scale, 0.0, t_wait, center=[-x+half_length, -y, -z])\n", "\n", " # add additional spinning motion\n", " angular_vel, t_end = 180, 15\n", "\n", " left_pin.spin(\n", " center=[-x, -y, -z],\n", " axis=[1, 0, 0],\n", " angular_velocity=angular_vel,\n", " t_start=t_wait,\n", " t_end=t_end,\n", " )\n", "\n", " right_pin.spin(\n", " center=[-x, -y, -z],\n", " axis=[-1, 0, 0],\n", " angular_velocity=angular_vel,\n", " t_start=t_wait,\n", " t_end=t_end,\n", " )\n", "\n", "# compile the scene and report stats\n", "scene = scene.build().report()\n", "\n", "# preview the initial scene\n", "scene.preview()" ] }, { "cell_type": "code", "execution_count": null, "id": "70ce60bb-552f-4d59-9116-1cdc805cbe5f", "metadata": {}, "outputs": [], "source": [ "# create a new session with the compiled scene\n", "session = app.session.create(scene)\n", "\n", "# set session parameters - timestep, frames, disable gravity\n", "(\n", " session.param.set(\"dt\", 1 / 60)\n", " .set(\"frames\", 480)\n", " .set(\"gravity\", [0, 0, 0])\n", " .set(\"friction-mode\", \"max\")\n", ")\n", "\n", "# build this session\n", "session = session.build()" ] }, { "cell_type": "code", "execution_count": null, "id": "ab76b71d-6c12-486b-9ff0-f8713f96f0a7", "metadata": {}, "outputs": [], "source": [ "# start the simulation and live-preview the results\n", "session.start().preview()\n", "\n", "# also show simulation logs in realtime\n", "session.stream()" ] }, { "cell_type": "code", "execution_count": null, "id": "6f295e70-36ec-4771-9458-f29adc6a1ded", "metadata": {}, "outputs": [], "source": [ "# create an animation from the simulation results\n", "session.animate()" ] }, { "cell_type": "code", "execution_count": null, "id": "6824e966-cc2d-4001-9c7f-1a56bc242284", "metadata": {}, "outputs": [], "source": [ "# export the animation to file\n", "session.export.animation()" ] }, { "cell_type": "code", "execution_count": null, "id": "2f830039-41b5-4cb7-9bc5-059542d53edc", "metadata": {}, "outputs": [], "source": [ "# this is for CI\n", "if app.ci:\n", " assert session.finished()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }