physics-simulations

A collection of physics simulations
git clone https://git.ashermorgan.net/physics-simulations/
Log | Files | Refs | README

horizontal-motion.js (5020B)


      1 const App = {
      2     data: function() {
      3         return {
      4             // Input data
      5             mass: 5,            // The object's mass (Kg)
      6             force: 5,           // The force acting on the object (N)
      7             staticFriction: 0,  // The coefficient of static friction
      8             kineticFriction: 0, // The coefficient of kinetic friction
      9             gravity: 9.8,       // The acceleration due to gravity (m/s/s)
     10 
     11             // Output data
     12             time: 0,            // The time (s)
     13             position: 0,        // The object's current position (m)
     14             velocity: 0,        // The object's current velocity (m/s)
     15 
     16             // Simulation properties
     17             active: false,      // Whether the simulation is active
     18             refreshRate: 0.01,  // The simulation refresh rate (s)
     19             intervalId: null,   // The value returned by setInterval
     20             infoVisible: false,
     21         }
     22     },
     23     computed: {
     24         /**
     25          * The force of static friction when the object is at rest
     26          */
     27         staticFrictionForce: function() {
     28             let maxForce = this.staticFriction * this.mass * this.gravity;
     29             if (Math.abs(this.force) <= maxForce) return -1 * this.force;
     30             else return Math.sign(this.force) * -1 * maxForce;
     31         },
     32 
     33         /**
     34          * The force of kinetic friction when the object is in motion
     35          */
     36         kineticFrictionForce: function() {
     37             let value = this.kineticFriction * this.mass * this.gravity;
     38             if (this.velocity > 0) return -1 * value;
     39             else if (this.velocity < 0) return value;
     40             else if (this.force > 0) return -1 * value;
     41             else if (this.force < 0) return value;
     42             else return 0;
     43         },
     44 
     45         /**
     46          * The net force on the object
     47          */
     48         netForce: function() {
     49             if (this.velocity === 0 && (Math.abs(this.staticFrictionForce) >= Math.abs(this.force) || Math.abs(this.kineticFrictionForce) >= Math.abs(this.force))) {
     50                 // The object is at rest and cannot overcome friction
     51                 return 0;
     52             }
     53             else {
     54                 return this.force + this.kineticFrictionForce;
     55             }
     56         },
     57 
     58         /**
     59          * The acceleration of the object
     60          */
     61         acceleration: function() {
     62             return this.netForce / this.mass;
     63         },
     64 
     65         /**
     66          * The position of reference frame indicators
     67          */
     68         references: function() {
     69             return [
     70                 (-1 * this.position) % 1,    // 1m
     71                 (-1 * this.position) % 0.1,  // 0.1m
     72             ];
     73         },
     74     },
     75     methods: {
     76         /**
     77          * Handle a keyup event (implements keyboard shortcuts)
     78          * @param {object} e - The event args
     79          */
     80         keyup: function(e) {
     81             if (e.key === "Escape") {
     82                 if (this.infoVisible) this.infoVisible = false;
     83                 else window.location.href = "../";
     84             }
     85         },
     86 
     87         /**
     88          * Toggle whether the simulation is active
     89          */
     90         toggle: function() {
     91             this.active = !this.active;
     92             if (this.active) this.intervalID = setInterval(this.update, this.refreshRate * 1000);
     93             else clearInterval(this.intervalID);
     94         },
     95 
     96         /**
     97          * Reset the simulation
     98          */
     99         reset: function() {
    100             this.time = 0;
    101             this.position = 0;
    102             this.velocity = 0;
    103         },
    104 
    105         /**
    106          * Update the simulation
    107          */
    108         update: function() {
    109             // Update time
    110             this.time += this.refreshRate;
    111 
    112             // Get updated velocity
    113             let newVelocity = this.velocity + (this.acceleration * this.refreshRate)
    114 
    115             // Correct velocity for friction
    116             if (Math.sign(this.velocity) !== Math.sign(newVelocity)) {
    117                 // The object was recently at rest
    118                 this.velocity = 0;
    119 
    120                 if (this.acceleration !== 0) {
    121                     // The object was able to overcome friction
    122                     this.velocity = newVelocity;
    123                 }
    124             }
    125             else {
    126                 // The object was not recently at rest
    127                 this.velocity = newVelocity;
    128             }
    129 
    130             // Update position
    131             this.position += (this.velocity * this.refreshRate);
    132         },
    133     },
    134     created: function() {
    135         // Add keyup handler
    136         window.addEventListener("keyup", this.keyup);
    137     },
    138     destroyed: function() {
    139         // Remove keyup handler
    140         window.removeEventListener("keyup", this.keyup);
    141     },
    142 }
    143 
    144 
    145 
    146 // Create Vue app
    147 function createApp() {
    148     // Create app
    149     Vue.createApp(App).mount("#app");
    150 
    151     // Unhide app divs
    152     document.getElementById("input").hidden = false;
    153     document.getElementById("output").hidden = false;
    154     document.getElementById("data").hidden = false;
    155     document.getElementById("info").hidden = false;
    156 }