Last active
September 11, 2017 02:59
-
-
Save lilgreenland/56811b37617a584bab5dc48189dbb174 to your computer and use it in GitHub Desktop.
2-D ballistics calculator (vue.js)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
https://vuejs.org/ | |
https://github.com/NightCatSama/vue-slider-component | |
https://nightcatsama.github.io/vue-slider-component/example/#demo3 | |
https://vuejs.org/v2/guide/components.html | |
--> | |
<div id="values"> | |
<table> | |
<tr> | |
<td colspan="2"> | |
<div> | |
<vue-slider v-model="t" v-on:input="calcT" event-type="auto" width="auto" :height="6" :dot-size="20" :min="-5" :max="30" :interval="0.1"></vue-slider> | |
</div> | |
<div class='center'>Δt = <input v-on:input="calcT" v-model.number="t" type="number"> s</div> | |
</td> | |
</tr> | |
<!-- <tr> | |
<td> | |
horizontal | |
</td> | |
<td> | |
vertical | |
</td> | |
</tr> --> | |
<tr> | |
<td> | |
<!-- Δx = <input v-on:input="calcX" v-model.number="x" type="number"> m --> | |
↔ Δx = {{x}} m | |
</td> | |
<td> | |
<!-- Δy = <input v-on:input="calc" v-model.number="y" type="number"> m --> | |
↕ Δy = {{y}} m | |
</td> | |
</tr> | |
<tr> | |
<td class = 'cyan'> | |
↔ u = <input v-on:input="calcX" v-model.number="ux" type="number"> m/s | |
</td> | |
<td class = 'pink'> | |
↕ u = <input v-on:input="calc" v-model.number="uy" type="number"> m/s | |
</td> | |
</tr> | |
<tr> | |
<td class = 'cyan'>↔ v = {{vx}} m/s</td> | |
<td class = 'pink'>↕ v = {{vy}} m/s</td> | |
</tr> | |
<tr> | |
<td > | |
↔ a = <input v-on:input="calcX" v-model.number="ax" type="number"> m/s² | |
</td> | |
<td> | |
↕ a = <input v-on:input="calc" v-model.number="ay" type="number"> m/s² | |
</td> | |
</tr> | |
</table> | |
</div> | |
<svg id='plot' class='graph' width="600" height="400" xmlns="http://www.w3.org/2000/svg"> | |
<!-- acceleration vectors --> | |
<text text-anchor="middle" alignment-baseline="middle" x="550" y="40" font-size='20px' fill ='#bbb'>a</text> | |
<polygon id = 'a' transform='translate(200 100) rotate(0)' points="2,0 -6,4 -6,-4" fill = "#bbb" /> | |
<line id = 'a_line' x1="550" y1="50" x2="0" y2="0" stroke = "#bbb" stroke-width ="2"/> | |
<!-- initial velocity vectors--> | |
<line id = 'v_ux' x1="50" y1="200" x2="0" y2="200" stroke = "rgba(150,220,220,0.8)" stroke-width ="5"/> | |
<line id = 'v_uy' x1="50" y1="200" x2="50" y2="0" stroke = "rgba(250,150,150,0.7)" stroke-width ="5"/> | |
<!-- final velocity vectors--> | |
<line id = 'v_vx' x1="0" y1="0" x2="0" y2="0" stroke = "rgba(150,220,220,0.8)" stroke-width ="5"/> | |
<line id = 'v_vy' x1="0" y1="0" x2="0" y2="0" stroke = "rgba(250,150,150,0.7)" stroke-width ="5"/> | |
<!-- trajectory --> | |
<path id ='b-path-full' d="" stroke="#888" stroke-width="1" fill = 'none' stroke-linejoin="round" stroke-linecap="round"/> | |
<path id ='b-path' d="" stroke="#000" stroke-width="2" fill = 'none' stroke-linejoin="round" stroke-linecap="round"/> | |
<circle id ='b_path_start' cx="50" cy="200" r="5" fill ='#000' OPACITY = '0.6'/> | |
<circle id ='b_path_end' cx="100" cy="100" r="5" fill ='#000' OPACITY = '0.6'/> | |
<!-- v-bind:style="{cx: cxEnd}" --> | |
<!-- axis --> | |
<path d="M0 200 h600 M50 0 v1000" stroke="#888" stroke-width="1" fill = 'none' stroke-dasharray="5, 5"/> | |
</svg> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let round = function(input) { | |
return Math.round(input * 100) / 100; | |
}; | |
Vue.component( | |
"vueSlider", | |
{ | |
// options | |
} | |
); | |
var ballistic1 = new Vue({ | |
el: "#values", | |
components: { | |
vueSlider: window["vue-slider-component"] | |
}, | |
data: { | |
t: 0, | |
x: 0, | |
ux: 30, | |
vx: 0, | |
ax: 0, | |
y: 0, | |
uy: 30, | |
vy: 0, | |
ay: -9.8, | |
value: 10 | |
}, | |
methods: { | |
calc: function() { | |
// if (this.ay > 0) this.ay = 0; | |
this.vy = round(-Math.sqrt(this.uy * this.uy + 2 * this.ay * this.y)); | |
this.t = round((this.vy - this.uy) / this.ay); | |
this.x = round(this.t * this.ux + this.ax * this.t * this.t / 2); | |
this.vx = round(this.ux + this.ax * this.t); | |
this.drawSVG(); | |
}, | |
calcX: function() { | |
this.vx = round(Math.sqrt(this.ux * this.ux + 2 * this.ax * this.x)); | |
this.t = round(2 * this.x / (this.vx + this.ux)); | |
this.y = round(this.t * this.uy + this.ay * this.t * this.t / 2); | |
this.vy = round(-Math.sqrt(this.uy * this.uy + 2 * this.ay * this.y)); | |
// document.getElementById("plot").style.visibility = hidden | |
this.drawSVG(); | |
}, | |
calcT: function() { | |
//x side | |
this.x = round(this.ux * this.t + 0.5 * this.ax * this.t * this.t); | |
this.vx = round(this.ux + this.ax * this.t); | |
//y side | |
this.y = round(this.uy * this.t + 0.5 * this.ay * this.t * this.t); | |
this.vy = round(this.uy + this.ay * this.t); | |
this.drawSVG(); | |
}, | |
drawSVG: function() { | |
const xOff = 50; | |
const yOff = 200; | |
const SCALE = 2; | |
//set path of projectile | |
let d = " M" + (xOff + this.ux * -100 + 0.5 * this.ax * -100 * -100) * SCALE + " " + (yOff - (this.uy * -100 + 0.5 * this.ay * -100 * -100)) * SCALE; | |
for (let t = -100, len = 1000; t < len; t += 0.2) { | |
d += " L" + (xOff + (this.ux * t + 0.5 * this.ax * t * t) * SCALE) + " " + (yOff - (this.uy * t + 0.5 * this.ay * t * t) * SCALE); | |
} | |
document.getElementById("b-path-full").setAttribute("d", d); | |
//partial path | |
d = " M" + xOff + " " + yOff; | |
for (let t = 0, len = this.t; t < len; t += 0.01) { | |
d += " L" + (xOff + (this.ux * t + 0.5 * this.ax * t * t) * SCALE) + " " + (yOff - (this.uy * t + 0.5 * this.ay * t * t) * SCALE); | |
} | |
document.getElementById("b-path").setAttribute("d", d); | |
//move circle to end of trajectory | |
if (!isNaN(this.x) && !isNaN(this.y)) { | |
document.getElementById("b_path_end").style.display = "inline"; | |
document.getElementById("b_path_end").setAttribute("cx", xOff + this.x * SCALE); | |
document.getElementById("b_path_end").setAttribute("cy", yOff - this.y * SCALE); | |
} else { | |
document.getElementById("b_path_end").style.display = "none"; | |
} | |
//change initial velocity vectors | |
document.getElementById("v_ux").setAttribute("x2", xOff + this.ux * 2); | |
document.getElementById("v_uy").setAttribute("y2", yOff - this.uy * 2); | |
//change final velocity vectors | |
document.getElementById("v_vx").setAttribute("x1", xOff + this.x * SCALE); | |
document.getElementById("v_vx").setAttribute("y1", yOff - this.y * SCALE); | |
document.getElementById("v_vx").setAttribute("y2", yOff - this.y * SCALE); | |
document.getElementById("v_vx").setAttribute("x2", xOff + this.x * SCALE + this.vx * 2); | |
document.getElementById("v_vy").setAttribute("x1", xOff + this.x * SCALE); | |
document.getElementById("v_vy").setAttribute("y1", yOff - this.y * SCALE); | |
document.getElementById("v_vy").setAttribute("x2", xOff + this.x * SCALE); | |
document.getElementById("v_vy").setAttribute("y2", yOff - this.y * SCALE - this.vy * 2); | |
//change acceleration vectors | |
const Vx = 550 + this.ax * 4; | |
const Vy = 50 - this.ay * 4; | |
document | |
.getElementById("a") | |
.setAttribute( | |
"transform", | |
`translate(${Vx} ${Vy}) rotate(${Math.atan2(-this.ay, this.ax) * | |
180 / | |
Math.PI} )` | |
); | |
document.getElementById("a_line").setAttribute("x2", Vx); | |
document.getElementById("a_line").setAttribute("y2", Vy); | |
//hide arrow if vector is small | |
if (this.ax * this.ax + this.ay * this.ay < 1) { | |
document.getElementById("a").style.display = "none"; | |
} else { | |
document.getElementById("a").style.display = "inline"; | |
} | |
} | |
} | |
}); | |
ballistic1.calc(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://unpkg.com/vue/dist/vue.min.js"></script> | |
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/464612/vueslider.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
font-family: "Arial", sans-serif; | |
margin: 0 auto; | |
max-width: 600px; | |
font-size: 150%; | |
} | |
input { | |
font-size: 100%; | |
width: 80px; | |
background: #eee; | |
border: 10px; | |
margin: 0.2em; | |
} | |
input:focus { | |
outline: 0; | |
} | |
.graph { | |
margin 0; | |
padding 0; | |
border: 1px solid #ccc; | |
} | |
.center { | |
text-align: center; | |
padding: 0; | |
margin: auto; | |
display: block; | |
} | |
table { | |
margin: 25px 0px -1px 0px; | |
padding 0; | |
border-collapse: collapse; | |
border: 1px solid #ccc; | |
/*border-bottom: 2px solid #222;*/ | |
width: 602px; | |
} | |
table th, table td { | |
color: #555; | |
border: 1px solid #ccc; | |
padding: 12px 20px; | |
border-collapse: collapse; | |
} | |
table th { | |
background: #444; | |
color: #fff; | |
text-transform: uppercase; | |
font-size: 0.85em; | |
} | |
table th.last { | |
border-right: none; | |
} | |
.pink { | |
background-color: #fffbff; | |
/* border-left: 2px solid rgba(250,150,150,0.7); */ | |
border-right: 2px solid #fbb; | |
border-bottom: 2px solid #fbb; | |
border-top: 2px solid #fbb; | |
} | |
.cyan { | |
background-color: #fbffff; | |
border-left: 2px solid #bdd; | |
/* border-right: 2px solid rgba(150,220,220,0.8); */ | |
border-bottom: 2px solid #bdd; | |
border-top: 2px solid #bdd; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment