/** * Throw a ball * by Kazuki Maeda * Last-Modified: Apr. 12, 2016 */ var WIDTH=1020, HEIGHT=520; var marginX=20, marginY=20; var w=WIDTH-marginX, h=HEIGHT-marginY; var interval = 20; var rootSVG; var ball; var trajectory; var tt, xt, yt; var thread; var t, x, y; var delta = 1.0/60; var v0=0, g=0, theta=0; var points; window.onload = function(){ init(); } function init(){ document.getElementById("throw").addEventListener("click", draw, true); document.getElementById("trajectory").addEventListener("click", switchtrajectory, true); document.getElementById("canvas").removeChild(document.getElementById("canvas").firstChild); rootSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg"); rootSVG.setAttribute("width", WIDTH); rootSVG.setAttribute("height", HEIGHT); document.getElementById("canvas").appendChild(rootSVG); // draw axes var xAxis = document.createElementNS("http://www.w3.org/2000/svg", "line"); xAxis.setAttribute("x1", ""+marginX); xAxis.setAttribute("y1", ""+h); xAxis.setAttribute("x2", ""+WIDTH); xAxis.setAttribute("y2", ""+h); xAxis.setAttribute("stroke", "#D3D7CF"); xAxis.setAttribute("stroke-width", "2"); rootSVG.appendChild(xAxis); var yAxis = document.createElementNS("http://www.w3.org/2000/svg", "line"); yAxis.setAttribute("x1", ""+marginX); yAxis.setAttribute("y1", ""+(h+interval)); yAxis.setAttribute("x2", ""+marginX); yAxis.setAttribute("y2", ""+0); yAxis.setAttribute("stroke", "#D3D7CF"); yAxis.setAttribute("stroke-width", "2"); rootSVG.appendChild(yAxis); var i = 0; for(var x = marginX; x <= WIDTH; x += interval){ var xTick = document.createElementNS("http://www.w3.org/2000/svg", "line"); xTick.setAttribute("x1", ""+x) xTick.setAttribute("x2", ""+x) xTick.setAttribute("y1", ""+h) xTick.setAttribute("y2", ""+(h-interval/5)) xTick.setAttribute("stroke", "#D3D7CF"); xTick.setAttribute("stroke-width", "1"); rootSVG.appendChild(xTick); if(!(i%5)){ xTick.setAttribute("y2", ""+(HEIGHT-marginY-interval/5*2)) var xLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); xLabel.setAttribute("x", ""+x-(8/72*96)); xLabel.setAttribute("y", ""+(HEIGHT-marginY+(8/72*96))); xLabel.setAttribute("font-size", "8pt"); xLabel.setAttribute("fill", "#D3D7CF"); xLabel.textContent = ""+i/5; rootSVG.appendChild(xLabel); } ++i; } i = 25; for(var y = 0; y <= h+interval; y += interval){ var yTick = document.createElementNS("http://www.w3.org/2000/svg", "line"); yTick.setAttribute("x1", ""+marginX) yTick.setAttribute("x2", ""+(marginX+interval/5)) yTick.setAttribute("y1", ""+y) yTick.setAttribute("y2", ""+y) yTick.setAttribute("stroke", "#D3D7CF"); yTick.setAttribute("stroke-width", "1"); rootSVG.appendChild(yTick); if(!(i%5) && i!=0){ yTick.setAttribute("x2", ""+(marginX+interval/5*2)); var yLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); yLabel.setAttribute("x", ""+(marginX-8/72*96)); yLabel.setAttribute("y", ""+(y+8/72*96)); yLabel.setAttribute("font-size", "8pt"); yLabel.setAttribute("fill", "#D3D7CF"); yLabel.textContent = ""+(i/5); rootSVG.appendChild(yLabel); } --i; } trajectory = document.createElementNS("http://www.w3.org/2000/svg", "polyline"); trajectory.setAttribute("stroke", "#7FFF00"); trajectory.setAttribute("stroke-width", "0"); trajectory.setAttribute("fill", "none"); rootSVG.appendChild(trajectory); tt = document.createElementNS("http://www.w3.org/2000/svg", "text"); tt.setAttribute("x", ""+(w-interval*5)); tt.setAttribute("y", ""+(interval*2)); tt.setAttribute("font-size", "16pt"); tt.setAttribute("font-family", "monospace"); tt.setAttribute("fill", "#D3D7CF"); rootSVG.appendChild(tt); xt = document.createElementNS("http://www.w3.org/2000/svg", "text"); xt.setAttribute("x", ""+(w-interval*5)); xt.setAttribute("y", ""+(interval*4)); xt.setAttribute("font-size", "16pt"); xt.setAttribute("font-family", "monospace"); xt.setAttribute("fill", "#D3D7CF"); rootSVG.appendChild(xt); yt = document.createElementNS("http://www.w3.org/2000/svg", "text"); yt.setAttribute("x", ""+(w-interval*5)); yt.setAttribute("y", ""+(interval*6)); yt.setAttribute("font-size", "16pt"); yt.setAttribute("font-family", "monospace"); yt.setAttribute("fill", "#D3D7CF"); rootSVG.appendChild(yt); ball = document.createElementNS("http://www.w3.org/2000/svg", "circle"); ball.setAttribute("fill", "#7FFF00"); ball.setAttribute("opacity", "0.8"); ball.setAttribute("cx", ""+marginX); ball.setAttribute("cy", ""+HEIGHT-marginY); ball.setAttribute("r", "10"); rootSVG.appendChild(ball); t = 0; points = ""; setBall(); } function draw(){ clearInterval(thread); switchtrajectory(); v0 = parseFloat(document.getElementById("v0").value); theta = parseFloat(document.getElementById("theta").value)/180*Math.PI; g = parseFloat(document.getElementById("g").value); t = 0; points = ""; setBall(); thread = setInterval("animate();", 1000*delta); } function animate(){ t += delta; if(t*v0*Math.sin(theta)-g*t*t/2 < 0){ clearInterval(thread); t = 2/g*v0*Math.sin(theta); } setBall(); } function setBall(){ x = t*v0*Math.cos(theta); y = t*v0*Math.sin(theta)-g*t*t/2; ball.setAttribute("cx", ""+(marginX+5*interval*x)); ball.setAttribute("cy", ""+(HEIGHT-marginY-5*interval*y)); tt.textContent = "t=" + t.toFixed(3); xt.textContent = "x=" + x.toFixed(3); yt.textContent = "y=" + y.toFixed(3); points += " " + (marginX+5*interval*x) + "," + (HEIGHT-marginY-5*interval*y); trajectory.setAttribute("points", points); } function switchtrajectory(){ if(document.getElementById("trajectory").checked) trajectory.setAttribute("stroke-width", "2"); else trajectory.setAttribute("stroke-width", "0"); }