{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Wheel on Inclined Plane" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib widget" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from ipywidgets import FloatSlider, AppLayout, Label, HBox" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import numpy" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import time" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from IPython.display import display, clear_output" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from pysketcher import *" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "g = 9.81" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def inclined_plane():\n", " theta = 30.\n", " L = 10.\n", " a = 1.\n", " xmin = 0\n", " ymin = -3\n", "\n", " drawing_tool.set_coordinate_system(xmin=xmin, xmax=xmin+1.5*L,\n", " ymin=ymin, ymax=ymin+L+1,\n", " #axis=True,\n", " instruction_file='tmp_mpl.py'\n", " )\n", " #drawing_tool.set_grid(True)\n", " fontsize = 18\n", " from math import tan, radians\n", "\n", " B = point(a+L, 0)\n", " A = point(a, tan(radians(theta))*L)\n", "\n", " wall = Wall(x=[A[0], B[0]], y=[A[1], B[1]], thickness=-0.25,\n", " transparent=False)\n", "\n", " angle = Arc_wText(r'$\\theta$', center=B, radius=3,\n", " start_angle=180-theta, arc_angle=theta,\n", " fontsize=fontsize)\n", " angle.set_linecolor('black')\n", " angle.set_linewidth(1)\n", "\n", " ground = Line((B[0]-L/10., 0), (B[0]-L/2.,0))\n", " ground.set_linecolor('black')\n", " ground.set_linestyle('dashed')\n", " ground.set_linewidth(1)\n", "\n", " r = 1 # radius of wheel\n", " help_line = Line(A, B)\n", " x = a + 3*L/10.; y = help_line(x=x)\n", " contact = point(x, y)\n", " normal_vec = point(sin(radians(theta)), cos(radians(theta)))\n", " tangent_vec = point(cos(radians(theta)), -sin(radians(theta)))\n", " c = contact + r*normal_vec\n", " outer_wheel = Circle(c, r)\n", " outer_wheel.set_linecolor('blue')\n", " outer_wheel.set_filled_curves('blue')\n", " hole = Circle(c, r/2.)\n", " hole.set_linecolor('blue')\n", " hole.set_filled_curves('white')\n", "\n", " wheel = Composition({'outer': outer_wheel, 'inner': hole})\n", " wheel.set_shadow(4)\n", "\n", " drawing_tool.set_linecolor('black')\n", " N = Force(contact - 2*r*normal_vec, contact, r'$N$', text_pos='start')\n", " mg = Gravity(c, 3*r, text='$Mg$')\n", "\n", " x_const = Line(contact, contact + point(0,4))\n", " x_const.set_linestyle('dotted')\n", " x_const.rotate(-theta, contact)\n", " # or x_const = Line(contact-2*r*normal_vec, contact+4*r*normal_vec).set_linestyle('dotted')\n", " x_axis = Axis(start=contact+ 3*r*normal_vec, length=4*r,\n", " label='$x$', rotation_angle=-theta)\n", "\n", " body = Composition({'wheel': wheel, 'N': N, 'mg': mg})\n", " fixed = Composition({'angle': angle, 'inclined wall': wall,\n", " 'ground': ground,\n", " 'x start': x_const, 'x axis': x_axis})\n", "\n", " fig = Composition({'body': body, 'fixed elements': fixed})\n", " fig.draw()\n", " return (fig,normal_vec,tangent_vec,c)\n", "\n", "def position(t):\n", " \"\"\"Position of center point of wheel.\"\"\"\n", " global tangent_vec,c\n", " return c + 0.5*g*t**2*tangent_vec\n", "\n", "t = 0\n", "\n", "def speed(displacement,dt):\n", " if dt != 0: \n", " v = (displacement)/dt\n", " #print(v)\n", " v = numpy.sqrt(v[0]**2 + v[1]**2)\n", " else:\n", " v = 0\n", " return v\n", " \n", "def move(change):\n", " global fig,t,label,x,x0,dt\n", " dt = change.new - t \n", " t = change.new\n", " drawing_tool.erase()\n", " x = position(t)\n", " x0 = position(t-dt)\n", " displacement = x - x0 \n", " fig['body'].translate(displacement)\n", " fig.draw()\n", " label.value = f\"v={speed(displacement,dt):.2f}\"\n", " #drawing_tool.display()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "slider = FloatSlider(\n", " orientation='horizontal',\n", " description='Time:',\n", " value=0.0,\n", " min=0.0,\n", " max=1.0,\n", " step = 1.0 / 30\n", ")\n", "slider.observe(move, 'value')" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "label = Label(value=\"0\")" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d62ee3eb721b4dfb8e5ed6cb5f0b506b", "version_major": 2, "version_minor": 0 }, "text/plain": [ "AppLayout(children=(HBox(children=(FloatSlider(value=0.0, description='Time:', max=1.0, step=0.033333333333333…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig,normal_vec,tangent_vec,c = inclined_plane()\n", "AppLayout(\n", " center=drawing_tool.mpl.gcf().canvas,\n", " footer=HBox([slider,label]),\n", " pane_heights=[0, 6, 1]\n", ")\n", "#drawing_tool.mpl.ion()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "drawing_tool.mpl.ion()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for t in numpy.linspace(0.0,1.0,100):\n", " slider.value = t\n", " print(t)\n", " clear_output(wait=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "drawing_tool.mpl.ioff()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }