circular-motion.js (5410B)
1 const App = { 2 data: function() { 3 return { 4 mass: 5, // The object's mass (Kg) 5 force: 5, // The centripetal force on the object (N) 6 radius: 1, // The radius of the circle (m) 7 time: 0, // The time (s) 8 active: false, // Whether the simulation is active 9 refreshRate: 0.01, // The simulation refresh rate (s) 10 intervalId: null, // The value returned by setInterval 11 infoVisible: false, 12 } 13 }, 14 computed: { 15 /** 16 * The speed of the object 17 */ 18 speed: function() { 19 return Math.sqrt((this.force * this.radius) / this.mass); 20 }, 21 22 /** 23 * The circumference of the circle 24 */ 25 circumference: function() { 26 return 2 * Math.PI * this.radius; 27 }, 28 29 /** 30 * The time it takes the object to complete 1 rotation 31 */ 32 period: function() { 33 return this.circumference / this.speed; 34 }, 35 36 /** 37 * The angle of the object as a percentage (0 - 1) 38 */ 39 angle: function() { 40 return ((this.time * this.speed) / this.circumference) % 1; 41 }, 42 43 /** 44 * The coordinates of the object 45 */ 46 position: function() { 47 let x = this.getX(this.angle, this.radius); 48 let y = this.getY(this.angle, this.radius); 49 return [x, y]; 50 }, 51 52 /** 53 * The coordinates of the velocity vector 54 */ 55 velocityVector: function() { 56 let x = this.getX(this.angle + 0.25, (0.25 * this.speed * this.radius) + 0.1); 57 let y = this.getY(this.angle + 0.25, (0.25 * this.speed * this.radius) + 0.1); 58 let arrow1x = x - this.getX(this.angle + 0.35, 0.02); 59 let arrow1y = y - this.getY(this.angle + 0.35, 0.02); 60 let arrow2x = x - this.getX(this.angle + 0.15, 0.02); 61 let arrow2y = y - this.getY(this.angle + 0.15, 0.02); 62 return [ 63 x + this.position[0], y + this.position[1], // Center point 64 arrow1x + this.position[0], arrow1y + this.position[1], // Arrow line #1 65 arrow2x + this.position[0], arrow2y + this.position[1], // Arrow line #2 66 ]; 67 }, 68 69 /** 70 * The coordinates of the centripetal force vector 71 */ 72 forceVector: function() { 73 let x = this.getX(this.angle, (0.9 - (0.08 * this.force)) * this.radius); 74 let y = this.getY(this.angle, (0.9 - (0.08 * this.force)) * this.radius); 75 let arrow1x = x + this.getX(this.angle + 0.1, 0.02); 76 let arrow1y = y + this.getY(this.angle + 0.1, 0.02); 77 let arrow2x = x + this.getX(this.angle - 0.1, 0.02); 78 let arrow2y = y + this.getY(this.angle - 0.1, 0.02); 79 return [ 80 x, y, // Center point 81 arrow1x, arrow1y, // Arrow line #1 82 arrow2x, arrow2y, // Arrow line #2 83 ]; 84 } 85 }, 86 methods: { 87 /** 88 * Handle a keyup event (implements keyboard shortcuts) 89 * @param {object} e - The event args 90 */ 91 keyup: function(e) { 92 if (e.key === "Escape") { 93 if (this.infoVisible) this.infoVisible = false; 94 else window.location.href = "../"; 95 } 96 }, 97 98 /** 99 * Toggle whether the simulation is active 100 */ 101 toggle: function() { 102 this.active = !this.active; 103 if (this.active) this.intervalID = setInterval(this.update, this.refreshRate * 1000); 104 else clearInterval(this.intervalID); 105 }, 106 107 /** 108 * Reset the simulation 109 */ 110 reset: function() { 111 this.time = 0; 112 }, 113 114 /** 115 * Update the simulation output 116 */ 117 update: function() { 118 this.time += this.refreshRate; 119 }, 120 121 /** 122 * Get the C coordinate of a point from an angle and distance 123 * @param {Number} angle The angle as a percentage (0 - 1) 124 * @param {Number} distance The distance 125 * @returns {Number} The X coordinate 126 */ 127 getX: function(angle, distance) { 128 return Math.sin(angle * 2 * Math.PI) * distance; 129 }, 130 131 /** 132 * Get the Y coordinate of a point from an angle and distance 133 * @param {Number} angle The angle as a percentage (0 - 1) 134 * @param {Number} distance The distance 135 * @returns {Number} The Y coordinate 136 */ 137 getY: function(angle, distance) { 138 return -Math.cos(angle * 2 * Math.PI) * distance; 139 }, 140 }, 141 created: function() { 142 // Add keyup handler 143 window.addEventListener("keyup", this.keyup); 144 }, 145 destroyed: function() { 146 // Remove keyup handler 147 window.removeEventListener("keyup", this.keyup); 148 }, 149 } 150 151 152 153 // Create Vue app 154 function createApp() { 155 // Create app 156 Vue.createApp(App).mount("#app"); 157 158 // Unhide app divs 159 document.getElementById("input").hidden = false; 160 document.getElementById("output").hidden = false; 161 document.getElementById("data").hidden = false; 162 document.getElementById("info").hidden = false; 163 }