From a936f7c60c56e4a92aed99cae8e4194fa7fdeda5 Mon Sep 17 00:00:00 2001
From: brynnchernosky <56202540+brynnchernosky@users.noreply.github.com>
Date: Mon, 1 May 2023 14:19:49 -0400
Subject: add to box

---
 .../nodes/PhysicsBox/PhysicsSimulationBox.tsx      | 343 ++++++++++++++++++++-
 1 file changed, 341 insertions(+), 2 deletions(-)

(limited to 'src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx')

diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
index 3ae281177..88338d9b8 100644
--- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
+++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
@@ -95,7 +95,6 @@ export default class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<Fi
   const radius = 50;
   const wallPositions: IWallProps[] = [];
 
-
   componentDidMount() {
     this.wallPositions.push({ length: 70, xPos: 0, yPos: 0, angleInDegrees: 0 });
     this.wallPositions.push({ length: 70, xPos: 0, yPos: 80, angleInDegrees: 0 });
@@ -196,9 +195,167 @@ export default class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<Fi
     this.dataDoc.startForces2 = this.dataDoc.startForces2 ?? [];
     this.dataDoc.updatedForces2 = this.dataDoc.updatedForces2 ?? [];
     this.dataDoc.mass2 = this.dataDoc.mass2 ?? 1;
+
+    // Setup simulation
+    if (this.dataDoc.simulationType != "Circular Motion") {
+      this.dataDoc.startVelX = 0;
+      this.dataDoc.setStartVelY = 0;
+      this.dataDoc.velocityXDisplay = (0);
+      this.dataDoc.velocityYDisplay = (0);
+    }
+    if (this.dataDoc.mode == "Freeform") {
+      this.dataDoc.showForceMagnitudes = (true);
+      if (this.dataDoc.simulationType == "One Weight") {
+        this.dataDoc.showComponentForces = false;
+        this.dataDoc.startPosY = (this.yMin + this.radius);
+        this.dataDoc.startPosX = ((this.xMax + this.xMin) / 2 - this.radius);
+        this.dataDoc.positionYDisplay = (this.getDisplayYPos(this.yMin + this.radius));
+        this.dataDoc.positionXDisplay((this.xMax + this.xMin) / 2 - this.radius);
+        this.dataDoc.updatedForces = ([
+          {
+            description: "Gravity",
+            magnitude: Math.abs(this.dataDoc.gravity) * this.dataDoc.mass,
+            directionInDegrees: 270,
+            component: false,
+          },
+        ]);
+        this.dataDoc.startForces = ([
+          {
+            description: "Gravity",
+            magnitude: Math.abs(this.dataDoc.gravity) * this.dataDoc.mass,
+            directionInDegrees: 270,
+            component: false,
+          },
+        ]);
+        this.dataDoc.simulationReset = (!this.dataDoc.simulationReset);
+      } else if (this.dataDoc.simulationType == "Inclined Plane") {
+        this.changeWedgeBasedOnNewAngle(26);
+        this.dataDoc.startForces = ([
+          {
+            description: "Gravity",
+            magnitude: Math.abs(this.dataDoc.gravity) * this.dataDoc.mass,
+            directionInDegrees: 270,
+            component: false,
+          },
+        ]);
+        this.updateForcesWithFriction(Number(this.dataDoc.coefficientOfStaticFriction));
+      } else if (this.dataDoc.simulationType == "Pendulum") {
+        this.setupPendulum();
+      } else if (this.dataDoc.simulationType == "Spring") {
+        this.setupSpring();
+      } else if (this.dataDoc.simulationType == "Circular Motion") {
+        this.setupCircular(0);
+      } else if (this.dataDoc.simulationType == "Pulley") {
+        this.setupPulley();
+      } else if (this.dataDoc.simulationType == "Suspension") {
+        this.setupSuspension();
+      }
+    } else if (this.dataDoc.mode == "Review") {
+      this.dataDoc.showComponentForces = (false);
+      this.dataDoc.showForceMagnitudes = (true);
+      this.dataDoc.showAcceleration = (false);
+      this.dataDoc.showVelocity = (false);
+      this.dataDoc.showForces= (true);
+      this.generateNewQuestion();
+      if (this.dataDoc.simulationType == "One Weight") {
+        // TODO - one weight review problems
+      } else if (this.dataDoc.simulationType == "Spring") {
+        this.setupSpring();
+        // TODO - spring review problems
+      } else if (this.dataDoc.simulationType == "Inclined Plane") {
+        this.dataDoc.updatedForces = ([]);
+        this.dataDoc.startForces = ([]);
+      } else if (this.dataDoc.simulationType == "Pendulum") {
+        this.setupPendulum();
+        // TODO - pendulum review problems
+      } else if (this.dataDoc.simulationType == "Circular Motion") {
+        this.setupCircular(0);
+        // TODO - circular motion review problems
+      } else if (this.dataDoc.simulationType == "Pulley") {
+        this.setupPulley();
+        // TODO - pulley tutorial review problems
+      } else if (this.dataDoc.simulationType == "Suspension") {
+        this.setupSuspension();
+        // TODO - suspension tutorial review problems
+      }
+    } else if (this.dataDoc.mode == "Tutorial") {
+      this.dataDoc.showComponentForces = (false);
+      this.dataDoc.stepNumber = (0);
+      this.dataDoc.showAcceleration = (false);
+      if (this.dataDoc.simulationType != "Circular Motion") {
+        this.dataDoc.velocityXDisplay = (0);
+        setVelocityYDisplay = (0);
+        this.dataDoc.showVelocity = (false);
+      } else {
+        this.dataDoc.velocityXDisplay = (20);
+        this.dataDoc.velocityYDisplay = (0);
+        this.dataDoc.showVelocity = (true);
+      }
+
+      if (this.dataDoc.simulationType == "One Weight") {
+        this.dataDoc.showForces = (true);
+        this.dataDoc.startPosY = (this.yMax - 100);
+        this.dataDoc.startPosX = ((this.xMax + this.xMin) / 2 - this.radius);
+        this.dataDoc.selectedTutorial = (tutorials.freeWeight);
+        this.dataDoc.startForces = (this.getForceFromJSON(tutorials.freeWeight.steps[0].forces));
+        this.dataDoc.showForceMagnitudes = (tutorials.freeWeight.steps[0].showMagnitude);
+      } else if (this.dataDoc.simulationType == "Spring") {
+        this.dataDoc.showForces = (true);
+        this.setupSpring();
+        this.dataDoc.startPosY = (this.yMin + 200 + 19.62);
+        this.dataDoc.startPosX = ((this.xMax + this.xMin) / 2 - this.radius);
+        this.dataDoc.selectedTutorial = (tutorials.spring);
+        this.dataDoc.startForces = (this.getForceFromJSON(tutorials.spring.steps[0].forces));
+        this.dataDoc.showForceMagnitudes = (tutorials.spring.steps[0].showMagnitude);
+      } else if (this.dataDoc.simulationType == "Pendulum") {
+        this.dataDoc.showForces = (true);
+        const length = 300;
+        const angle = 30;
+        const x = length * Math.cos(((90 - angle) * Math.PI) / 180);
+        const y = length * Math.sin(((90 - angle) * Math.PI) / 180);
+        const xPos = this.xMax / 2 - x - this.radius;
+        const yPos = y - this.radius - 5;
+        this.dataDoc.startPosX = (xPos);
+        this.dataDoc.startPosY = (yPos);
+        this.dataDoc.selectedTutorial = (tutorials.pendulum);
+        this.dataDoc.startForces = (this.getForceFromJSON(tutorials.pendulum.steps[0].forces));
+        this.dataDoc.showForceMagnitudes = (tutorials.pendulum.steps[0].showMagnitude);
+        this.dataDoc.pendulumAngle = (30);
+        this.dataDoc.pendulumLength = (300);
+        this.dataDoc.adjustPendulumAngle = ({ angle: 30, length: 300 });
+      } else if (this.dataDoc.simulationType == "Inclined Plane") {
+        this.dataDoc.showForces = (true);
+        this.dataDoc.wedgeAngle = (26);
+        this.changeWedgeBasedOnNewAngle(26);
+        this.dataDoc.selectedTutorial = (tutorials.inclinePlane);
+        this.dataDoc.startForces = (
+          this.getForceFromJSON(tutorials.inclinePlane.steps[0].forces)
+        );
+        this.dataDoc.showForceMagnitudes = (tutorials.inclinePlane.steps[0].showMagnitude);
+      } else if (this.dataDoc.simulationType == "Circular Motion") {
+        this.dataDoc.showForces = (true);
+        this.setupCircular(40);
+        this.dataDoc.selectedTutorial = (tutorials.circular);
+        this.dataDoc.startForces = (this.getForceFromJSON(tutorials.circular.steps[0].forces));
+        this.dataDoc.showForceMagnitudes = (tutorials.circular.steps[0].showMagnitude);
+      } else if (simulationType == "Pulley") {
+        this.dataDoc.showForces = (true);
+        this.setupPulley();
+        this.dataDoc.selectedTutorial = (tutorials.pulley);
+        this.dataDoc.startForces = (this.getForceFromJSON(tutorials.pulley.steps[0].forces));
+        this.dataDoc.showForceMagnitudes = (tutorials.pulley.steps[0].showMagnitude);
+      } else if (this.dataDoc.simulationType == "Suspension") {
+        this.dataDoc.showForces = (true);
+        this.setupSuspension();
+        this.dataDoc.selectedTutorial = (tutorials.suspension);
+        this.dataDoc.startForces = (this.getForceFromJSON(tutorials.suspension.steps[0].forces));
+        this.dataDoc.showForceMagnitudes = (tutorials.suspension.steps[0].showMagnitude);
+      }
+      this.dataDoc.simulationReset = (!this.dataDoc.simulationReset);
+    }
   }
 
