From 9a2974cfc4c4e70e8cfcd18c46c059590835a09d Mon Sep 17 00:00:00 2001
From: brynnchernosky <56202540+brynnchernosky@users.noreply.github.com>
Date: Mon, 1 May 2023 16:39:52 -0400
Subject: refactor weight

---
 .../nodes/PhysicsBox/PhysicsSimulationWeight.tsx   | 419 ++++++++++-----------
 1 file changed, 207 insertions(+), 212 deletions(-)

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

diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx
index f43994346..4b3daa0d8 100644
--- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx
+++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx
@@ -11,7 +11,7 @@ export interface IForce {
   component: boolean;
 }
 export interface IWeightProps {
-  dataDoc: doc;
+  dataDoc: Doc;
   adjustPendulumAngle: { angle: number; length: number };
   circularMotionRadius: number;
   coefficientOfKineticFriction: number;
@@ -21,7 +21,6 @@ export interface IWeightProps {
   displayYVelocity: number;
   elasticCollisions: boolean;
   gravity: number;
-  incrementTime: number;
   mass: number;
   mode: string;
   noMovement: boolean;
@@ -229,8 +228,213 @@ export default class Weight extends React.Component<IWeightProps, IState> {
         this.props.dataDoc['velocityYDisplay'] = y
       }
     }
+    
+    // Prevent bug when switching between sims
+    if (prevProps.startForces != this.props.startForces) {
+      this.setState({xVelocity: this.props.startVelX})
+      this.setState({yVelocity: this.props.startVelY})
+      this.setDisplayValues();
+    }
+
+    // Make sure weight doesn't go above max height
+    if (prevState.updatedStartPosY != this.state.updatedStartPosY || prevProps.startVelY != this.props.startVelY) {
+      if (this.props.dataDoc['simulationType'] == "One Weight") {
+        let maxYPos = this.state.updatedStartPosY;
+        if (this.props.startVelY != 0) {
+          maxYPos -= (this.props.startVelY * this.props.startVelY) / (2 * Math.abs(this.props.gravity));
+        }
+        if (maxYPos < 0) {
+          maxYPos = 0;
+        }
+        this.setState({maxPosYConservation: maxYPos})
+      }
+    }
+
+    // Check for collisions and update
+    if (prevState.timer != this.state.timer) {
+      if (!this.props.paused && !this.props.noMovement) {
+        let collisions = false;
+        if (
+          this.props.dataDoc['simulationType'] == "One Weight" ||
+          this.props.dataDoc['simulationType'] == "Inclined Plane"
+        ) {
+          const collisionsWithGround = this.checkForCollisionsWithGround();
+          const collisionsWithWalls = this.checkForCollisionsWithWall();
+          collisions = collisionsWithGround || collisionsWithWalls;
+        }
+        if (this.props.dataDoc['simulationType'] == "Pulley") {
+          if (this.state.yPosition <= this.props.yMin + 100 || this.state.yPosition >= this.props.yMax - 100) {
+            collisions = true;
+          }
+        }
+        if (!collisions) {
+          this.update();
+        }
+        this.setDisplayValues();
+      }
+    }
+
+    // Reset everything on reset button click
+    if (prevProps.reset != this.props.reset) {
+      this.resetEverything();
+    }
+    
+    // Convert from static to kinetic friction if/when weight slips on inclined plane
+    if (prevState.xVelocity != this.state.xVelocity) {
+      if (
+        this.props.dataDoc['simulationType'] == "Inclined Plane" &&
+        Math.abs(this.state.xVelocity) > 0.1 &&
+        this.props.dataDoc['mode'] != "Review" &&
+        !this.state.kineticFriction
+      ) {
+        this.setState({kineticFriction: true})
+        const normalForce: IForce = {
+          description: "Normal Force",
+          magnitude:
+            this.props.mass *
+            Math.abs(this.props.gravity) *
+            Math.cos(Math.atan(this.props.wedgeHeight / this.props.wedgeWidth)),
+          directionInDegrees:
+            180 - 90 - (Math.atan(this.props.wedgeHeight / this.props.wedgeWidth) * 180) / Math.PI,
+          component: false,
+        };
+        let frictionForce: IForce = {
+          description: "Kinetic Friction Force",
+          magnitude:
+            this.props.mass *
+            this.props.coefficientOfKineticFriction *
+            Math.abs(this.props.gravity) *
+            Math.cos(Math.atan(this.props.wedgeHeight / this.props.wedgeWidth)),
+          directionInDegrees:
+            180 - (Math.atan(this.props.wedgeHeight / this.props.wedgeWidth) * 180) / Math.PI,
+          component: false,
+        };
+        // reduce magnitude of friction force if necessary such that block cannot slide up plane
+        let yForce = -Math.abs(this.props.gravity);
+        yForce +=
+          normalForce.magnitude *
+          Math.sin((normalForce.directionInDegrees * Math.PI) / 180);
+        yForce +=
+          frictionForce.magnitude *
+          Math.sin((frictionForce.directionInDegrees * Math.PI) / 180);
+        if (yForce > 0) {
+          frictionForce.magnitude =
+            (-normalForce.magnitude *
+              Math.sin((normalForce.directionInDegrees * Math.PI) / 180) +
+              Math.abs(this.props.gravity)) /
+            Math.sin((frictionForce.directionInDegrees * Math.PI) / 180);
+        }
+
+        const frictionForceComponent: IForce = {
+          description: "Kinetic Friction Force",
+
+          magnitude:
+            this.props.mass *
+            this.props.coefficientOfKineticFriction *
+            Math.abs(this.props.gravity) *
+            Math.cos(Math.atan(this.props.wedgeHeight / this.props.wedgeWidth)),
+          directionInDegrees:
+            180 - (Math.atan(this.props.wedgeHeight / this.props.wedgeWidth) * 180) / Math.PI,
+          component: true,
+        };
+        const normalForceComponent: IForce = {
+          description: "Normal Force",
+          magnitude:
+            this.props.mass *
+            Math.abs(this.props.gravity) *
+            Math.cos(Math.atan(this.props.wedgeHeight / this.props.wedgeWidth)),
+          directionInDegrees:
+            180 - 90 - (Math.atan(this.props.wedgeHeight / this.props.wedgeWidth) * 180) / Math.PI,
+          component: true,
+        };
+        const gravityParallel: IForce = {
+          description: "Gravity Parallel Component",
+          magnitude:
+            this.props.mass *
+            Math.abs(this.props.gravity) *
+            Math.sin(Math.PI / 2 - Math.atan(this.props.wedgeHeight / this.props.wedgeWidth)),
+          directionInDegrees:
+            180 -
+            90 -
+            (Math.atan(this.props.wedgeHeight / this.props.wedgeWidth) * 180) / Math.PI +
+            180,
+          component: true,
+        };
+        const gravityPerpendicular: IForce = {
+          description: "Gravity Perpendicular Component",
+          magnitude:
+            this.props.mass *
+            Math.abs(this.props.gravity) *
+            Math.cos(Math.PI / 2 - Math.atan(this.props.wedgeHeight / this.props.wedgeWidth)),
+          directionInDegrees:
+            360 - (Math.atan(this.props.wedgeHeight / this.props.wedgeWidth) * 180) / Math.PI,
+          component: true,
+        };
+        const gravityForce: IForce = {
+          description: "Gravity",
+          magnitude: this.props.mass * Math.abs(this.props.gravity),
+          directionInDegrees: 270,
+          component: false,
+        };
+        if (this.props.coefficientOfKineticFriction != 0) {
+          this.props.dataDoc['updatedForces'] = ([gravityForce, normalForce, frictionForce]);
+          this.props.dataDoc['componentForces'] = ([
+            frictionForceComponent,
+            normalForceComponent,
+            gravityParallel,
+            gravityPerpendicular,
+          ]);
+        } else {
+          this.props.dataDoc['updatedForces'] = ([gravityForce, normalForce]);
+          this.props.dataDoc['componentForces'] = ([
+            normalForceComponent,
+            gravityParallel,
+            gravityPerpendicular,
+          ]);
+        }
+      }
+    }
+
+    // Add/remove walls when simulation type changes
+    if (prevProps.simulationType != this.props.simulationType) {
+      let w: IWallProps[] = [];
+      if (this.props.dataDoc['simulationType'] == "One Weight" || this.props.dataDoc['simulationType'] == "Inclined Plane") {
+        w.push({ length: 70, xPos: 0, yPos: 0, angleInDegrees: 0 });
+        w.push({ length: 70, xPos: 0, yPos: 80, angleInDegrees: 0 });
+        w.push({ length: 80, xPos: 0, yPos: 0, angleInDegrees: 90 });
+        w.push({ length: 80, xPos: 69.5, yPos: 0, angleInDegrees: 90 });
+      }
+      this.setState({walls: w})
+    }
 
-    // TODO move all use effect code here
+    // Update x position when start pos x changes
+    if (prevProps.startPosX != this.props.startPosX) {
+      if (this.props.paused) {
+        this.setState({xPosition: this.props.startPosX})
+        this.setState({updatedStartPosX: this.props.startPosX})
+        this.props.dataDoc['positionXDisplay'] = this.props.startPosX
+      }
+    }
+
+
+    // Update y position when start pos y changes
+    if (prevProps.startPosY != this.props.startPosY) {
+       if (this.props.paused) {
+        this.setState({yPosition: this.props.startPosY})
+        this.setState({updatedStartPosY: this.props.startPosY})
+        this.props.dataDoc['positionYDisplay'] = this.props.startPosY
+      }
+    }
+
+    // Update wedge coordinates
+    if (prevProps.wedgeWidth != this.props.wedgeWidth || prevProps.wedgeHeight != this.props.wedgeHeight) {
+      const left = this.props.xMax * 0.5 - 200;
+      const coordinatePair1 = Math.round(left) + "," + this.props.yMax + " ";
+      const coordinatePair2 = Math.round(left + this.props.wedgeWidth) + "," + this.props.yMax + " ";
+      const coordinatePair3 = Math.round(left) + "," + (this.props.yMax - this.props.wedgeHeight);
+      const coord = coordinatePair1 + coordinatePair2 + coordinatePair3;
+      this.setState({coordinates: coord})
+    } 
   }
 
   // Reset simulation on reset button click
