Mathematical Modeling of the Rubber Pencil Illusion
2016-04-20 03:21
This applet mathematically models the famous 'Rubber Pencil Illusion.' Using trigonometric functions, parametric equations, and transformations, it simulates the visual deformation of a rapidly shaken pencil. By adjusting sliders for amplitude, phase, and speed, users can observe how sinusoidal curves and trajectories interact, revealing the math behind this classic visual illusion.
In collections
My First Interactive Picture Book
<?xml version="1.0" encoding="utf-8"?>
<geogebra format="4.0" id="4b39bf72-5ff7-4c5d-9179-6b9528ed833e" xsi:noNamespaceSchemaLocation="http://www.geogebra.org/ggb.xsd" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<gui>
<window width="881" height="665" />
<perspectives>
<perspective id="tmp">
<panes>
<pane location="" divider="0.4301929625425653" orientation="1" />
</panes>
<views>
<view id="4" toolbar="0 || 2020 , 2021 , 2022 , 66 || 2001 , 2003 , 2002 , 2004 , 2005 || 2040 , 2041 , 2042 , 2044 , 2043" visible="false" inframe="false" stylebar="false" location="1,1" size="200" window="0,0,400,400" />
<view id="16" visible="false" inframe="false" stylebar="false" location="1,2" size="217" window="50,50,500,500" />
<view id="1" visible="true" inframe="false" stylebar="false" location="1" size="881" window="0,0,400,400" />
<view id="2" visible="false" inframe="false" stylebar="false" location="3" size="379" window="0,0,200,400" />
<view id="32" visible="false" inframe="true" stylebar="true" location="1" size="150" window="50,50,500,500" />
<view id="64" visible="false" inframe="true" stylebar="false" location="1" size="150" window="50,50,500,500" />
</views>
<toolbar show="false" items="0 39 59 || 1 501 67 , 5 19 , 72 | 2 15 45 , 18 65 , 7 37 | 4 3 8 9 , 13 44 , 58 , 47 || 16 51 64 , 70 | 10 34 53 11 , 24 20 22 , 21 23 | 55 56 57 , 12 || 36 46 , 38 49 50 , 71 | 30 29 54 32 31 33 | 17 26 62 , 14 66 68 | 25 52 60 61 || 40 41 42 , 27 28 35 , 6" />
<input show="true" cmd="true" top="false" />
</perspective>
</perspectives>
<labelingStyle val="3"/>
<font size="16"/>
<graphicsSettings javaLatexFonts="false"/>
<consProtColumns col0="true" col1="true" col2="false" col3="true" col4="false" col5="true" col6="true" col7="false"/>
<consProtocol useColors="true" addIcons="false" showOnlyBreakpoints="false"/>
</gui>
<euclidianView>
<size width="881" height="580"/>
<coordSystem xZero="233.44391002186248" yZero="348.74833128215755" scale="48.075104796354694" yscale="48.0751047963548"/>
<evSettings axes="true" grid="false" gridIsBold="false" pointCapturing="3" rightAngleStyle="1" checkboxSize="13" gridType="0"/>
<bgColor r="255" g="255" b="255"/>
<axesColor r="0" g="0" b="0"/>
<gridColor r="192" g="192" b="192"/>
<lineStyle axes="1" grid="10"/>
<axis id="0" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
<axis id="1" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true" tickDistance="1.0"/>
</euclidianView>
<kernel>
<continuous val="false"/>
<decimals val="4"/>
<angleUnit val="degree"/>
<algebraStyle val="0"/>
<coordStyle val="0"/>
<angleFromInvTrig val="false"/>
<startAnimation val="true"/>
</kernel>
<scripting blocked="false" disabled="false"/>
<construction title="" author="" date="">
<element type="numeric" label="Doffset_y">
<value val="3.25"/>
<show object="false" label="false"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
<layer val="0"/>
<labelMode val="1"/>
<animation step="1" speed="1" type="0" playing="false"/>
</element>
<element type="numeric" label="amp_{hand}">
<value val="1.0"/>
<show object="true" label="true"/>
<condition showObject="TFequations"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
<layer val="0"/>
<labelMode val="1"/>
<slider min="0.5" max="2" absoluteScreenLocation="true" width="100.0" x="26.0" y="36.0" fixed="false" horizontal="true"/>
<lineStyle thickness="2" type="0" typeHidden="1"/>
<animation step="0.1" speed="1" type="0" playing="false"/>
</element>
<element type="numeric" label="θ">
<value val="0.5890486225480862"/>
<show object="true" label="true"/>
<condition showObject="TFequations"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
<layer val="0"/>
<labelMode val="1"/>
<slider min="0" max="2 * π / b" absoluteScreenLocation="true" width="100.0" x="25.0" y="131.0" fixed="false" horizontal="true"/>
<lineStyle thickness="2" type="0" typeHidden="1"/>
<animation step="π / (24 * b)" speed="speed * b" type="1" playing="true"/>
</element>
<element type="numeric" label="b">
<value val="2.0"/>
<show object="true" label="true"/>
<condition showObject="TFequations"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
<layer val="0"/>
<labelMode val="1"/>
<slider min="0.1" max="5" absoluteScreenLocation="true" width="100.0" x="25.0" y="169.0" fixed="false" horizontal="true"/>
<lineStyle thickness="2" type="0" typeHidden="1"/>
<animation step="0.1" speed="1" type="0" playing="false"/>
</element>
<expression label="handmotion" exp="amp_{hand} * cos(b * θ)" />
<element type="numeric" label="handmotion">
<value val="0.38268343236508984"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
</element>
<element type="image" label="pic1">
<file name="b09f3c99cb67afef9dad2406efe35ece/rubberpencil_hand.gif"/>
<inBackground val="false"/>
<startPoint number="0" exp="A"/>
<startPoint number="1" exp="B"/>
<show object="true" label="false"/>
<objColor r="0" g="0" b="0" alpha="1.0"/>
<layer val="1"/>
<labelMode val="0"/>
<animation step="1" speed="1" type="0" playing="false"/>
</element>
<expression label="A" exp="(0, -Doffset_y + handmotion)" type="point" />
<element type="point" label="A">
<show object="false" label="true"/>
<objColor r="64" g="64" b="64" alpha="0.0"/>
<layer val="0"/>
<labelMode val="0"/>
<coords x="0.0" y="-2.8673165676349104" z="1.0"/>
<pointSize val="3"/>
<pointStyle val="0"/>
</element>
<expression label="B" exp="A + (5.5, 0)" type="point" />
<element type="point" label="B">
<show object="false" label="true"/>
<objColor r="64" g="64" b="64" alpha="0.0"/>
<layer val="0"/>
<labelMode val="0"/>
<coords x="5.5" y="-2.8673165676349104" z="1.0"/>
<pointSize val="3"/>
<pointStyle val="0"/>
</element>
<element type="numeric" label="speed">
<value val="1.59154943"/>
<show object="true" label="true"/>
<objColor r="0" g="153" b="51" alpha="0.1"/>
<layer val="0"/>
<labelMode val="3"/>
<tooltipMode val="3"/>
<slider min="0" max="1.59154943" absoluteScreenLocation="true" width="30.0" x="735.0" y="42.0" fixed="false" horizontal="true"/>
<lineStyle thickness="13" type="0" typeHidden="1"/>
<animation step="1.5915494309189535" speed="1" type="0" playing="false"/>
<caption val="start/stop"/>
</element>
<element type="numeric" label="pencillength">
<value val="7.5"/>
<show object="false" label="false"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
<layer val="0"/>
<labelMode val="1"/>
<animation step="1" speed="1" type="0" playing="false"/>
</element>
<element type="numeric" label="pencilgrip">
<value val="1.25"/>
<show object="false" label="false"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
<layer val="0"/>
<labelMode val="1"/>
<animation step="1" speed="1" type="0" playing="false"/>
</element>
<element type="numeric" label="Doffset_x">
<value val="5.1"/>
<show object="false" label="false"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
<layer val="0"/>
<labelMode val="1"/>
<animation step="1" speed="1" type="0" playing="false"/>
</element>
<expression label="H" exp="A + (Doffset_x, Doffset_y)" type="point" />
<element type="point" label="H">
<show object="true" label="true"/>
<objColor r="0" g="0" b="255" alpha="0.0"/>
<layer val="2"/>
<labelMode val="0"/>
<coords x="5.1" y="0.3826834323650896" z="1.0"/>
<pointSize val="3"/>
<pointStyle val="0"/>
</element>
<element type="numeric" label="amp_{scale}">
<value val="0.4"/>
<show object="true" label="true"/>
<condition showObject="TFequations"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
<layer val="0"/>
<labelMode val="1"/>
<slider min="0" max="1" absoluteScreenLocation="true" width="100.0" x="25.0" y="85.0" fixed="false" horizontal="true"/>
<lineStyle thickness="2" type="0" typeHidden="1"/>
<animation step="0.1" speed="1" type="0" playing="false"/>
</element>
<element type="numeric" label="phaseshift">
<value val="0.39269908169872414"/>
<show object="true" label="true"/>
<condition showObject="TFequations"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
<layer val="0"/>
<labelOffset x="-17" y="2"/>
<labelMode val="1"/>
<slider min="0" max="6.283185307179586" absoluteScreenLocation="true" width="100.0" x="24.0" y="217.0" fixed="false" horizontal="true"/>
<lineStyle thickness="2" type="0" typeHidden="1"/>
<animation step="0.1308996938995747" speed="1" type="0" playing="false"/>
</element>
<expression label="pencilcenter_y" exp="amp_{scale} * amp_{hand} * cos(b * (θ - phaseshift))" />
<element type="numeric" label="pencilcenter_y">
<value val="0.36955181300451473"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
</element>
<expression label="pencilctrhorizon" exp="y = pencilcenter_y" type="line" />
<element type="line" label="pencilctrhorizon">
<show object="false" label="false"/>
<objColor r="0" g="0" b="0" alpha="0.0"/>
<layer val="0"/>
<labelMode val="0"/>
<coords x="0.0" y="1.0" z="-0.36955181300451473"/>
<lineStyle thickness="2" type="0" typeHidden="1"/>
<eqnStyle style="explicit"/>
</element>
<command name="Circle">
<input a0="H" a1="pencillength / 2 - pencilgrip"/>
<output a0="d"/>
</command>
<element type="conic" label="d">
<show object="false" label="false"/>
<objColor r="0" g="0" b="0" alpha="0.0"/>
<layer val="0"/>
<labelMode val="0"/>
<lineStyle thickness="2" type="0" typeHidden="1"/>
<eigenvectors x0="1.0" y0="0.0" z0="1.0" x1="-0.0" y1="1.0" z1="1.0"/>
<matrix A0="1.0" A1="1.0" A2="19.906446609406725" A3="0.0" A4="-5.1" A5="-0.3826834323650896"/>
<eqnStyle style="specific"/>
</element>
<command name="Intersect">
<input a0="d" a1="pencilctrhorizon" a2="2"/>
<output a0="P"/>
</command>
<element type="point" label="P">
<show object="true" label="true"/>
<objColor r="255" g="0" b="0" alpha="0.0"/>
<layer val="2"/>
<labelMode val="0"/>
<coords x="7.599965511876707" y="0.36955181300451473" z="1.0"/>
<pointSize val="3"/>
<pointStyle val="0"/>
</element>
<element type="image" label="pic2">
<file name="455de932fd32c6177eb5f306e555ba69/rubberpencil_pencil.gif"/>
<inBackground val="false"/>
<startPoint number="0" exp="pencilcorner1"/>
<startPoint number="1" exp="pencilcorner2"/>
<startPoint number="2" exp="pencilcorner4"/>
<show object="true" label="false"/>
<objColor r="0" g="0" b="0" alpha="1.0"/>
<layer val="0"/>
<labelMode val="0"/>
<animation step="1" speed="1" type="0" playing="false"/>
</element>
<element type="numeric" label="pencilaspectratio">
<value val="24.0"/>
<show object="false" label="false"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
<layer val="0"/>
<labelMode val="1"/>
<animation step="1" speed="1" type="0" playing="false"/>
</element>
<expression label="α" exp="atan(y(P - H) / x(P - H))" />
<element type="numeric" label="α">
<value val="-0.005252671898224974"/>
<objColor r="0" g="0" b="0" alpha="0.1"/>
</element>
<expression label="F" exp="pencillength / (pencillength - 2 * pencilgrip) * (H - P) + P" type="point" />
<element type="point" label="F">
<show object="false" label="true"/>
<objColor r="64" g="64" b="64" alpha="0.0"/>
<layer val="0"/>
<labelMode val="0"/>
<coords x="3.850017244061646" y="0.38924924204537703" z="1.0"/>
<pointSize val="3"/>
<pointStyle val="0"/>
</element>
<command name="Mirror">
<input a0="F" a1="P"/>
<output a0="F'"/>
</command>
<element type="point" label="F'">
<show object="false" label="true"/>
<objColor r="64" g="64" b="64" alpha="0.0"/>
<layer val="0"/>
<labelMode val="0"/>
<coords x="11.349913779691768" y="0.3498543839636524" z="1.0"/>
<pointSize val="3"/>
<pointStyle val="0"/>
</element>
<command name="Segment">
<input a0="F" a1="F'"/>
<output a0="e"/>
</command>
<element type="segment" label="e">
<show object="true" label="false"/>
<condition showObject="TFtrace"/>
<objColor r="0" g="0" b="0" alpha="0.0"/>
<layer val="0"/>
<labelMode val="0"/>
<trace val="true"/>
<coords x="0.039394858081724604" y="7.499896535630122" z="-3.0709999248547746"/>
<lineStyle thickness="2" type="0" typeHidden="1"/>
<eqnStyle style="implicit"/>
<outlyingIntersections val="false"/>
<keepTypeOnTransform val="true"/>
</element>
<expression label="pencilcorner1" exp="F + pencillength / (2 * pencilaspectratio) * (sin(α), -cos(α))" type="point" />
<element type="point" label="pencilcorner1">
<show object="false" label="true"/>
<objColor r="0" g="0" b="255" alpha="0.0"/>
<layer val="0"/>
<labelMode val="0"/>
<coords x="3.8491965178516097" y="0.2330013975530828" z="1.0"/>
<pointSize val="3"/>
<pointStyle val="0"/>
</element>
<expression label="pencilcorner2" exp="pencilcorner1 + F' - F" type="point" />
<element type="point" label="pencilcorner2">
<show object="false" label="true"/>
<objColor r="0" g="0" b="255" alpha="0.0"/>
<layer val="0"/>
<labelMode val="0"/>
<coords x="11.349093053481731" y="0.1936065394713582" z="1.0"/>
<pointSize val="3"/>
<pointStyle val="0"/>
</element>
<expression label="pencilcorner4" exp="2 * F - pencilcorner1" type="point" />
<element type="point" label="pencilcorner4">
<show object="false" label="true"/>
<objColor r="0" g="0" b="255" alpha="0.0"/>
<layer val="0"/>
<labelMode val="0"/>
<coords x="3.850837970271682" y="0.5454970865376713" z="1.0"/>
<pointSize val="3"/>
<pointStyle val="0"/>
</element>
<element type="boolean" label="TFtrace">
<value val="true"/>
<show object="true" label="true"/>
<objColor r="0" g="0" b="0" alpha="0.0"/>
<layer val="0"/>
<labelOffset x="708" y="77"/>
<labelMode val="0"/>
<caption val="trace pencil"/>
</element>
<element type="image" label="pic_{pixel}">
<file name="5bec6606b8392065f9da9898ca6f7b14/pixel.gif"/>
<inBackground val="true"/>
<startPoint number="0" exp="(TFtrace * amp_{hand} * amp_{scale} * b * phaseshift, 0)"/>
<show object="true" label="false"/>
<objColor r="0" g="0" b="0" alpha="1.0"/>
<layer val="0"/>
<labelMode val="0"/>
<animation step="1" speed="1" type="0" playing="false"/>
<caption val="for ensuring trace gets cleared when in off position"/>
</element>
<expression label="f" exp="f(x) = amp_{hand} * cos(b * (x + θ - Doffset_x))" />
<element type="function" label="f">
<show object="true" label="false"/>
<condition showObject="TFsinusoids"/>
<objColor r="0" g="0" b="255" alpha="0.0"/>
<layer val="2"/>
<labelMode val="0"/>
<lineStyle thickness="2" type="0" typeHidden="1"/>
</element>
<expression label="g" exp="g(x) = amp_{scale} * amp_{hand} * cos(b * (x + θ - x(P) - phaseshift))" />
<element type="function" label="g">
<show object="true" label="false"/>
<condition showObject="TFsinusoids"/>
<objColor r="255" g="0" b="0" alpha="0.0"/>
<layer val="2"/>
<labelMode val="0"/>
<lineStyle thickness="2" type="0" typeHidden="1"/>
</element>
<element type="boolean" label="TFsinusoids">
<value val="true"/>
<show object="true" label="true"/>
<objColor r="0" g="0" b="0" alpha="0.0"/>
<layer val="0"/>
<labelOffset x="709" y="103"/>
<labelMode val="0"/>
<caption val="show sinusoids"/>
</element>
<expression label="text_h" exp=""y_{hand}=" * LaTeX[handmotion, false]" />
<element type="text" label="text_h">
<show object="true" label="false"/>
<condition showObject="TFequations"/>
<objColor r="0" g="0" b="255" alpha="0.0"/>
<bgColor r="255" g="255" b="255" alpha="255"/>
<layer val="0"/>
<labelMode val="0"/>
<isLaTeX val="true"/>
<font serif="false" size="0" style="0"/>
<absoluteScreenLocation x="291" y="21"/>
</element>
<expression label="text_p" exp=""y_{pencil}=" * LaTeX[pencilcenter_y, false]" />
<element type="text" label="text_p">
<show object="true" label="false"/>
<condition showObject="TFequations"/>
<objColor r="255" g="0" b="0" alpha="0.0"/>
<bgColor r="255" g="255" b="255" alpha="255"/>
<layer val="0"/>
<labelMode val="0"/>
<isLaTeX val="true"/>
<font serif="false" size="0" style="0"/>
<absoluteScreenLocation x="287" y="64"/>
</element>
<element type="boolean" label="TFequations">
<value val="true"/>
<show object="true" label="true"/>
<objColor r="0" g="0" b="0" alpha="0.0"/>
<layer val="0"/>
<labelOffset x="709" y="132"/>
<labelMode val="0"/>
<caption val="show equations"/>
</element>
<expression label="text1" exp=""JeromeA.White""/>
<element type="text" label="text1">
<show object="true" label="false"/>
<objColor r="192" g="192" b="192" alpha="0.0"/>
<layer val="2"/>
<labelMode val="0"/>
<fixed val="true"/>
<startPoint exp="Corner[1, 1] + 0.02 * (Corner[1, 3] - Corner[1, 1])"/>
</element>
</construction>
</geogebra>