var theCanvas = document.getElementById("theCanvas");
var theContext = theCanvas.getContext("2d");
var theImage = document.getElementById("frog");
var ay = 9.81; //gravity constant in SI units
var dt = 0.2; //time step in seconds
var timer, vel, yo, xo, a, angle, vx, vy, x, y, colDiam;
var t = 0; //initial time
var velSlider = document.getElementById("velSlider"); //intial speed in meters per second
var collagenSlider = document.getElementById("collagenSlider");
var velReadout = document.getElementById("velReadout"); //intial speed in meters per second
var collagenReadout = document.getElementById("collagenReadout");
function launchProjectile() {
if (timer) {
window.clearTimeout(timer);
timer=null;
}
t = 0;
vel = Number(velSlider.value);
colDiam = Number(collagenSlider.value);
yo = 479; //pixels from top to start
xo = 6; //pixels from left to start
vx = vel * Math.cos(angle);
vy = vel * Math.sin(angle);
angle = 10*Math.PI/180; // 45 degrees converted to radians
x = xo; //position at t=0
y = yo; //position at t=0
moveProjectile();
}
function drawProjectile() {
theContext.clearRect(0, 0, theCanvas.width, theCanvas.height);
theContext.drawImage(theImage,x,y,100,100);
}
function moveProjectile() {
if (y<480) {
t =+ dt;
x = (x + vx * t) + colDiam * .0109;
y = y - vy * t + .5*ay*(t*t);
range = (x - xo) * 0.00086805544619423;
document.getElementById("rangeprint").innerHTML = range;
drawProjectile();
if (timer) window.clearTimeout(timer);
timer = window.setTimeout(moveProjectile, 100*dt);
}
}
function showVel() {
velReadout.innerHTML = velSlider.value;
}
function showCollagen() {
collagenReadout.innerHTML = collagenSlider.value;
}
<div style="width:1000px; float:left; margin-left:auto; margin-right:auto;">
<img src="https://static.wikia.nocookie.net/uncharted/images/2/26/Amazon_rainforest_1.png/revision/latest?cb=20200519083419" width="1224" height="572" style="position:absolute;">
<canvas id="theCanvas" width="1224" height="572" style="position:relative;">
Canvas not supported; please update your browser.
</canvas>
<div style="text-align:center">
<input type="button" value="Launch!" onclick="launchProjectile();">
</div>
<p>
<input type="range" id="velSlider" min="0" max="30" step="10" value="10" oninput="showVel();" onchange="showVel();">
Initial velocity = <span id="velReadout">10</span> m/s
<p>
<input type="range" id="collagenSlider" min="50" max="500" step="50" value="100" oninput="showCollagen();" onchange="showCollagen();">
Collagen diameter = <span id="collagenReadout">100</span> nanometers
<p>
<p style="text-align:center" id="rangeprint">Range:</p>
</div>
<img id="frog" src="https://static.scientificamerican.com/sciam/cache/file/41DF7DA0-EE58-4259-AA815A390FB37C55_source.jpg" width="100" height="100" style="position:relative;">
The code above seems to work perfectly when the velocity is set to 0. However, if the velocity is anything above 0, the projectile seems to move infinitely, way past the expected, and if left high enough all the way into 1000+ feet. Something is wrong here but I'm not sure how to fix it. PS: You have to double-click the Launch button because of HTML shenanigans.
You wrote:
t =+ dt
Which just assigns dt
to t
. I think you meant:
t += dt
Which adds dt
to t
.
You also need to initialize angle
before calculating vx
and vy
, that will fix your double click bug.
var theCanvas = document.getElementById("theCanvas");
var theContext = theCanvas.getContext("2d");
var theImage = document.getElementById("frog");
var ay = 9.81; //gravity constant in SI units
var dt = 0.2; //time step in seconds
var timer, vel, yo, xo, a, angle, vx, vy, x, y, colDiam;
var t = 0; //initial time
var velSlider = document.getElementById("velSlider"); //intial speed in meters per second
var collagenSlider = document.getElementById("collagenSlider");
var velReadout = document.getElementById("velReadout"); //intial speed in meters per second
var collagenReadout = document.getElementById("collagenReadout");
function launchProjectile() {
if (timer) {
window.clearTimeout(timer);
timer=null;
}
t = 0;
vel = Number(velSlider.value);
colDiam = Number(collagenSlider.value);
yo = 479; //pixels from top to start
xo = 6; //pixels from left to start
angle = 10*Math.PI/180; // 45 degrees converted to radians
vx = vel * Math.cos(angle);
vy = vel * Math.sin(angle);
x = xo; //position at t=0
y = yo; //position at t=0
moveProjectile();
}
function drawProjectile() {
theContext.clearRect(0, 0, theCanvas.width, theCanvas.height);
theContext.drawImage(theImage,x,y,100,100);
}
function moveProjectile() {
if (y<480) {
t += dt;
x = (x + vx * t) + colDiam * .0109;
y = y - vy * t + .5*ay*(t*t);
range = (x - xo) * 0.00086805544619423;
document.getElementById("rangeprint").innerHTML = range;
drawProjectile();
if (timer) window.clearTimeout(timer);
timer = window.setTimeout(moveProjectile, 100*dt);
}
}
function showVel() {
velReadout.innerHTML = velSlider.value;
}
function showCollagen() {
collagenReadout.innerHTML = collagenSlider.value;
}
<div style="width:1000px; float:left; margin-left:auto; margin-right:auto;">
<img src="https://static.wikia.nocookie.net/uncharted/images/2/26/Amazon_rainforest_1.png/revision/latest?cb=20200519083419" width="1224" height="572" style="position:absolute;">
<canvas id="theCanvas" width="1224" height="572" style="position:relative;">
Canvas not supported; please update your browser.
</canvas>
<div style="text-align:center">
<input type="button" value="Launch!" onclick="launchProjectile();">
</div>
<p>
<input type="range" id="velSlider" min="0" max="30" step="10" value="10" oninput="showVel();" onchange="showVel();">
Initial velocity = <span id="velReadout">10</span> m/s
<p>
<input type="range" id="collagenSlider" min="50" max="500" step="50" value="100" oninput="showCollagen();" onchange="showCollagen();">
Collagen diameter = <span id="collagenReadout">100</span> nanometers
<p>
<p style="text-align:center" id="rangeprint">Range:</p>
</div>
<img id="frog" src="https://static.scientificamerican.com/sciam/cache/file/41DF7DA0-EE58-4259-AA815A390FB37C55_source.jpg" width="100" height="100" style="position:relative;">