aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrynnchernosky <56202540+brynnchernosky@users.noreply.github.com>2023-05-01 15:22:38 -0400
committerbrynnchernosky <56202540+brynnchernosky@users.noreply.github.com>2023-05-01 15:22:38 -0400
commitdd1e2c37988b88ce1c045cf326cf1c328d64e523 (patch)
treec79aa6da8854d5f95a92ef71e79255e06f01e3a1
parentd071f4d835bca978833c6b7adeda56f41e82ef06 (diff)
refactor weight
-rw-r--r--src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx257
1 files changed, 125 insertions, 132 deletions
diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx
index ab23c42c0..f43994346 100644
--- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx
+++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx
@@ -179,13 +179,59 @@ export default class Weight extends React.Component<IWeightProps, IState> {
};
componentDidUpdate(prevProps: Readonly<IWeightProps>, prevState: Readonly<IState>, snapshot?: any): void {
- }
-
-
-
-
+ // Change pendulum angle from input field
+ if (prevProps.adjustPendulumAngle != this.props.adjustPendulumAngle) {
+ let length = this.props.adjustPendulumAngle.length;
+ const x =
+ length * Math.cos(((90 - this.props.adjustPendulumAngle.angle) * Math.PI) / 180);
+ const y =
+ length * Math.sin(((90 - this.props.adjustPendulumAngle.angle) * Math.PI) / 180);
+ const xPos = this.props.xMax / 2 - x - this.props.radius;
+ const yPos = y - this.props.radius - 5;
+ this.setState({xPosition: xPos})
+ this.setState({yPosition: yPos})
+ this.setState({updatedStartPosX: xPos})
+ this.setState({updatedStartPosY: yPos})
+ this.props.dataDoc['pendulumAngle'] = this.props.adjustPendulumAngle.angle
+ this.props.dataDoc['pendulumLength'] = this.props.adjustPendulumAngle.length
+ }
+ // When display values updated by user, update real values
+ if (prevProps.updateDisplay != this.props.updateDisplay) {
+ if (this.props.updateDisplay.xDisplay != this.state.xPosition) {
+ let x = this.props.updateDisplay.xDisplay;
+ x = Math.max(0, x);
+ x = Math.min(x, this.props.xMax - 2 * this.props.radius);
+ this.setState({updatedStartPosX: x})
+ this.setState({xPosition: x})
+ this.props.dataDoc['positionXDisplay'] = x
+ }
+
+ if (this.props.updateDisplay.yDisplay != this.getDisplayYPos(this.state.yPosition)) {
+ let y = this.props.updateDisplay.yDisplay;
+ y = Math.max(0, y);
+ y = Math.min(y, this.props.yMax - 2 * this.props.radius);
+ let coordinatePosition = this.getYPosFromDisplay(y);
+ this.setState({updatedStartPosY: coordinatePosition})
+ this.setState({yPosition: coordinatePosition})
+ this.props.dataDoc['positionYDisplay'] = y
+ }
+
+ if (this.props.displayXVelocity != this.state.xVelocity) {
+ let x = this.props.displayXVelocity;
+ this.setState({xVelocity: x})
+ this.props.dataDoc['velocityXDisplay'] = x
+ }
+
+ if (this.props.displayYVelocity != -this.state.yVelocity) {
+ let y = this.props.displayYVelocity;
+ this.setState({yVelocity: -y})
+ this.props.dataDoc['velocityYDisplay'] = y
+ }
+ }
+ // TODO move all use effect code here
+ }
// Reset simulation on reset button click
resetEverything = () => {
@@ -205,9 +251,6 @@ export default class Weight extends React.Component<IWeightProps, IState> {
this.setState({angleLabel: Math.round(this.props.dataDoc['pendulumAngle']* 100) / 100})
};
-
-
-
// Compute x acceleration from forces, F=ma
getNewAccelerationX = (forceList: IForce[]) => {
let newXAcc = 0;
@@ -275,7 +318,6 @@ export default class Weight extends React.Component<IWeightProps, IState> {
component: false,
};
}
-
return [
{
description: "Gravity",
@@ -309,7 +351,7 @@ export default class Weight extends React.Component<IWeightProps, IState> {
this.props.dataDoc['pendulumAngle'] = oppositeAngle;
const mag =
- this.props.mass * 9.81 * Math.cos((oppositeAngle * Math.PI) / 180) +
+ this.props.mass * Math.abs(this.props.gravity) * Math.cos((oppositeAngle * Math.PI) / 180) +
(this.props.mass * (xVel * xVel + yVel * yVel)) / pendulumLength;
const forceOfTension: IForce = {
@@ -437,7 +479,7 @@ export default class Weight extends React.Component<IWeightProps, IState> {
};
// Called at each RK4 step
- const evaluate = (
+ evaluate = (
currentXPos: number,
currentYPos: number,
currentXVel: number,
@@ -454,16 +496,16 @@ export default class Weight extends React.Component<IWeightProps, IState> {
const newYVel = currentYVel + deltaYVel * dt;
const newDeltaXPos = newXVel;
const newDeltaYPos = newYVel;
- let forces = updatedForces;
+ let forces = this.props.dataDoc['updatedForces'];
if (this.props.dataDoc['simulationType'] == "Pendulum") {
- forces = getNewPendulumForces(newXPos, newYPos, newXVel, newYVel);
+ forces = this.getNewPendulumForces(newXPos, newYPos, newXVel, newYVel);
} else if (this.props.dataDoc['simulationType'] == "Spring") {
- forces = getNewSpringForces(newYPos);
+ forces = this.getNewSpringForces(newYPos);
} else if (this.props.dataDoc['simulationType'] == "Circular Motion") {
- forces = getNewCircularMotionForces(newXPos, newYPos);
+ forces = this.getNewCircularMotionForces(newXPos, newYPos);
}
- const newDeltaXVel = getNewAccelerationX(forces);
- const newDeltaYVel = getNewAccelerationY(forces);
+ const newDeltaXVel = this.getNewAccelerationX(forces);
+ const newDeltaYVel = this.getNewAccelerationY(forces);
return {
xPos: newXPos,
yPos: newYPos,
@@ -477,26 +519,26 @@ export default class Weight extends React.Component<IWeightProps, IState> {
};
// Update position, velocity using RK4 method
- const update = () => {
- let startXVel = xVelocity;
- let startYVel = yVelocity;
- let xPos = xPosition;
- let yPos = yPosition;
- let xVel = xVelocity;
- let yVel = yVelocity;
- let forces = updatedForces;
+ update = () => {
+ let startXVel = this.state.xVelocity;
+ let startYVel = this.state.yVelocity;
+ let xPos = this.state.xPosition;
+ let yPos = this.state.yPosition;
+ let xVel = this.state.xVelocity;
+ let yVel = this.state.yVelocity;
+ let forces = this.props.dataDoc['updatedForces'];
if (this.props.dataDoc['simulationType'] == "Pendulum") {
- forces = getNewPendulumForces(xPos, yPos, xVel, yVel);
+ forces = this.getNewPendulumForces(xPos, yPos, xVel, yVel);
} else if (this.props.dataDoc['simulationType'] == "Spring") {
- forces = getNewSpringForces(yPos);
+ forces = this.getNewSpringForces(yPos);
} else if (this.props.dataDoc['simulationType'] == "Circular Motion") {
- forces = getNewCircularMotionForces(xPos, yPos);
+ forces = this.getNewCircularMotionForces(xPos, yPos);
}
- const xAcc = getNewAccelerationX(forces);
- const yAcc = getNewAccelerationY(forces);
- for (let i = 0; i < simulationSpeed; i++) {
- const k1 = evaluate(xPos, yPos, xVel, yVel, xVel, yVel, xAcc, yAcc, 0);
- const k2 = evaluate(
+ const xAcc = this.getNewAccelerationX(forces);
+ const yAcc = this.getNewAccelerationY(forces);
+ for (let i = 0; i < this.props.simulationSpeed; i++) {
+ const k1 = this.evaluate(xPos, yPos, xVel, yVel, xVel, yVel, xAcc, yAcc, 0);
+ const k2 = this.evaluate(
xPos,
yPos,
xVel,
@@ -505,9 +547,9 @@ export default class Weight extends React.Component<IWeightProps, IState> {
k1.deltaYPos,
k1.deltaXVel,
k1.deltaYVel,
- timestepSize * 0.5
+ this.props.timestepSize * 0.5
);
- const k3 = evaluate(
+ const k3 = this.evaluate(
xPos,
yPos,
xVel,
@@ -516,9 +558,9 @@ export default class Weight extends React.Component<IWeightProps, IState> {
k2.deltaYPos,
k2.deltaXVel,
k2.deltaYVel,
- timestepSize * 0.5
+ this.props.timestepSize * 0.5
);
- const k4 = evaluate(
+ const k4 = this.evaluate(
xPos,
yPos,
xVel,
@@ -527,75 +569,75 @@ export default class Weight extends React.Component<IWeightProps, IState> {
k3.deltaYPos,
k3.deltaXVel,
k3.deltaYVel,
- timestepSize
+ this.props.timestepSize
);
xVel +=
- ((timestepSize * 1.0) / 6.0) *
+ ((this.props.timestepSize * 1.0) / 6.0) *
(k1.deltaXVel + 2 * (k2.deltaXVel + k3.deltaXVel) + k4.deltaXVel);
yVel +=
- ((timestepSize * 1.0) / 6.0) *
+ ((this.props.timestepSize * 1.0) / 6.0) *
(k1.deltaYVel + 2 * (k2.deltaYVel + k3.deltaYVel) + k4.deltaYVel);
xPos +=
- ((timestepSize * 1.0) / 6.0) *
+ ((this.props.timestepSize * 1.0) / 6.0) *
(k1.deltaXPos + 2 * (k2.deltaXPos + k3.deltaXPos) + k4.deltaXPos);
yPos +=
- ((timestepSize * 1.0) / 6.0) *
+ ((this.props.timestepSize * 1.0) / 6.0) *
(k1.deltaYPos + 2 * (k2.deltaYPos + k3.deltaYPos) + k4.deltaYPos);
}
// make sure harmonic motion maintained and errors don't propagate
if (this.props.dataDoc['simulationType'] == "Spring") {
- if (startYVel < 0 && yVel > 0 && yPos < springRestLength) {
+ if (startYVel < 0 && yVel > 0 && yPos < this.props.springRestLength) {
let equilibriumPos =
- springRestLength + (mass * Math.abs(gravity)) / springConstant;
- let amplitude = Math.abs(equilibriumPos - springStartLength);
+ this.props.springRestLength + (this.props.mass * Math.abs(this.props.gravity)) / this.props.springConstant;
+ let amplitude = Math.abs(equilibriumPos - this.props.springStartLength);
yPos = equilibriumPos - amplitude;
- } else if (startYVel > 0 && yVel < 0 && yPos > springRestLength) {
+ } else if (startYVel > 0 && yVel < 0 && yPos > this.props.springRestLength) {
let equilibriumPos =
- springRestLength + (mass * Math.abs(gravity)) / springConstant;
- let amplitude = Math.abs(equilibriumPos - springStartLength);
+ this.props.springRestLength + (this.props.mass * Math.abs(this.props.gravity)) / this.props.springConstant;
+ let amplitude = Math.abs(equilibriumPos - this.props.springStartLength);
yPos = equilibriumPos + amplitude;
}
}
if (this.props.dataDoc['simulationType'] == "Pendulum") {
- let startX = updatedStartPosX;
+ let startX = this.state.updatedStartPosX;
if (startXVel <= 0 && xVel > 0) {
- xPos = updatedStartPosX;
- if (updatedStartPosX > xMax / 2) {
- xPos = xMax / 2 + (xMax / 2 - startX) - 2 * radius;
+ xPos = this.state.updatedStartPosX;
+ if (this.state.updatedStartPosX > this.props.xMax / 2) {
+ xPos = this.props.xMax / 2 + (this.props.xMax / 2 - startX) - 2 * this.props.radius;
}
- yPos = startPosY;
+ yPos = this.props.startPosY;
} else if (startXVel >= 0 && xVel < 0) {
- xPos = updatedStartPosX;
- if (updatedStartPosX < xMax / 2) {
- xPos = xMax / 2 + (xMax / 2 - startX) - 2 * radius;
+ xPos = this.state.updatedStartPosX;
+ if (this.state.updatedStartPosX < this.props.xMax / 2) {
+ xPos = this.props.xMax / 2 + (this.props.xMax / 2 - startX) - 2 * this.props.radius;
}
- yPos = startPosY;
+ yPos = this.props.startPosY;
}
}
if (this.props.dataDoc['simulationType'] == "One Weight") {
- if (yPos < maxPosYConservation) {
- yPos = maxPosYConservation;
+ if (yPos < this.state.maxPosYConservation) {
+ yPos = this.state.maxPosYConservation;
}
}
- setXVelocity(xVel);
- setYVelocity(yVel);
- setXPosition(xPos);
- setYPosition(yPos);
- let forcesn = updatedForces;
+ this.setState({xVelocity: xVel});
+ this.setState({yVelocity: yVel});
+ this.setState({xPosition: xPos});
+ this.setState({yPosition: yPos});
+ let forcesn = this.props.dataDoc['updatedForces']
if (this.props.dataDoc['simulationType'] == "Pendulum") {
- forcesn = getNewPendulumForces(xPos, yPos, xVel, yVel);
+ forcesn = this.getNewPendulumForces(xPos, yPos, xVel, yVel);
} else if (this.props.dataDoc['simulationType'] == "Spring") {
- forcesn = getNewSpringForces(yPos);
+ forcesn = this.getNewSpringForces(yPos);
} else if (this.props.dataDoc['simulationType'] == "Circular Motion") {
- forcesn = getNewCircularMotionForces(xPos, yPos);
+ forcesn = this.getNewCircularMotionForces(xPos, yPos);
}
- setUpdatedForces(forcesn);
+ this.props.dataDoc['updatedForces'] = (forcesn);
// set component forces if they change
if (this.props.dataDoc['simulationType'] == "Pendulum") {
- let x = xMax / 2 - xPos - radius;
- let y = yPos + radius + 5;
+ let x = this.props.xMax / 2 - xPos - this.props.radius;
+ let y = yPos + this.props.radius + 5;
let angle = (Math.atan(y / x) * 180) / Math.PI;
if (angle < 0) {
angle += 180;
@@ -608,8 +650,8 @@ export default class Weight extends React.Component<IWeightProps, IState> {
const pendulumLength = Math.sqrt(x * x + y * y);
const mag =
- mass * Math.abs(gravity) * Math.cos((oppositeAngle * Math.PI) / 180) +
- (mass * (xVel * xVel + yVel * yVel)) / pendulumLength;
+ this.props.mass * Math.abs(this.props.gravity) * Math.cos((oppositeAngle * Math.PI) / 180) +
+ (this.props.mass * (xVel * xVel + yVel * yVel)) / pendulumLength;
const tensionComponent: IForce = {
description: "Tension",
@@ -619,23 +661,23 @@ export default class Weight extends React.Component<IWeightProps, IState> {
};
const gravityParallel: IForce = {
description: "Gravity Parallel Component",
- magnitude: Math.abs(gravity) * Math.cos(((90 - angle) * Math.PI) / 180),
+ magnitude: Math.abs(this.props.gravity) * Math.cos(((90 - angle) * Math.PI) / 180),
directionInDegrees: 270 - (90 - angle),
component: true,
};
const gravityPerpendicular: IForce = {
description: "Gravity Perpendicular Component",
- magnitude: Math.abs(gravity) * Math.sin(((90 - angle) * Math.PI) / 180),
+ magnitude: Math.abs(this.props.gravity) * Math.sin(((90 - angle) * Math.PI) / 180),
directionInDegrees: -(90 - angle),
component: true,
};
- if (Math.abs(gravity) * Math.sin(((90 - angle) * Math.PI) / 180) < 0) {
+ if (Math.abs(this.props.gravity) * Math.sin(((90 - angle) * Math.PI) / 180) < 0) {
gravityPerpendicular.magnitude = Math.abs(
- Math.abs(gravity) * Math.sin(((90 - angle) * Math.PI) / 180)
+ Math.abs(this.props.gravity) * Math.sin(((90 - angle) * Math.PI) / 180)
);
gravityPerpendicular.directionInDegrees = 180 - (90 - angle);
}
- setComponentForces([
+ this.props.dataDoc['componentForces'] = ([
tensionComponent,
gravityParallel,
gravityPerpendicular,
@@ -643,57 +685,8 @@ export default class Weight extends React.Component<IWeightProps, IState> {
}
};
- // Change pendulum angle based on input field
- useEffect(() => {
- let length = adjustPendulumAngle.length;
- const x =
- length * Math.cos(((90 - adjustPendulumAngle.angle) * Math.PI) / 180);
- const y =
- length * Math.sin(((90 - adjustPendulumAngle.angle) * Math.PI) / 180);
- const xPos = xMax / 2 - x - radius;
- const yPos = y - radius - 5;
- setXPosition(xPos);
- setYPosition(yPos);
- setUpdatedStartPosX(xPos);
- setUpdatedStartPosY(yPos);
- setPendulumAngle(adjustPendulumAngle.angle);
- setPendulumLength(adjustPendulumAngle.length);
- }, [adjustPendulumAngle]);
-
- // When display values updated by user, update real values
- useEffect(() => {
- if (updateDisplay.xDisplay != xPosition) {
- let x = updateDisplay.xDisplay;
- x = Math.max(0, x);
- x = Math.min(x, xMax - 2 * radius);
- setUpdatedStartPosX(x);
- setXPosition(x);
- setDisplayXPosition(x);
- }
-
- if (updateDisplay.yDisplay != getDisplayYPos(yPosition)) {
- let y = updateDisplay.yDisplay;
- y = Math.max(0, y);
- y = Math.min(y, yMax - 2 * radius);
- setDisplayYPosition(y);
- let coordinatePosition = getYPosFromDisplay(y);
- setUpdatedStartPosY(coordinatePosition);
- setYPosition(coordinatePosition);
- }
-
- if (displayXVelocity != xVelocity) {
- let x = displayXVelocity;
- setXVelocity(x);
- setDisplayXVelocity(x);
- }
-
- if (displayYVelocity != -yVelocity) {
- let y = displayYVelocity;
- setYVelocity(-y);
- setDisplayYVelocity(y);
- }
- }, [updateDisplay]);
+ // TODO
// Prevent bug when switching between sims
useEffect(() => {
setXVelocity(startVelX);
@@ -843,16 +836,16 @@ export default class Weight extends React.Component<IWeightProps, IState> {
component: false,
};
if (coefficientOfKineticFriction != 0) {
- setUpdatedForces([gravityForce, normalForce, frictionForce]);
- setComponentForces([
+ this.props.dataDoc['updatedForces'] = ([gravityForce, normalForce, frictionForce]);
+ this.props.dataDoc['componentForces'] = ([
frictionForceComponent,
normalForceComponent,
gravityParallel,
gravityPerpendicular,
]);
} else {
- setUpdatedForces([gravityForce, normalForce]);
- setComponentForces([
+ this.props.dataDoc['updatedForces'] = ([gravityForce, normalForce]);
+ this.props.dataDoc['componentForces'] = ([
normalForceComponent,
gravityParallel,
gravityPerpendicular,
@@ -1020,7 +1013,7 @@ export default class Weight extends React.Component<IWeightProps, IState> {
directionInDegrees: 270,
component: false,
};
- setUpdatedForces([tensionForce1, tensionForce2, grav]);
+ this.props.dataDoc['updatedForces'] = ([tensionForce1, tensionForce2, grav]);
}
}
}}