projectile-motion.html (10345B)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Projectile Motion Simulation</title> 6 <meta name="Description" content="Projectile motion physics simulation and calculator"> 7 <meta name="viewport" content="width=device-width"> 8 <link rel="manifest" href="../manifest.json"> 9 <link rel="icon" type="image/png" href="../images/favicon-32.png"> 10 <link rel="apple-touch-icon" href="../images/favicon-180.png"> 11 <script src="../vendor/vue.js"></script> 12 <script src="../vendor/svg-pan-zoom.js"></script> 13 <script src="../vendor/hammer.js"></script> 14 <link rel="stylesheet" href="styles.css"> 15 <script src="projectile-motion.js"></script> 16 <script id="MathJax-script" async src="../vendor/mathjax.js"></script> 17 </head> 18 <body onload="createApp()"> 19 <div id="app"> 20 <header> 21 <a title="Home" href="../" class="icon"><img alt="" src="../images/home.svg"></a> 22 <button v-show="!infoVisible" title="About" class="icon" @click="infoVisible=true"><img alt="" src="../images/info.svg"></button> 23 <button v-show="infoVisible" title="Close" class="icon" @click="infoVisible=false"><img alt="" src="../images/x.svg"></button> 24 <h1>Projectile Motion</h1> 25 </header> 26 27 <noscript> 28 <p>This simulation requires JavaScript</p> 29 </noscript> 30 31 <div id="simulation" v-show="!infoVisible"> 32 <div id="input" hidden> 33 <section> 34 <label for="heightInput"><b>Height:</b> {{ height.toFixed(1) }} m</label> 35 <input type="range" min="0" max="10" step="0.1" v-model.number="height" @input="reset" :disabled="active" @dblclick="height=1" id="heightInput"> 36 </section> 37 <section> 38 <label for="initialVelocityInput"><b>Velocity:</b> {{ initialVelocity.toFixed(1) }} m/s</label> 39 <input type="range" min="0" max="10" step="0.1" v-model.number="initialVelocity" @input="reset" :disabled="active" @dblclick="initialVelocity=5" id="initialVelocityInput"> 40 </section> 41 <section> 42 <label for="angleInput"><b>Angle:</b> {{ angle.toFixed(0) }}<sup>o</sup></label> 43 <input type="range" min="-90" max="90" step="1" v-model.number="angle" @input="reset" :disabled="active" @dblclick="angle=0" id="angleInput"> 44 </section> 45 <section> 46 <label for="gravityInput"><b>Gravity:</b> {{ gravity.toFixed(1) }} m/s<sup>2</sup></label> 47 <input type="range" min="0" max="10" step="0.1" v-model.number="gravity" @input="reset" :disabled="active" @dblclick="gravity=9.8" id="gravityInput"> 48 </section> 49 </div> 50 51 <div id="output" hidden> 52 <div id="simControls"> 53 <button @click="toggle" class="icon" :title="active ? 'Pause' : (time === 0 ? 'Start' : 'Resume')" :disabled="time !== 0 && position.y <= 0"> 54 <img alt="" :src="active ? '../images/pause.svg' : '../images/play.svg'"> 55 </button> 56 <button @click="update" class="icon" title="Step Forward" :disabled="(time !== 0 && position.y <= 0) || active"> 57 <img alt="" src="../images/step-forward.svg"> 58 </button> 59 <button @click="reset" class="icon" title="Reset" :disabled="time === 0"> 60 <img alt="" src="../images/reset.svg"> 61 </button> 62 </div> 63 <div id="zoomControls"> 64 <button @click="svg.zoomOut()" class="icon" title="Zoom Out"> 65 <img alt="" src="../images/zoom-out.svg"> 66 </button> 67 <button @click="svg.resetZoom();svg.resetPan()" class="icon" title="Reset Zoom"> 68 <img alt="" src="../images/home.svg"> 69 </button> 70 <button @click="svg.zoomIn()" class="icon" title="Zoom In"> 71 <img alt="" src="../images/zoom-in.svg"> 72 </button> 73 </div> 74 <svg width="400px" height="400px" viewBox="-1 -1 101 102"> 75 <!-- Ground --> 76 <line x1="-10000" y1="101" x2="10000" y2="101" stroke-width="1" stroke="#606060"></line> 77 78 <!-- Path --> 79 <circle v-for="position in positions" :cx="10*position.x" :cy="100 - 10*position.y" r="0.5" fill="#a0a0a0"></circle> 80 81 <!-- Launch vector --> 82 <line :x1="10*position.x" :y1="100 - 10*position.y" :x2="10*launchArrow[1].x" :y2="100 - 10*launchArrow[1].y" stroke-width="1" stroke="#a0a0a0"></line> 83 <path :d="`M${10*launchArrow[0].x} ${100 - 10*launchArrow[0].y} L${10*launchArrow[1].x} ${100 - 10*launchArrow[1].y} L${10*launchArrow[2].x} ${100 - 10*launchArrow[2].y} Z`" stroke="#a0a0a0" stroke-width="1" fill="#a0a0a0"/> 84 85 <!-- Projectile --> 86 <circle :cx="10*position.x" :cy="100 - 10*position.y" r="1" fill="#ff0000"></circle> 87 </svg> 88 </div> 89 90 <div id="data" hidden> 91 <label><b>Time:</b> {{ time.toFixed(2) }} s</label> 92 <label><b>Position:</b> {{ position.x.toFixed(2) }} m, {{ position.y > 0 ? position.y.toFixed(2) : 0.0.toFixed(2) }} m</label> 93 <label><b>Velocity:</b> {{ velocity.total.toFixed(2) }} m/s at {{ velocity.angle.toFixed(1) }}<sup>o</sup></label> 94 </div> 95 </div> 96 97 <div id="info" v-show="infoVisible" hidden> 98 <h2>Simulation Information</h2> 99 <p>This simulation consists of a projectile that can be launched.</p> 100 101 <p>You can control the simulation using these variables:</p> 102 <ul> 103 <li><b>Height:</b> The initial height of the projectile</li> 104 <li><b>Velocity:</b> The initial velocity of the projectile</li> 105 <li><b>Angle:</b> The angle to launch the projectile at</li> 106 <li><b>Gravity:</b> The acceleration due to gravity</li> 107 </ul> 108 109 <p>The simulation also contains these output measurements:</p> 110 <ul> 111 <li><b>Time:</b> The time that has passed</li> 112 <li><b>Position:</b> The current position of the projectile</li> 113 <li><b>Velocity:</b> The current velocity of the projectile</li> 114 </ul> 115 116 <p>Controls:</p> 117 <ul> 118 <li>Use the start <img alt="" src="../images/play.svg"> and stop <img alt="" src="../images/pause.svg"> buttons to start and stop the simulation</li> 119 <li>Use the step <img alt="" src="../images/step-forward.svg"> button to advance the simulation by 0.01 seconds</li> 120 <li>Use the reset <img alt="" src="../images/reset.svg"> button to restore the simulation to its initial state</li> 121 <li>Click and drag the simulation to pan</li> 122 <li>Use the zoom in <img alt="" src="../images/zoom-in.svg"> and zoom out <img alt="" src="../images/zoom-out.svg"> buttons or the mouse wheel to zoom in and out</li> 123 <li>Use the reset zoom <img alt="" src="../images/home.svg"> button to undo all zooming and panning</li> 124 </ul> 125 126 <p>Equations:</p> 127 <ul> 128 <li> 129 \( x = { t \cdot v_0 \cdot cos{ \theta } } \) 130 <ul> 131 <li>\(x\) is the horizontal position of the projectile</li> 132 <li>\(t\) is the time that has passed</li> 133 <li>\(v_0\) is the initial velocity of the projectile</li> 134 <li>\(\theta\) is the angle that the projectile was launched at</li> 135 </ul> 136 </li> 137 <li> 138 \( y = { y_0 + t \cdot v_0 \cdot sin{ \theta } - {1 \over 2} \cdot g \cdot t^2 } \) 139 <ul> 140 <li>\(y\) is the vertical position of the projectile</li> 141 <li>\(y_0\) is the initial height of the projectile</li> 142 <li>\(t\) is the time that has passed</li> 143 <li>\(v_0\) is the initial velocity of the projectile</li> 144 <li>\(\theta\) is the angle that the projectile was launched at</li> 145 <li>\(g\) is the acceleration due to gravity</li> 146 </ul> 147 </li> 148 <li> 149 \( v_x = { v_0 \cdot cos{ \theta } } \) 150 <ul> 151 <li>\(v_x\) is the horizontal velocity of the projectile</li> 152 <li>\(v_0\) is the initial velocity of the projectile</l> 153 <li>\(\theta\) is the angle that the projectile was launched at</li> 154 </ul> 155 </li> 156 <li> 157 \( v_y = { v_0 \cdot sin{ \theta } - g \cdot t } \) 158 <ul> 159 <li>\(v_y\) is the vertical velocity of the projectile</li> 160 <li>\(v_0\) is the initial velocity of the projectile</l> 161 <li>\(\theta\) is the angle that the projectile was launched at</li> 162 <li>\(g\) is the acceleration due to gravity</li> 163 <li>\(t\) is the time that has passed</li> 164 </ul> 165 </li> 166 </ul> 167 </div> 168 </div> 169 </body> 170 </html>