diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx | 343 |
1 files changed, 341 insertions, 2 deletions
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); + }; |