-  componentDidUpdate(prevProps, prevState) {
+  componentDidUpdate() {
     this.xMax = this.layoutDoc._width;
     this.yMax = this.layoutDoc._height;
     this.radius = 0.1*this.layoutDoc._height;
@@ -838,6 +995,188 @@ export default class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<Fi
     );
   };
   
+  // Default setup for uniform circular motion simulation
+  setupCircular = (value: number) => {
+    this.dataDoc.showComponentForces = (false);
+    this.dataDoc.startVelY = (0);
+    this.dataDoc.startVelX = (value);
+    let xPos = (this.xMax + this.xMin) / 2 - this.radius;
+    let yPos = (this.yMax + this.yMin) / 2 + this.dataDoc.circularMotionRadius - this.radius;
+    this.dataDoc.startPosY = (yPos);
+    this.dataDoc.startPosX = (xPos);
+    const tensionForce: IForce = {
+      description: "Centripetal Force",
+      magnitude: (this.dataDoc.startVelX ** 2 * this.dataDoc.mass) / this.dataDoc.circularMotionRadius,
+      directionInDegrees: 90,
+      component: false,
+    };
+    this.dataDoc.updatedForces = ([tensionForce]);
+    this.dataDoc.startForces = ([tensionForce]);
+    this.dataDoc.simulationReset = (!this.dataDoc.simulationReset);
+  };
+
+  // Default setup for pendulum simulation
+  setupPendulum = () => {
+    const length = 300;
+    const angle = 30;
+    const x = length * Math.cos(((90 - angle) * Math.PI) / 180);
+    const y = length * Math.sin(((90 - angle) * Math.PI) / 180);
+    const xPos = this.xMax / 2 - x - this.radius;
+    const yPos = y - this.radius - 5;
+    this.dataDoc.startPosX = (xPos);
+    this.dataDoc.startPosY = (yPos);
+    const mag = this.dataDoc.mass * Math.abs(this.dataDoc.gravity) * Math.sin((60 * Math.PI) / 180);
+    const forceOfTension: IForce = {
+      description: "Tension",
+      magnitude: mag,
+      directionInDegrees: 90 - angle,
+      component: false,
+    };
+
+    const tensionComponent: IForce = {
+      description: "Tension",
+      magnitude: mag,
+      directionInDegrees: 90 - angle,
+      component: true,
+    };
+    const gravityParallel: IForce = {
+      description: "Gravity Parallel Component",
+      magnitude:
+      this.dataDoc.mass * Math.abs(this.dataDoc.gravity) * Math.sin(((90 - angle) * Math.PI) / 180),
+      directionInDegrees: -angle - 90,
+      component: true,
+    };
+    const gravityPerpendicular: IForce = {
+      description: "Gravity Perpendicular Component",
+      magnitude:
+      this.dataDoc.mass * Math.abs(this.dataDoc.gravity) * Math.cos(((90 - angle) * Math.PI) / 180),
+      directionInDegrees: -angle,
+      component: true,
+    };
+
+    this.dataDoc.componentForces = ([
+      tensionComponent,
+      gravityParallel,
+      gravityPerpendicular,
+    ]);
+    this.dataDoc.updatedForces = ([
+      {
+        description: "Gravity",
+        magnitude: this.dataDoc.mass * Math.abs(this.dataDoc.gravity),
+        directionInDegrees: 270,
+        component: false,
+      },
+      forceOfTension,
+    ]);
+    this.dataDoc.startForces = ([
+      {
+        description: "Gravity",
+        magnitude: this.dataDoc.mass * Math.abs(this.dataDoc.gravity),
+        directionInDegrees: 270,
+        component: false,
+      },
+      forceOfTension,
+    ]);
+    this.dataDoc.startPendulumAngle = (30);
+    this.dataDoc.pendulumAngle = (30);
+    this.dataDoc.pendulumLength = (300);
+    this.dataDoc.adjustPendulumAngle = ({ angle: 30, length: 300 });
+  };
+
+  // Default setup for spring simulation
+  setupSpring = () => {
+    this.dataDoc.showComponentForces = (false);
+    const gravityForce: IForce = {
+      description: "Gravity",
+      magnitude: Math.abs(this.dataDoc.gravity) * this.dataDoc.mass,
+      directionInDegrees: 270,
+      component: false,
+    };
+    this.dataDoc.updatedForces = ([gravityForce]);
+    this.dataDoc.startForces = ([gravityForce]);
+    this.dataDoc.startPosX = (this.xMax / 2 - this.radius);
+    this.dataDoc.startPosY = (200);
+    this.dataDoc.springConstant = (0.5);
+    this.dataDoc.springRestLength = (200);
+    this.dataDoc.springStartLength = (200);
+    this.dataDoc.simulationReset = (!this.dataDoc.simulationReset);
+  };
+
+  // Default setup for suspension simulation
+  setupSuspension = () => {
+    let xPos = (this.xMax + this.xMin) / 2 - this.radius;
+    let yPos = this.yMin + 200;
+    this.dataDoc.startPosY = (yPos);
+    this.dataDoc.startPosX = (xPos);
+    this.dataDoc.positionYDisplay = (getDisplayYPos(yPos));
+    this.dataDoc.positionXDisplay = (xPos);
+    let tensionMag = (this.dataDoc.mass * Math.abs(this.dataDoc.gravity)) / (2 * Math.sin(Math.PI / 4));
+    const tensionForce1: IForce = {
+      description: "Tension",
+      magnitude: tensionMag,
+      directionInDegrees: 45,
+      component: false,
+    };
+    const tensionForce2: IForce = {
+      description: "Tension",
+      magnitude: tensionMag,
+      directionInDegrees: 135,
+      component: false,
+    };
+    const grav: IForce = {
+      description: "Gravity",
+      magnitude: this.dataDoc.mass * Math.abs(this.dataDoc.gravity),
+      directionInDegrees: 270,
+      component: false,
+    };
+    this.dataDoc.updatedForces = ([tensionForce1, tensionForce2, grav]);
+    this.dataDoc.startForces = ([tensionForce1, tensionForce2, grav]);
+    this.dataDoc.simulationReset = (!this.dataDoc.simulationReset);
+  };
+
+  // Default setup for pulley simulation
+  setupPulley = () => {
+    this.dataDoc.showComponentForces = (false);
+    this.dataDoc.startPosY = ((this.yMax + this.yMin) / 2);
+    this.dataDoc.startPosX = ((this.xMin + this.xMax) / 2 - 105);
+    this.dataDoc.positionYDisplay = (getDisplayYPos((this.yMax + this.yMin) / 2));
+    this.dataDoc.positionXDisplay = ((this.xMin + this.xMax) / 2 - 105);
+    let a = (-1 * ((mass - mass2) * Math.abs(gravity))) / (mass + mass2);
+    const gravityForce1: IForce = {
+      description: "Gravity",
+      magnitude: this.dataDoc.mass * Math.abs(this.dataDoc.gravity),
+      directionInDegrees: 270,
+      component: false,
+    };
+    const tensionForce1: IForce = {
+      description: "Tension",
+      magnitude: this.dataDoc.mass * a + this.dataDoc.mass * Math.abs(this.dataDoc.gravity),
+      directionInDegrees: 90,
+      component: false,
+    };
+    a *= -1;
+    const gravityForce2: IForce = {
+      description: "Gravity",
+      magnitude: this.dataDoc.mass2 * Math.abs(this.dataDoc.gravity),
+      directionInDegrees: 270,
+      component: false,
+    };
+    const tensionForce2: IForce = {
+      description: "Tension",
+      magnitude: this.dataDoc.mass2 * a + this.dataDoc.mass2 * Math.abs(this.dataDoc.gravity),
+      directionInDegrees: 90,
+      component: false,
+    };
+    this.dataDoc.updatedForces = ([gravityForce1, tensionForce1]);
+    this.dataDoc.startForces = ([gravityForce1, tensionForce1]);
+    this.dataDoc.startPosY2 = ((yMax + yMin) / 2);
+    this.dataDoc.startPosX2 = ((xMin + xMax) / 2 + 5);
+    this.dataDoc.positionYDisplay2 = (getDisplayYPos((yMax + yMin) / 2));
+    this.dataDoc.positionXDisplay2 = ((xMin + xMax) / 2 + 5);
+    this.dataDoc.updatedForces2 = ([gravityForce2, tensionForce2]);
+    this.dataDoc.startForces2 = ([gravityForce2, tensionForce2]);
+    this.dataDoc.simulationReset = (!this.dataDoc.simulationReset);
+  };
 
 
 
-- 
cgit v1.2.3-70-g09d2

