commit 864a1f61ba8051553fe9d713dafb9ae107aa6369
parent 3e21420a4692d91c2adf0543e14dc3cd53a33efe
Author: AsherMorgan <59518073+AsherMorgan@users.noreply.github.com>
Date: Mon, 8 Mar 2021 08:56:18 -0800
Implement friction in horizontal motion simulation
Diffstat:
2 files changed, 78 insertions(+), 17 deletions(-)
diff --git a/simulations/horizontal-motion.html b/simulations/horizontal-motion.html
@@ -25,15 +25,23 @@
<div id="input" hidden>
<section>
<label for="massInput"><b>Mass:</b> {{ mass.toFixed(1) }} Kg</label>
- <input type="range" min="1" max="10" step="0.1" v-model.number="mass" @input="reset" @dblclick="mass=5" :disabled="active" id="massInput">
+ <input type="range" min="1" max="10" step="0.1" v-model.number="mass" @dblclick="mass=5" id="massInput">
</section>
<section>
- <label for="initialVelocityInput"><b>Initial Velocity:</b> {{ initialVelocity.toFixed(1) }} m/s</label>
- <input type="range" min="-10" max="10" step="0.1" v-model.number="initialVelocity" @input="reset" @dblclick="initialVelocity=1" :disabled="active" id="initialVelocityInput">
+ <label for="forceInput"><b>Applied Force:</b> {{ force.toFixed(1) }} N</label>
+ <input type="range" min="-10" max="10" step="0.1" v-model.number="force" @dblclick="force=0" id="forceInput">
</section>
<section>
- <label for="forceInput"><b>Applied Force:</b> {{ force.toFixed(1) }} N</label>
- <input type="range" min="-10" max="10" step="0.1" v-model.number="force" @input="reset" @dblclick="force=0" :disabled="active" id="forceInput">
+ <label for="staticFrictionInput"><b>Static Friction:</b> {{ staticFriction.toFixed(2) }}</label>
+ <input type="range" min="0" max="1" step="0.01" v-model.number="staticFriction" @dblclick="staticFriction=0" id="staticFrictionInput">
+ </section>
+ <section>
+ <label for="kineticFrictionInput"><b>Kinetic Friction:</b> {{ kineticFriction.toFixed(2) }}</label>
+ <input type="range" min="0" max="1" step="0.01" v-model.number="kineticFriction" @dblclick="kineticFriction=0" id="kineticFrictionInput">
+ </section>
+ <section>
+ <label for="gravityInput"><b>Gravity:</b> {{ gravity.toFixed(1) }} m/s<sup>2</sup></label>
+ <input type="range" min="0" max="10" step="0.1" v-model.number="gravity" @dblclick="gravity=9.8" id="gravityInput">
</section>
</div>
diff --git a/simulations/horizontal-motion.js b/simulations/horizontal-motion.js
@@ -1,10 +1,19 @@
const App = {
data: function() {
return {
+ // Input data
mass: 5, // The object's mass (Kg)
- initialVelocity: 1, // The object's initial velocity (m/s)
- force: 0, // The force acting on the object (N)
+ force: 5, // The force acting on the object (N)
+ staticFriction: 0, // The coefficient of static friction
+ kineticFriction: 0, // The coefficient of kinetic friction
+ gravity: 9.8, // The acceleration due to gravity (m/s/s)
+
+ // Output data
time: 0, // The time (s)
+ position: 0, // The object's current position (m)
+ velocity: 0, // The object's current velocity (m/s)
+
+ // Simulation properties
active: false, // Whether the simulation is active
refreshRate: 0.01, // The simulation refresh rate (s)
intervalId: null, // The value returned by setInterval
@@ -12,24 +21,44 @@ const App = {
},
computed: {
/**
- * The acceleration of the object
+ * The force of static friction when the object is at rest
*/
- acceleration: function() {
- return this.force / this.mass;
+ staticFrictionForce: function() {
+ let maxForce = this.staticFriction * this.mass * this.gravity;
+ if (Math.abs(this.force) <= maxForce) return -1 * this.force;
+ else return Math.sign(this.force) * -1 * maxForce;
},
/**
- * The velocity of the object
+ * The force of kinetic friction when the object is in motion
*/
- velocity: function() {
- return this.initialVelocity + (this.acceleration * this.time);
+ kineticFrictionForce: function() {
+ let value = this.kineticFriction * this.mass * this.gravity;
+ if (this.velocity > 0) return -1 * value;
+ else if (this.velocity < 0) return value;
+ else if (this.force > 0) return -1 * value;
+ else if (this.force < 0) return value;
+ else return 0;
},
/**
- * The position of the object
+ * The net force on the object
*/
- position: function() {
- return (this.initialVelocity * this.time) + (0.5 * this.acceleration * this.time * this.time);
+ netForce: function() {
+ if (this.velocity === 0 && (Math.abs(this.staticFrictionForce) >= Math.abs(this.force) || Math.abs(this.kineticFrictionForce) >= Math.abs(this.force))) {
+ // The object is at rest and cannot overcome friction
+ return 0;
+ }
+ else {
+ return this.force + this.kineticFrictionForce;
+ }
+ },
+
+ /**
+ * The acceleration of the object
+ */
+ acceleration: function() {
+ return this.netForce / this.mass;
},
/**
@@ -57,13 +86,37 @@ const App = {
*/
reset: function() {
this.time = 0;
+ this.position = 0;
+ this.velocity = 0;
},
/**
- * Update the simulation output
+ * Update the simulation
*/
update: function() {
+ // Update time
this.time += this.refreshRate;
+
+ // Get updated velocity
+ let newVelocity = this.velocity + (this.acceleration * this.refreshRate)
+
+ // Correct velocity for friction
+ if (Math.sign(this.velocity) !== Math.sign(newVelocity)) {
+ // The object was recently at rest
+ this.velocity = 0;
+
+ if (this.acceleration !== 0) {
+ // The object was able to overcome friction
+ this.velocity = newVelocity;
+ }
+ }
+ else {
+ // The object was not recently at rest
+ this.velocity = newVelocity;
+ }
+
+ // Update position
+ this.position += (this.velocity * this.refreshRate);
},
},
}