@@ -685,215 +889,6 @@ export default class Weight extends React.Component<IWeightProps, IState> {
     }
   };
 
-
-  // TODO
-  // Prevent bug when switching between sims
-  useEffect(() => {
-    setXVelocity(startVelX);
-    setYVelocity(startVelY);
-    setDisplayValues();
-  }, [startForces]);
-
-  // Make sure weight doesn't go above max height
-  useEffect(() => {
-    if (this.props.dataDoc['simulationType'] == "One Weight") {
-      let maxYPos = updatedStartPosY;
-      if (startVelY != 0) {
-        maxYPos -= (startVelY * startVelY) / (2 * Math.abs(gravity));
-      }
-      if (maxYPos < 0) {
-        maxYPos = 0;
-      }
-      setMaxPosYConservation(maxYPos);
-    }
-  }, [updatedStartPosY, startVelY]);
-
-  // Check for collisions and update
-  useEffect(() => {
-    if (!paused && !noMovement) {
-      let collisions = false;
-      if (
-        this.props.dataDoc['simulationType'] == "One Weight" ||
-        this.props.dataDoc['simulationType'] == "Inclined Plane"
-      ) {
-        const collisionsWithGround = checkForCollisionsWithGround();
-        const collisionsWithWalls = checkForCollisionsWithWall();
-        collisions = collisionsWithGround || collisionsWithWalls;
-      }
-      if (this.props.dataDoc['simulationType'] == "Pulley") {
-        if (yPosition <= yMin + 100 || yPosition >= yMax - 100) {
-          collisions = true;
-        }
-      }
-      if (!collisions) {
-        update();
-      }
-      setDisplayValues();
-    }
-  }, [incrementTime]);
-
-  // Reset everything on reset button click
-  useEffect(() => {
-    resetEverything();
-  }, [reset]);
-
-  // Convert from static to kinetic friction if/when weight slips on inclined plane
-  useEffect(() => {
-    if (
-      this.props.dataDoc['simulationType'] == "Inclined Plane" &&
-      Math.abs(xVelocity) > 0.1 &&
-      this.props.dataDoc['mode'] != "Review" &&
-      !kineticFriction
-    ) {
-      setKineticFriction(true);
-      //switch from static to kinetic friction
-      const normalForce: IForce = {
-        description: "Normal Force",
-        magnitude:
-          mass *
-          Math.abs(gravity) *
-          Math.cos(Math.atan(wedgeHeight / wedgeWidth)),
-        directionInDegrees:
-          180 - 90 - (Math.atan(wedgeHeight / wedgeWidth) * 180) / Math.PI,
-        component: false,
-      };
-      let frictionForce: IForce = {
-        description: "Kinetic Friction Force",
-        magnitude:
-          mass *
-          coefficientOfKineticFriction *
-          Math.abs(gravity) *
-          Math.cos(Math.atan(wedgeHeight / wedgeWidth)),
-        directionInDegrees:
-          180 - (Math.atan(wedgeHeight / wedgeWidth) * 180) / Math.PI,
-        component: false,
-      };
-      // reduce magnitude of friction force if necessary such that block cannot slide up plane
-      let yForce = -Math.abs(gravity);
-      yForce +=
-        normalForce.magnitude *
-        Math.sin((normalForce.directionInDegrees * Math.PI) / 180);
-      yForce +=
-        frictionForce.magnitude *
-        Math.sin((frictionForce.directionInDegrees * Math.PI) / 180);
-      if (yForce > 0) {
-        frictionForce.magnitude =
-          (-normalForce.magnitude *
-            Math.sin((normalForce.directionInDegrees * Math.PI) / 180) +
-            Math.abs(gravity)) /
-          Math.sin((frictionForce.directionInDegrees * Math.PI) / 180);
-      }
-
-      const frictionForceComponent: IForce = {
-        description: "Kinetic Friction Force",
-
-        magnitude:
-          mass *
-          coefficientOfKineticFriction *
-          Math.abs(gravity) *
-          Math.cos(Math.atan(wedgeHeight / wedgeWidth)),
-        directionInDegrees:
-          180 - (Math.atan(wedgeHeight / wedgeWidth) * 180) / Math.PI,
-        component: true,
-      };
-      const normalForceComponent: IForce = {
-        description: "Normal Force",
-        magnitude:
-          mass *
-          Math.abs(gravity) *
-          Math.cos(Math.atan(wedgeHeight / wedgeWidth)),
-        directionInDegrees:
-          180 - 90 - (Math.atan(wedgeHeight / wedgeWidth) * 180) / Math.PI,
-        component: true,
-      };
-      const gravityParallel: IForce = {
-        description: "Gravity Parallel Component",
-        magnitude:
-          mass *
-          Math.abs(gravity) *
-          Math.sin(Math.PI / 2 - Math.atan(wedgeHeight / wedgeWidth)),
-        directionInDegrees:
-          180 -
-          90 -
-          (Math.atan(wedgeHeight / wedgeWidth) * 180) / Math.PI +
-          180,
-        component: true,
-      };
-      const gravityPerpendicular: IForce = {
-        description: "Gravity Perpendicular Component",
-        magnitude:
-          mass *
-          Math.abs(gravity) *
-          Math.cos(Math.PI / 2 - Math.atan(wedgeHeight / wedgeWidth)),
-        directionInDegrees:
-          360 - (Math.atan(wedgeHeight / wedgeWidth) * 180) / Math.PI,
-        component: true,
-      };
-      const gravityForce: IForce = {
-        description: "Gravity",
-        magnitude: mass * Math.abs(gravity),
-        directionInDegrees: 270,
-        component: false,
-      };
-      if (coefficientOfKineticFriction != 0) {
-        this.props.dataDoc['updatedForces'] = ([gravityForce, normalForce, frictionForce]);
-        this.props.dataDoc['componentForces'] = ([
-          frictionForceComponent,
-          normalForceComponent,
-          gravityParallel,
-          gravityPerpendicular,
-        ]);
-      } else {
-        this.props.dataDoc['updatedForces'] = ([gravityForce, normalForce]);
-        this.props.dataDoc['componentForces'] = ([
-          normalForceComponent,
-          gravityParallel,
-          gravityPerpendicular,
-        ]);
-      }
-    }
-  }, [xVelocity]);
-
-  // Add/remove walls when simulation type changes
-  useEffect(() => {
-    let w: IWallProps[] = [];
-    if (this.props.dataDoc['simulationType'] == "One Weight" || this.props.dataDoc['simulationType'] == "Inclined Plane") {
-      w.push({ length: 70, xPos: 0, yPos: 0, angleInDegrees: 0 });
-      w.push({ length: 70, xPos: 0, yPos: 80, angleInDegrees: 0 });
-      w.push({ length: 80, xPos: 0, yPos: 0, angleInDegrees: 90 });
-      w.push({ length: 80, xPos: 69.5, yPos: 0, angleInDegrees: 90 });
-    }
-    setWalls(w);
-  }, [this.props.dataDoc['simulationType']]);
-
-  // Update x position when start pos x changes
-  useEffect(() => {
-    if (paused) {
-      setUpdatedStartPosX(startPosX);
-      setXPosition(startPosX);
-      setXPosDisplay(startPosX);
-    }
-  }, [startPosX]);
-
-  // Update y position when start pos y changes
-  useEffect(() => {
-    if (paused) {
-      setUpdatedStartPosY(startPosY);
-      setYPosition(startPosY);
-      setYPosDisplay(startPosY);
-    }
-  }, [startPosY]);
-
-  // Update wedge coordinates
-  useEffect(() => {
-    const left = xMax * 0.5 - 200;
-    const coordinatePair1 = Math.round(left) + "," + yMax + " ";
-    const coordinatePair2 = Math.round(left + wedgeWidth) + "," + yMax + " ";
-    const coordinatePair3 = Math.round(left) + "," + (yMax - wedgeHeight);
-    const coord = coordinatePair1 + coordinatePair2 + coordinatePair3;
-    setCoordinates(coord);
-  }, [wedgeWidth, wedgeHeight]);
-
   // Render weight, spring, rod(s), vectors
   return (
     <div style={{ zIndex: -1000 }}>
-- 
cgit v1.2.3-70-g09d2

