From 2c7c450f646dff3ec771f10f0fe323ae761670aa Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 23 May 2023 14:57:38 -0400 Subject: more phys cleanup --- .../nodes/PhysicsBox/PhysicsSimulationBox.tsx | 660 +++++++++++---------- .../nodes/PhysicsBox/PhysicsSimulationWeight.tsx | 137 ++--- 2 files changed, 385 insertions(+), 412 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx index 35e9c189f..fa47a218b 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx @@ -86,6 +86,78 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { + setupSimulation = () => { + const simulationType = this.simulationType; + const mode = this.simulationMode; this.dataDoc.simulation_paused = true; if (simulationType != 'Circular Motion') { this.dataDoc.mass1_velocityXstart = 0; @@ -180,7 +231,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { + updateForcesWithFriction = (coefficient: number, width = this.wedgeWidth, height = this.wedgeHeight) => { const normalForce: IForce = { description: 'Normal Force', - magnitude: Math.abs(this.gravity) * Math.cos(Math.atan(height / width)) * NumCast(this.dataDoc.mass1), + magnitude: Math.abs(this.gravity) * Math.cos(Math.atan(height / width)) * this.mass1, directionInDegrees: 180 - 90 - (Math.atan(height / width) * 180) / Math.PI, component: false, }; let frictionForce: IForce = { description: 'Static Friction Force', - magnitude: coefficient * Math.abs(this.gravity) * Math.cos(Math.atan(height / width)) * NumCast(this.dataDoc.mass1), + magnitude: coefficient * Math.abs(this.gravity) * Math.cos(Math.atan(height / width)) * this.mass1, directionInDegrees: 180 - (Math.atan(height / width) * 180) / Math.PI, component: false, }; // reduce magnitude or friction force if necessary such that block cannot slide up plane - let yForce = -Math.abs(this.gravity) * NumCast(this.dataDoc.mass1); + let yForce = -Math.abs(this.gravity) * this.mass1; 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.gravity) * NumCast(this.dataDoc.mass1)) / Math.sin((frictionForce.directionInDegrees * Math.PI) / 180); + frictionForce.magnitude = (-normalForce.magnitude * Math.sin((normalForce.directionInDegrees * Math.PI) / 180) + Math.abs(this.gravity) * this.mass1) / Math.sin((frictionForce.directionInDegrees * Math.PI) / 180); } const frictionForceComponent: IForce = { description: 'Static Friction Force', @@ -363,19 +403,19 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { - let theta: number = NumCast(this.dataDoc.wedge_angle); + let theta = this.wedgeAngle; let index = this.dataDoc.selectedQuestion.variablesForQuestionSetup.indexOf('theta - max 45'); if (index >= 0) { theta = NumListCast(this.dataDoc.questionVariables)[index]; @@ -472,7 +512,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { const solutions: number[] = []; - let theta: number = NumCast(this.dataDoc.wedge_angle); + let theta = this.wedgeAngle; let index = question.variablesForQuestionSetup.indexOf('theta - max 45'); if (index >= 0) { theta = questionVars[index]; @@ -549,7 +589,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent epsilon) { + if (Math.abs(this.wedgeAngle - this.dataDoc.selectedSolutions[i]) > epsilon) { error = true; } } @@ -596,7 +636,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent (this.dataDoc.paused = true); componentForces1 = () => PhysicsSimulationBox.parseJSON(StrCast(this.dataDoc.mass1_componentForces)); setComponentForces1 = (forces: IForce[]) => (this.dataDoc.mass1_componentForces = JSON.stringify(forces)); componentForces2 = () => PhysicsSimulationBox.parseJSON(StrCast(this.dataDoc.mass2_componentForces)); @@ -859,8 +897,76 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent (this.dataDoc.mass1_forcesUpdated = JSON.stringify(forces)); forcesUpdated2 = () => PhysicsSimulationBox.parseJSON(StrCast(this.dataDoc.mass2_forcesUpdated)); setForcesUpdated2 = (forces: IForce[]) => (this.dataDoc.mass2_forcesUpdated = JSON.stringify(forces)); - + setPosition1 = (xPos: number | undefined, yPos: number | undefined) => { + yPos !== undefined && (this.dataDoc.mass1_positionY = Math.round(yPos * 100) / 100); + xPos !== undefined && (this.dataDoc.mass1_positionX = Math.round(xPos * 100) / 100); + }; + setPosition2 = (xPos: number | undefined, yPos: number | undefined) => { + yPos !== undefined && (this.dataDoc.mass2_positionY = Math.round(yPos * 100) / 100); + xPos !== undefined && (this.dataDoc.mass2_positionX = Math.round(xPos * 100) / 100); + }; + setVelocity1 = (xVel: number | undefined, yVel: number | undefined) => { + yVel !== undefined && (this.dataDoc.mass1_velocityY = (-1 * Math.round(yVel * 100)) / 100); + xVel !== undefined && (this.dataDoc.mass1_velocityX = Math.round(xVel * 100) / 100); + }; + setVelocity2 = (xVel: number | undefined, yVel: number | undefined) => { + yVel !== undefined && (this.dataDoc.mass2_velocityY = (-1 * Math.round(yVel * 100)) / 100); + xVel !== undefined && (this.dataDoc.mass2_velocityX = Math.round(xVel * 100) / 100); + }; + setAcceleration1 = (xAccel: number, yAccel: number) => { + this.dataDoc.mass1_accelerationY = yAccel; + this.dataDoc.mass1_accelerationX = xAccel; + }; + setAcceleration2 = (xAccel: number, yAccel: number) => { + this.dataDoc.mass2_accelerationY = yAccel; + this.dataDoc.mass2_accelerationX = xAccel; + }; + setPendulumAngle = (angle: number | undefined, length: number | undefined) => { + angle !== undefined && (this.dataDoc.pendulum_angle = angle); + length !== undefined && (this.dataDoc.pendulum_length = length); + }; + setSpringLength = (length: number) => { + this.dataDoc.spring_lengthStart = length; + }; render() { + const commonWeightProps = { + pause: this.pause, + paused: BoolCast(this.dataDoc.simulation_paused), + panelWidth: this.layoutDoc[WidthSym], + panelHeight: this.layoutDoc[HeightSym], + xMax: this.xMax, + xMin: this.xMin, + yMax: this.yMax, + yMin: this.yMin, + wallPositions: this.wallPositions, + gravity: this.gravity, + timestepSize: 0.05, + showComponentForces: BoolCast(this.dataDoc.simulation_showComponentForces), + coefficientOfKineticFriction: NumCast(this.dataDoc.coefficientOfKineticFriction), + elasticCollisions: BoolCast(this.dataDoc.elasticCollisions), + simulationMode: this.simulationMode, + noMovement: BoolCast(this.dataDoc.noMovement), + circularMotionRadius: this.circularMotionRadius, + wedgeHeight: this.wedgeHeight, + wedgeWidth: this.wedgeWidth, + springConstant: this.springConstant, + springStartLength: this.springLengthStart, + springRestLength: this.springLengthRest, + setSpringLength: this.setSpringLength, + setPendulumAngle: this.setPendulumAngle, + pendulumAngle: this.pendulumAngle, + pendulumLength: this.pendulumLength, + startPendulumAngle: this.pendulumAngleStart, + startPendulumLength: this.pendulumLengthStart, + radius: 0.08 * this.layoutDoc[HeightSym](), + reset: BoolCast(this.dataDoc.simulation_reset), + simulationSpeed: NumCast(this.dataDoc.simulation_speed), + showAcceleration: BoolCast(this.dataDoc.simulation_showAcceleration), + showForceMagnitudes: BoolCast(this.dataDoc.simulation_showForceMagnitudes), + showForces: BoolCast(this.dataDoc.simulation_showForces), + showVelocity: BoolCast(this.dataDoc.simulation_showVelocity), + simulationType: this.simulationType, + }; return (
@@ -881,153 +987,81 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
- {this.dataDoc.simulation_type == 'Pulley' && ( + {this.simulationType == 'Pulley' && ( )}
- {(this.dataDoc.simulation_type == 'One Weight' || this.dataDoc.simulation_type == 'Inclined Plane') && - this.wallPositions && - this.wallPositions.map((element, index) => { - return ; - })} + {(this.simulationType == 'One Weight' || this.simulationType == 'Inclined Plane') && + this.wallPositions?.map((element, index) => )}
- {this.dataDoc.simulation_paused && this.dataDoc.simulation_mode != 'Tutorial' && ( - { - this.dataDoc.simulation_paused = false; - }}> + {this.dataDoc.simulation_paused && this.simulationMode != 'Tutorial' && ( + (this.dataDoc.simulation_paused = false)}> )} - {!this.dataDoc.simulation_paused && this.dataDoc.simulation_mode != 'Tutorial' && ( - { - this.dataDoc.simulation_paused = true; - }}> + {!this.dataDoc.simulation_paused && this.simulationMode != 'Tutorial' && ( + (this.dataDoc.simulation_paused = true)}> )} - {this.dataDoc.simulation_paused && this.dataDoc.simulation_mode != 'Tutorial' && ( - { - this.dataDoc.simulation_reset = !this.dataDoc.simulation_reset; - }}> + {this.dataDoc.simulation_paused && this.simulationMode != 'Tutorial' && ( + (this.dataDoc.simulation_reset = !this.dataDoc.simulation_reset)}> )}
{ this.dataDoc.simulation_mode = event.target.value; - this.setupSimulation(StrCast(this.dataDoc.simulation_type), event.target.value); + this.setupSimulation(); }} style={{ height: '2em', width: '100%', fontSize: '16px' }}> @@ -1053,21 +1087,19 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
- {this.dataDoc.simulation_mode == 'Review' && this.dataDoc.simulation_type != 'Inclined Plane' && ( + {this.simulationMode == 'Review' && this.simulationType != 'Inclined Plane' && (

- <>{this.dataDoc.simulation_type} review problems in progress! + <>{this.simulationType} review problems in progress!


)} - {this.dataDoc.simulation_mode == 'Review' && this.dataDoc.simulation_type == 'Inclined Plane' && ( + {this.simulationMode == 'Review' && this.simulationType == 'Inclined Plane' && (
{!this.dataDoc.hintDialogueOpen && ( { - this.dataDoc.hintDialogueOpen = true; - }} + onClick={() => (this.dataDoc.hintDialogueOpen = true)} sx={{ position: 'fixed', left: this.xMax - 50 + 'px', @@ -1079,30 +1111,23 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent (this.dataDoc.hintDialogueOpen = false)}> Hints - {this.dataDoc.selectedQuestion.hints?.map((hint: any, index: number) => { - return ( -
- -
- - - Hint {index + 1}: {hint.description} - - - {hint.content} -
-
-
- ); - })} + {this.dataDoc.selectedQuestion.hints?.map((hint: any, index: number) => ( +
+ +
+ + + Hint {index + 1}: {hint.description} + + + {hint.content} +
+
+
+ ))}
- +
@@ -1232,7 +1257,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { this.changeWedgeBasedOnNewAngle(val); this.updateReviewForcesBasedOnAngle(val); @@ -1246,7 +1271,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)} - {this.dataDoc.simulation_mode == 'Tutorial' && ( + {this.simulationMode == 'Tutorial' && (

Problem

@@ -1292,8 +1317,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
- {(this.dataDoc.simulation_type == 'One Weight' || this.dataDoc.simulation_type == 'Inclined Plane' || this.dataDoc.simulation_type == 'Pendulum') &&

Resources

} - {this.dataDoc.simulation_type == 'One Weight' && ( + {(this.simulationType == 'One Weight' || this.simulationType == 'Inclined Plane' || this.simulationType == 'Pendulum') &&

Resources

} + {this.simulationType == 'One Weight' && ( )} - {this.dataDoc.simulation_type == 'Inclined Plane' && ( + {this.simulationType == 'Inclined Plane' && ( )} - {this.dataDoc.simulation_type == 'Pendulum' && ( + {this.simulationType == 'Pendulum' && (
)} - {this.dataDoc.simulation_mode == 'Review' && this.dataDoc.simulation_type == 'Inclined Plane' && ( + {this.simulationMode == 'Review' && this.simulationType == 'Inclined Plane' && (
)} - {this.dataDoc.simulation_mode == 'Freeform' && ( + {this.simulationMode == 'Freeform' && (
- {this.dataDoc.simulation_type == 'One Weight' && ( + {this.simulationType == 'One Weight' && ( (this.dataDoc.elasticCollisions = !this.dataDoc.elasticCollisions)} />} label="Make collisions elastic" @@ -1422,7 +1447,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent - {(this.dataDoc.simulation_type == 'Inclined Plane' || this.dataDoc.simulation_type == 'Pendulum') && ( + {(this.simulationType == 'Inclined Plane' || this.simulationType == 'Pendulum') && ( (this.dataDoc.simulation_showComponentForces = !this.dataDoc.simulation_showComponentForces)} />} label="Show component force vectors" @@ -1440,7 +1465,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent Speed} lowerBound={1} dataDoc={this.dataDoc} prop="simulation_speed" step={1} unit={'x'} upperBound={10} value={NumCast(this.dataDoc.simulation_speed, 2)} labelWidth={'5em'} /> - {this.dataDoc.simulation_paused && this.dataDoc.simulation_type != 'Circular Motion' && ( + {this.dataDoc.simulation_paused && this.simulationType != 'Circular Motion' && ( Gravity} lowerBound={-30} @@ -1450,13 +1475,11 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { - this.setupSimulation(StrCast(this.dataDoc.simulation_type), StrCast(this.dataDoc.simulation_mode)); - }} + effect={(val: number) => this.setupSimulation()} labelWidth={'5em'} /> )} - {this.dataDoc.simulation_paused && this.dataDoc.simulation_type != 'Pulley' && ( + {this.dataDoc.simulation_paused && this.simulationType != 'Pulley' && ( Mass} lowerBound={1} @@ -1465,14 +1488,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { - this.setupSimulation(StrCast(this.dataDoc.simulation_type), StrCast(this.dataDoc.simulation_mode)); - }} + value={this.mass1 ?? 1} + effect={(val: number) => this.setupSimulation()} labelWidth={'5em'} /> )} - {this.dataDoc.simulation_paused && this.dataDoc.simulation_type == 'Pulley' && ( + {this.dataDoc.simulation_paused && this.simulationType == 'Pulley' && ( Red mass} lowerBound={1} @@ -1481,14 +1502,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { - this.setupSimulation(StrCast(this.dataDoc.simulation_type), StrCast(this.dataDoc.simulation_mode)); - }} + value={this.mass1 ?? 1} + effect={(val: number) => this.setupSimulation()} labelWidth={'5em'} /> )} - {this.dataDoc.simulation_paused && this.dataDoc.simulation_type == 'Pulley' && ( + {this.dataDoc.simulation_paused && this.simulationType == 'Pulley' && ( Blue mass} lowerBound={1} @@ -1497,14 +1516,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { - this.setupSimulation(StrCast(this.dataDoc.simulation_type), StrCast(this.dataDoc.simulation_mode)); - }} + value={this.mass2 ?? 1} + effect={(val: number) => this.setupSimulation()} labelWidth={'5em'} /> )} - {this.dataDoc.simulation_paused && this.dataDoc.simulation_type == 'Circular Motion' && ( + {this.dataDoc.simulation_paused && this.simulationType == 'Circular Motion' && ( Rod length} lowerBound={100} @@ -1514,15 +1531,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { - this.setupSimulation(StrCast(this.dataDoc.simulation_type), StrCast(this.dataDoc.simulation_mode)); - }} + effect={(val: number) => this.setupSimulation()} labelWidth={'5em'} /> )} - {this.dataDoc.simulation_type == 'Spring' && this.dataDoc.simulation_paused && ( + {this.simulationType == 'Spring' && this.dataDoc.simulation_paused && (
Spring stiffness} @@ -1532,10 +1547,8 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { - this.dataDoc.simulation_reset = !this.dataDoc.simulation_reset; - }} + value={this.springConstant} + effect={(val: number) => (this.dataDoc.simulation_reset = !this.dataDoc.simulation_reset)} radianEquivalent={false} mode={'Freeform'} labelWidth={'7em'} @@ -1546,37 +1559,35 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { - this.dataDoc.simulation_reset = !this.dataDoc.simulation_reset; - }} + value={this.springLengthRest} + effect={(val: number) => (this.dataDoc.simulation_reset = !this.dataDoc.simulation_reset)} radianEquivalent={false} - mode={'Freeform'} + mode="Freeform" labelWidth={'7em'} /> Starting displacement} - lowerBound={-(NumCast(this.dataDoc.spring_lengthRest) - 10)} + lowerBound={-(this.springLengthRest - 10)} dataDoc={this.dataDoc} prop="" step={10} - unit={''} - upperBound={NumCast(this.dataDoc.spring_lengthRest)} - value={NumCast(this.dataDoc.spring_lengthStart) - NumCast(this.dataDoc.spring_lengthRest)} + unit="" + upperBound={this.springLengthRest} + value={this.springLengthStart - this.springLengthRest} effect={(val: number) => { - this.dataDoc.mass1_positionYstart = NumCast(this.dataDoc.spring_lengthRest) + val; - this.dataDoc.spring_lengthStart = NumCast(this.dataDoc.spring_lengthRest) + val; + this.dataDoc.mass1_positionYstart = this.springLengthRest + val; + this.dataDoc.spring_lengthStart = this.springLengthRest + val; this.dataDoc.simulation_reset = !this.dataDoc.simulation_reset; }} radianEquivalent={false} - mode={'Freeform'} + mode="Freeform" labelWidth={'7em'} />
)} - {this.dataDoc.simulation_type == 'Inclined Plane' && this.dataDoc.simulation_paused && ( + {this.simulationType == 'Inclined Plane' && this.dataDoc.simulation_paused && (
θ} @@ -1586,7 +1597,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { this.changeWedgeBasedOnNewAngle(val); this.dataDoc.simulation_reset = !this.dataDoc.simulation_reset; @@ -1639,10 +1650,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)} - {this.dataDoc.simulation_type == 'Inclined Plane' && !this.dataDoc.simulation_paused && ( + {this.simulationType == 'Inclined Plane' && !this.dataDoc.simulation_paused && ( <> - θ: {Math.round(NumCast(this.dataDoc.wedge_angle) * 100) / 100}° ≈ {Math.round(((NumCast(this.dataDoc.wedge_angle) * Math.PI) / 180) * 100) / 100} rad + θ: {Math.round(this.wedgeAngle * 100) / 100}° ≈ {Math.round(((this.wedgeAngle * Math.PI) / 180) * 100) / 100} rad
μ s: {this.dataDoc.coefficientOfStaticFriction}
@@ -1650,12 +1661,12 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)} - {this.dataDoc.simulation_type == 'Pendulum' && !this.dataDoc.simulation_paused && ( + {this.simulationType == 'Pendulum' && !this.dataDoc.simulation_paused && ( - θ: {Math.round(NumCast(this.dataDoc.pendulum_angle) * 100) / 100}° ≈ {Math.round(((NumCast(this.dataDoc.pendulum_angle) * Math.PI) / 180) * 100) / 100} rad + θ: {Math.round(this.pendulumAngle * 100) / 100}° ≈ {Math.round(((this.pendulumAngle * Math.PI) / 180) * 100) / 100} rad )} - {this.dataDoc.simulation_type == 'Pendulum' && this.dataDoc.simulation_paused && ( + {this.simulationType == 'Pendulum' && this.dataDoc.simulation_paused && (
Angle} @@ -1668,8 +1679,9 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { this.dataDoc.pendulum_angleStart = value; - if (this.dataDoc.simulation_type == 'Pendulum') { - const mag = NumCast(this.dataDoc.mass1) * Math.abs(this.gravity) * Math.cos((value * Math.PI) / 180); + this.dataDoc.pendulum_lengthStart = this.dataDoc.pendulum_length; + if (this.simulationType == 'Pendulum') { + const mag = this.mass1 * Math.abs(this.gravity) * Math.cos((value * Math.PI) / 180); const forceOfTension: IForce = { description: 'Tension', @@ -1697,7 +1709,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent Rod length} @@ -1739,30 +1749,30 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent { - if (this.dataDoc.simulation_type == 'Pendulum') { - this.dataDoc.pendulum_angle_adjust = NumCast(this.dataDoc.pendulum_angle); - this.dataDoc.pendulum_length_adjust = value; + if (this.simulationType == 'Pendulum') { + this.dataDoc.pendulum_angleStart = this.pendulumAngle; + this.dataDoc.pendulum_lengthStart = value; this.dataDoc.simulation_reset = !this.dataDoc.simulation_reset; } }} radianEquivalent={false} - mode={'Freeform'} - labelWidth={'5em'} + mode="Freeform" + labelWidth="5em" />
)}
)}
- {this.dataDoc.simulation_mode == 'Freeform' && ( + {this.simulationMode == 'Freeform' && ( - + @@ -1777,27 +1787,27 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent Position - {(!this.dataDoc.simulation_paused || this.dataDoc.simulation_type == 'Inclined Plane' || this.dataDoc.simulation_type == 'Circular Motion' || this.dataDoc.simulation_type == 'Pulley') && ( + {(!this.dataDoc.simulation_paused || this.simulationType == 'Inclined Plane' || this.simulationType == 'Circular Motion' || this.simulationType == 'Pulley') && ( )}{' '} - {this.dataDoc.simulation_paused && this.dataDoc.simulation_type != 'Inclined Plane' && this.dataDoc.simulation_type != 'Circular Motion' && this.dataDoc.simulation_type != 'Pulley' && ( + {this.dataDoc.simulation_paused && this.simulationType != 'Inclined Plane' && this.simulationType != 'Circular Motion' && this.simulationType != 'Pulley' && ( )}{' '} - {(!this.dataDoc.simulation_paused || this.dataDoc.simulation_type == 'Inclined Plane' || this.dataDoc.simulation_type == 'Circular Motion' || this.dataDoc.simulation_type == 'Pulley') && ( + {(!this.dataDoc.simulation_paused || this.simulationType == 'Inclined Plane' || this.simulationType == 'Circular Motion' || this.simulationType == 'Pulley') && ( )}{' '} - {this.dataDoc.simulation_paused && this.dataDoc.simulation_type != 'Inclined Plane' && this.dataDoc.simulation_type != 'Circular Motion' && this.dataDoc.simulation_type != 'Pulley' && ( + {this.dataDoc.simulation_paused && this.simulationType != 'Inclined Plane' && this.simulationType != 'Circular Motion' && this.simulationType != 'Pulley' && ( )}{' '} @@ -1903,10 +1913,10 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent Velocity - {(!this.dataDoc.simulation_paused || (this.dataDoc.simulation_type != 'One Weight' && this.dataDoc.simulation_type != 'Circular Motion')) && ( + {(!this.dataDoc.simulation_paused || (this.simulationType != 'One Weight' && this.simulationType != 'Circular Motion')) && ( )}{' '} - {this.dataDoc.simulation_paused && (this.dataDoc.simulation_type == 'One Weight' || this.dataDoc.simulation_type == 'Circular Motion') && ( + {this.dataDoc.simulation_paused && (this.simulationType == 'One Weight' || this.simulationType == 'Circular Motion') && ( )}{' '} - {(!this.dataDoc.simulation_paused || this.dataDoc.simulation_type != 'One Weight') && ( + {(!this.dataDoc.simulation_paused || this.simulationType != 'One Weight') && ( )}{' '} - {this.dataDoc.simulation_paused && this.dataDoc.simulation_type == 'One Weight' && ( + {this.dataDoc.simulation_paused && this.simulationType == 'One Weight' && ( )}{' '} @@ -1981,13 +1991,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent Momentum - - + +
{this.dataDoc.simulation_type == 'Pulley' ? 'Red Weight' : ''}{this.simulationType == 'Pulley' ? 'Red Weight' : ''} X Y
<>{this.dataDoc.mass1_positionX} m { this.dataDoc.mass1_xChange = value; - if (this.dataDoc.simulation_type == 'Suspension') { + if (this.simulationType == 'Suspension') { let x1rod = (this.xMax + this.xMin) / 2 - this.radius - this.yMin - 200; let x2rod = (this.xMax + this.xMin) / 2 + this.yMin + 200 + this.radius; let deltaX1 = value + this.radius - x1rod; @@ -1805,7 +1815,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent {`${NumCast(this.dataDoc.mass1_positionY)} m`} { this.dataDoc.mass1_yChange = value; - if (this.dataDoc.simulation_type == 'Suspension') { + if (this.simulationType == 'Suspension') { let x1rod = (this.xMax + this.xMin) / 2 - this.radius - this.yMin - 200; let x2rod = (this.xMax + this.xMin) / 2 + this.yMin + 200 + this.radius; let deltaX1 = NumCast(this.dataDoc.mass1_positionX) + this.radius - x1rod; @@ -1861,7 +1871,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent {`${NumCast(this.dataDoc.mass1_velocityX)} m/s`} <>{this.dataDoc.mass1_velocityY} m/s { this.dataDoc.mass1_velocityYstart = -value; }} small={true} - mode={'Freeform'} + mode="Freeform" /> {Math.round(NumCast(this.dataDoc.mass1_velocityX) * NumCast(this.dataDoc.mass1) * 10) / 10} kg*m/s{Math.round(NumCast(this.dataDoc.mass1_velocityY) * NumCast(this.dataDoc.mass1) * 10) / 10} kg*m/s{Math.round(NumCast(this.dataDoc.mass1_velocityX) * this.mass1 * 10) / 10} kg*m/s{Math.round(NumCast(this.dataDoc.mass1_velocityY) * this.mass1 * 10) / 10} kg*m/s
)} - {this.dataDoc.simulation_mode == 'Freeform' && this.dataDoc.simulation_type == 'Pulley' && ( + {this.simulationMode == 'Freeform' && this.simulationType == 'Pulley' && ( @@ -2028,14 +2038,14 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent Momentum - - + +
{Math.round(NumCast(this.dataDoc.mass2_velocityX) * NumCast(this.dataDoc.mass1) * 10) / 10} kg*m/s{Math.round(NumCast(this.dataDoc.mass2_velocityY) * NumCast(this.dataDoc.mass1) * 10) / 10} kg*m/s{Math.round(NumCast(this.dataDoc.mass2_velocityX) * this.mass1 * 10) / 10} kg*m/s{Math.round(NumCast(this.dataDoc.mass2_velocityY) * this.mass1 * 10) / 10} kg*m/s
)}
- {this.dataDoc.simulation_type != 'Pendulum' && this.dataDoc.simulation_type != 'Spring' && ( + {this.simulationType != 'Pendulum' && this.simulationType != 'Spring' && (

Kinematic Equations

    @@ -2052,7 +2062,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)} - {this.dataDoc.simulation_type == 'Spring' && ( + {this.simulationType == 'Spring' && (

Harmonic Motion Equations: Spring

    @@ -2081,7 +2091,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent
)} - {this.dataDoc.simulation_type == 'Pendulum' && ( + {this.simulationType == 'Pendulum' && (

Harmonic Motion Equations: Pendulum

    @@ -2116,7 +2126,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent - {this.dataDoc.simulation_type == 'Circular Motion' ? 'Z' : 'Y'} + {this.simulationType == 'Circular Motion' ? 'Z' : 'Y'}

    void; + panelWidth: () => number; + panelHeight: () => number; circularMotionRadius: number; coefficientOfKineticFriction: number; color: string; @@ -50,6 +48,7 @@ export interface IWeightProps { springStartLength: number; startForces: () => IForce[]; startPendulumAngle: number; + startPendulumLength: number; startPosX: number; startPosY: number; startVelX: number; @@ -59,6 +58,11 @@ export interface IWeightProps { updateMassPosY: number; forcesUpdated: () => IForce[]; setForcesUpdated: (x: IForce[]) => {}; + setPosition: (x: number | undefined, y: number | undefined) => void; + setVelocity: (x: number | undefined, y: number | undefined) => void; + setAcceleration: (x: number, y: number) => void; + setPendulumAngle: (ang: number | undefined, length: number | undefined) => void; + setSpringLength: (length: number) => void; wallPositions: IWallProps[]; wedgeHeight: number; wedgeWidth: number; @@ -147,43 +151,15 @@ export default class Weight extends React.Component { // Helper function to go between display and real values getDisplayYPos = (yPos: number) => this.props.yMax - yPos - 2 * this.props.radius + 5; - // Set display values based on real values - setPosition = (xPos: number | undefined, yPos: number | undefined) => { - if (this.props.color == 'red') { - yPos !== undefined && (this.props.dataDoc.mass1_positionY = Math.round(this.getDisplayYPos(yPos) * 100) / 100); - xPos !== undefined && (this.props.dataDoc.mass1_positionX = Math.round(xPos * 100) / 100); - } else { - yPos !== undefined && (this.props.dataDoc.mass2_positionY = Math.round(this.getDisplayYPos(yPos) * 100) / 100); - xPos !== undefined && (this.props.dataDoc.mass2_positionX = Math.round(xPos * 100) / 100); - } - }; - setVelocity = (xVel: number | undefined, yVel: number | undefined) => { - if (this.props.color == 'red') { - yVel !== undefined && (this.props.dataDoc.mass1_velocityY = (-1 * Math.round(yVel * 100)) / 100); - xVel !== undefined && (this.props.dataDoc.mass1_velocityX = Math.round(xVel * 100) / 100); - } else { - yVel !== undefined && (this.props.dataDoc.mass2_velocityY = (-1 * Math.round(yVel * 100)) / 100); - xVel !== undefined && (this.props.dataDoc.mass2_velocityX = Math.round(xVel * 100) / 100); - } - }; - setAcceleration = (xAccel: number, yAccel: number) => { - if (this.props.color == 'red') { - this.props.dataDoc.mass1_accelerationY = yAccel; - this.props.dataDoc.mass1_accelerationX = xAccel; - } else { - this.props.dataDoc.mass2_accelerationY = yAccel; - this.props.dataDoc.mass2_accelerationX = xAccel; - } - - this.setState({ xAccel }); - this.setState({ yAccel }); - }; - // Update display values when simulation updates setDisplayValues = (xPos: number = this.state.xPosition, yPos: number = this.state.yPosition, xVel: number = this.state.xVelocity, yVel: number = this.state.yVelocity) => { - this.setPosition(xPos, yPos); - this.setVelocity(xVel, yVel); - this.setAcceleration(Math.round(this.getNewAccelerationX(this.props.forcesUpdated()) * 100) / 100, (-1 * Math.round(this.getNewAccelerationY(this.props.forcesUpdated()) * 100)) / 100); + this.props.setPosition(xPos, this.getDisplayYPos(yPos)); + this.props.setVelocity(xVel, yVel); + const xAccel = Math.round(this.getNewAccelerationX(this.props.forcesUpdated()) * 100) / 100; + const yAccel = (-1 * Math.round(this.getNewAccelerationY(this.props.forcesUpdated()) * 100)) / 100; + this.props.setAcceleration(xAccel, yAccel); + this.setState({ xAccel }); + this.setState({ yAccel }); }; componentDidUpdate(prevProps: Readonly, prevState: Readonly, snapshot?: any): void { @@ -194,18 +170,17 @@ export default class Weight extends React.Component { } // Change pendulum angle from input field - if (prevProps.adjustPendulumAngle != this.props.adjustPendulumAngle || prevProps.adjustPendulumLength !== this.props.adjustPendulumLength) { - let length = this.props.adjustPendulumLength; - const x = length * Math.cos(((90 - this.props.adjustPendulumAngle) * Math.PI) / 180); - const y = length * Math.sin(((90 - this.props.adjustPendulumAngle) * Math.PI) / 180); + if (prevProps.startPendulumAngle != this.props.startPendulumAngle || prevProps.startPendulumLength !== this.props.startPendulumLength) { + let length = this.props.startPendulumLength; + const x = length * Math.cos(((90 - this.props.startPendulumAngle) * Math.PI) / 180); + const y = length * Math.sin(((90 - this.props.startPendulumAngle) * 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.pendulum_angle = this.props.adjustPendulumAngle; - this.props.dataDoc.pendulum_length = this.props.adjustPendulumLength; + this.props.setPendulumAngle(this.props.startPendulumAngle, this.props.startPendulumLength); } // When display values updated by user, update real value @@ -215,7 +190,7 @@ export default class Weight extends React.Component { x = Math.min(x, this.props.xMax - 2 * this.props.radius); this.setState({ updatedStartPosX: x }); this.setState({ xPosition: x }); - this.setPosition(x, undefined); + this.props.setPosition(x, undefined); } if (prevProps.updateMassPosY != this.props.updateMassPosY) { let y = this.props.updateMassPosY; @@ -224,18 +199,18 @@ export default class Weight extends React.Component { let coordinatePosition = this.getDisplayYPos(y); this.setState({ updatedStartPosY: coordinatePosition }); this.setState({ yPosition: coordinatePosition }); - this.setPosition(undefined, y); + this.props.setPosition(undefined, this.getDisplayYPos(y)); if (this.props.displayXVelocity != this.state.xVelocity) { let x = this.props.displayXVelocity; this.setState({ xVelocity: x }); - this.setVelocity(x, undefined); + this.props.setVelocity(x, undefined); } if (this.props.displayYVelocity != -this.state.yVelocity) { let y = this.props.displayYVelocity; this.setState({ yVelocity: -y }); - this.setVelocity(undefined, y); + this.props.setVelocity(undefined, y); } } @@ -360,7 +335,7 @@ export default class Weight extends React.Component { if (this.props.paused && !isNaN(this.props.startPosX)) { this.setState({ xPosition: this.props.startPosX }); this.setState({ updatedStartPosX: this.props.startPosX }); - this.setPosition(this.props.startPosX, undefined); + this.props.setPosition(this.props.startPosX, undefined); } } @@ -369,7 +344,7 @@ export default class Weight extends React.Component { if (this.props.paused && !isNaN(this.props.startPosY)) { this.setState({ yPosition: this.props.startPosY }); this.setState({ updatedStartPosY: this.props.startPosY ?? 0 }); - this.setPosition(undefined, this.props.startPosY ?? 0); + this.props.setPosition(undefined, this.getDisplayYPos(this.props.startPosY)); } } @@ -410,23 +385,11 @@ export default class Weight extends React.Component { this.setState({ yPosition: this.state.updatedStartPosY }); this.setState({ xVelocity: this.props.startVelX }); this.setState({ yVelocity: this.props.startVelY }); - this.props.dataDoc.pendulum_angle = this.props.startPendulumAngle; + this.props.setPendulumAngle(this.props.startPendulumAngle, undefined); this.props.setForcesUpdated(this.props.startForces()); - if (this.props.color == 'red') { - this.props.dataDoc.mass1_positionX = this.state.updatedStartPosX; - this.props.dataDoc.mass1_positionY = this.state.updatedStartPosY; - this.props.dataDoc.mass1_velocityX = this.props.startVelX; - this.props.dataDoc.mass1_velocityY = this.props.startVelY; - this.props.dataDoc.mass1_accelerationX = 0; - this.props.dataDoc.mass1_accelerationY = 0; - } else { - this.props.dataDoc.mass2_positionX = this.state.updatedStartPosX; - this.props.dataDoc.mass2_positionY = this.state.updatedStartPosY; - this.props.dataDoc.mass2_velocityX = this.props.startVelX; - this.props.dataDoc.mass2_velocityY = this.props.startVelY; - this.props.dataDoc.mass2_accelerationX = 0; - this.props.dataDoc.mass2_accelerationY = 0; - } + this.props.setPosition(this.state.updatedStartPosX, this.state.updatedStartPosY); + this.props.setVelocity(this.props.startVelX, this.props.startVelY); + this.props.setAcceleration(0, 0); this.setState({ angleLabel: Math.round(this.props.pendulumAngle * 100) / 100 }); }; @@ -514,7 +477,7 @@ export default class Weight extends React.Component { } const pendulumLength = Math.sqrt(x * x + y * y); - this.props.dataDoc.pendulum_angle = oppositeAngle; + this.props.setPendulumAngle(oppositeAngle, undefined); const mag = this.props.mass * Math.abs(this.props.gravity) * Math.cos((oppositeAngle * Math.PI) / 180) + (this.props.mass * (xVel * xVel + yVel * yVel)) / pendulumLength; @@ -544,7 +507,7 @@ export default class Weight extends React.Component { if (this.state.xVelocity != 0) { this.state.walls.forEach(wall => { if (wall.angleInDegrees == 90) { - const wallX = (wall.xPos / 100) * this.props.layoutDoc[WidthSym](); + const wallX = (wall.xPos / 100) * this.props.panelWidth(); if (wall.xPos < 0.35) { if (minX <= wallX) { this.setState({ xPosition: wallX + 0.01 }); @@ -580,7 +543,7 @@ export default class Weight extends React.Component { if (this.state.yVelocity > 0) { this.state.walls.forEach(wall => { if (wall.angleInDegrees == 0 && wall.yPos > 0.4) { - const groundY = (wall.yPos / 100) * this.props.layoutDoc[HeightSym](); + const groundY = (wall.yPos / 100) * this.props.panelHeight(); if (maxY > groundY) { this.setState({ yPosition: groundY - 2 * this.props.radius - 0.01 }); if (this.props.elasticCollisions) { @@ -626,7 +589,7 @@ export default class Weight extends React.Component { if (this.state.yVelocity < 0) { this.state.walls.forEach(wall => { if (wall.angleInDegrees == 0 && wall.yPos < 0.4) { - const groundY = (wall.yPos / 100) * this.props.layoutDoc[HeightSym](); + const groundY = (wall.yPos / 100) * this.props.panelHeight(); if (minY < groundY) { this.setState({ yPosition: groundY + 0.01 }); if (this.props.elasticCollisions) { @@ -800,7 +763,7 @@ export default class Weight extends React.Component { className="weightContainer" onPointerDown={e => { if (this.draggable) { - this.props.dataDoc.paused = true; + this.props.pause(); this.setState({ dragging: true }); this.setState({ clickPositionX: e.clientX }); this.setState({ clickPositionY: e.clientY }); @@ -830,10 +793,10 @@ export default class Weight extends React.Component { } this.setState({ yPosition: newY }); - this.props.dataDoc.mass1_positionY = Math.round((this.props.yMax - 2 * this.props.radius - newY + 5) * 100) / 100; + this.props.setPosition(undefined, Math.round((this.props.yMax - 2 * this.props.radius - newY + 5) * 100) / 100); if (this.props.simulationType != 'Pulley') { this.setState({ xPosition: newX }); - this.props.dataDoc.mass1_positionX = newX; + this.props.setPosition(newX, undefined); } if (this.props.simulationType != 'Suspension') { if (this.props.simulationType != 'Pulley') { @@ -866,7 +829,7 @@ export default class Weight extends React.Component { newX = 10; } if (this.props.simulationType == 'Spring') { - this.props.dataDoc.spring_lengthStart = newY; + this.props.setSpringLength(newY); } if (this.props.simulationType == 'Suspension') { let x1rod = (this.props.xMax + this.props.xMin) / 2 - this.props.radius - this.props.yMin - 200; @@ -915,7 +878,7 @@ export default class Weight extends React.Component { left: 0, top: 0, }}> - + {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(val => { const count = 10; let xPos1; @@ -946,7 +909,7 @@ export default class Weight extends React.Component { left: 0, top: 0, }}> - +

@@ -960,7 +923,7 @@ export default class Weight extends React.Component { left: 0, top: 0, }}> - +
@@ -974,7 +937,7 @@ export default class Weight extends React.Component { left: 0, top: 0, }}> - + { left: 0, top: 0, }}> - + { left: 0, top: 0, }}> - + { left: 0, top: 0, }}> - + {!this.state.dragging && ( @@ -1115,7 +1078,7 @@ export default class Weight extends React.Component { left: 0, top: 0, }}> - + @@ -1156,7 +1119,7 @@ export default class Weight extends React.Component { left: 0, top: 0, }}> - + @@ -1224,7 +1187,7 @@ export default class Weight extends React.Component { left: this.props.xMin, top: this.props.yMin, }}> - + @@ -1289,7 +1252,7 @@ export default class Weight extends React.Component { left: this.props.xMin, top: this.props.yMin, }}> - + -- cgit v1.2.3-70-g09d2