aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrynnchernosky <56202540+brynnchernosky@users.noreply.github.com>2023-05-01 16:39:52 -0400
committerbrynnchernosky <56202540+brynnchernosky@users.noreply.github.com>2023-05-01 16:39:52 -0400
commit9a2974cfc4c4e70e8cfcd18c46c059590835a09d (patch)
tree0f3ceafba657288a3049227e4eb5da761358fda8
parentdd1e2c37988b88ce1c045cf326cf1c328d64e523 (diff)
refactor weight
-rw-r--r--src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx419
1 files changed, 207 insertions, 212 deletions
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 }}>