diff options
author | brynnchernosky <56202540+brynnchernosky@users.noreply.github.com> | 2023-02-13 16:55:24 -0500 |
---|---|---|
committer | brynnchernosky <56202540+brynnchernosky@users.noreply.github.com> | 2023-02-13 16:55:24 -0500 |
commit | ac98c1e9b6a2370569113e64514dd1240a2adf7e (patch) | |
tree | c757485c16fd00bbe226b3f3332c72b52b864018 /src | |
parent | cb19032c67d810d3683e101896e20df7eecec77c (diff) |
keep converting to persistent
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/nodes/PhysicsSimulationApp.tsx | 557 | ||||
-rw-r--r-- | src/client/views/nodes/PhysicsSimulationBox.tsx | 194 | ||||
-rw-r--r-- | src/client/views/nodes/PhysicsSimulationWeight.tsx | 129 |
3 files changed, 55 insertions, 825 deletions
diff --git a/src/client/views/nodes/PhysicsSimulationApp.tsx b/src/client/views/nodes/PhysicsSimulationApp.tsx deleted file mode 100644 index acca65b08..000000000 --- a/src/client/views/nodes/PhysicsSimulationApp.tsx +++ /dev/null @@ -1,557 +0,0 @@ -import React = require('react'); -import "./PhysicsSimulationBox.scss"; -import Weight, { IForce } from "./PhysicsSimulationWeight"; -import Wall, { IWallProps } from "./PhysicsSimulationWall" -import Wedge from "./PhysicsSimulationWedge" - -interface PhysicsVectorTemplate { - top: number; - left: number; - width: number; - height: number; - x1: number; - y1: number; - x2: number; - y2: number; - weightX: number; - weightY: number; -} - -interface IState { - accelerationXDisplay: number, - accelerationYDisplay: number, - adjustPendulumAngle: {angle: number, length: number}, - coefficientOfKineticFriction: number, - coefficientOfStaticFriction: number, - currentForceSketch: PhysicsVectorTemplate | null, - deleteMode: boolean, - displayChange: {xDisplay: number, yDisplay: number}, - elasticCollisions: boolean, - forceSketches: PhysicsVectorTemplate[], - pendulum: boolean, - pendulumAngle: number, - pendulumLength: number, - positionXDisplay: number, - positionYDisplay: number, - showAcceleration: boolean, - showForceMagnitudes: boolean, - showForces: boolean, - showVelocity: boolean, - simulationPaused: boolean, - simulationReset: boolean, - simulationType: "Inclined Plane", - sketching: boolean, - startForces: IForce[], - startPendulumAngle: number, - startPosX: number, - startPosY: number, - stepNumber: number, - timer: number, - updatedForces: IForce[], - velocityXDisplay: number, - velocityYDisplay: number, - wallPositions: IWallProps[], - wedge: boolean, - wedgeAngle: number, - wedgeHeight: number, - wedgeWidth: number, - weight: boolean, -} -export default class App extends React.Component<{}, IState> { - - // Constants - gravityMagnitude = 9.81; - forceOfGravity: IForce = { - description: "Gravity", - magnitude: this.gravityMagnitude, - directionInDegrees: 270, - }; - xMin = 0; - yMin = 0; - xMax = 300; - yMax = 300; - color = `rgba(0,0,0,0.5)`; - radius = 0.1*this.yMax - - constructor(props: any) { - super(props) - this.state = { - accelerationXDisplay: 0, - accelerationYDisplay: 0, - adjustPendulumAngle: {angle: 0, length: 0}, - coefficientOfKineticFriction: 0, - coefficientOfStaticFriction: 0, - currentForceSketch: null, - deleteMode: false, - displayChange: {xDisplay: 0, yDisplay: 0}, - elasticCollisions: false, - forceSketches: [], - pendulum: false, - pendulumAngle: 0, - pendulumLength: 300, - positionXDisplay: 0, - positionYDisplay: 0, - showAcceleration: false, - showForceMagnitudes: false, - showForces: false, - showVelocity: false, - simulationPaused: true, - simulationReset: false, - simulationType: "Inclined Plane", - sketching: false, - startForces: [this.forceOfGravity], - startPendulumAngle: 0, - startPosX: 0, - startPosY: 0, - stepNumber: 0, - timer: 0, - updatedForces: [this.forceOfGravity], - velocityXDisplay: 0, - velocityYDisplay: 0, - wallPositions: [], - wedge: false, - wedgeAngle: 26, - wedgeHeight: Math.tan((26 * Math.PI) / 180) * this.xMax*0.6, - wedgeWidth: this.xMax*0.6, - weight: false, - } - } - - // Add one weight to the simulation - addWeight () { - this.setState({weight: true}) - this.setState({wedge: false}) - this.setState({pendulum: false}) - this.setState({startPosY: this.yMin+this.radius}) - this.setState({startPosX: (this.xMax+this.xMin-this.radius)/2}) - this.setState({updatedForces: [this.forceOfGravity]}) - this.setState({startForces: [this.forceOfGravity]}) - this.addWalls(); - this.setState({simulationReset: !this.state.simulationReset}) - }; - - // Add a wedge with a One Weight to the simulation - addWedge () { - this.setState({weight: true}) - this.setState({wedge: true}) - this.setState({pendulum: false}) - this.changeWedgeBasedOnNewAngle(26); - this.addWalls(); - this.setState({startForces: [this.forceOfGravity]}) - this.updateForcesWithFriction(this.state.coefficientOfStaticFriction); - }; - - // Add a simple pendulum to the simulation - addPendulum = () => { - this.setState({weight: true}) - this.setState({wedge: false}) - this.setState({pendulum: true}) - let length = this.xMax*0.7; - let angle = 35; - let x = length * Math.cos(((90 - angle) * Math.PI) / 180); - let y = length * Math.sin(((90 - angle) * Math.PI) / 180); - let xPos = this.xMax / 2 - x - this.radius; - let yPos = y - this.radius; - this.setState({startPosX: xPos}) - this.setState({startPosY: yPos}) - let mag = 9.81 * Math.cos((angle * Math.PI) / 180); - let forceOfTension: IForce = { - description: "Tension", - magnitude: mag, - directionInDegrees: 90 - angle, - }; - this.setState({updatedForces: [this.forceOfGravity, forceOfTension]}) - this.setState({startForces: [this.forceOfGravity, forceOfTension]}) - this.setState({pendulumAngle: angle}) - this.setState({pendulumLength: length}) - this.setState({adjustPendulumAngle: {angle: angle, length: length}}) - this.removeWalls(); - }; - - // Update forces when coefficient of static friction changes in freeform mode - updateForcesWithFriction ( - coefficient: number, - width: number = this.state.wedgeWidth, - height: number = this.state.wedgeHeight - ) { - let normalForce = { - description: "Normal Force", - magnitude: this.forceOfGravity.magnitude * Math.cos(Math.atan(height / width)), - directionInDegrees: - 180 - 90 - (Math.atan(height / width) * 180) / Math.PI, - }; - let frictionForce: IForce = { - description: "Static Friction Force", - magnitude: - coefficient * - this.forceOfGravity.magnitude * - Math.cos(Math.atan(height / width)), - directionInDegrees: 180 - (Math.atan(height / width) * 180) / Math.PI, - }; - // reduce magnitude of friction force if necessary such that block cannot slide up plane - let yForce = -this.forceOfGravity.magnitude; - 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) + - this.forceOfGravity.magnitude) / - Math.sin((frictionForce.directionInDegrees * Math.PI) / 180); - } - if (coefficient != 0) { - this.setState({startForces: [this.forceOfGravity, normalForce, frictionForce]}) - this.setState({updatedForces: [this.forceOfGravity, normalForce, frictionForce]}); - } else { - this.setState({startForces: [this.forceOfGravity, normalForce]}) - this.setState({updatedForces: [this.forceOfGravity, normalForce]}); - } - }; - - // Change wedge height and width and weight position to match new wedge angle - changeWedgeBasedOnNewAngle = (angle: number) => { - let width = 0; - let height = 0; - if (angle < 50) { - width = this.xMax*0.6; - height = Math.tan((angle * Math.PI) / 180) * width; - this.setState({wedgeWidth: width}) - this.setState({wedgeHeight: height}) - } else if (angle < 70) { - width = this.xMax*0.3; - height = Math.tan((angle * Math.PI) / 180) * width; - this.setState({wedgeWidth: width}) - this.setState({wedgeHeight: height}) - } else { - width = this.xMax*0.15; - height = Math.tan((angle * Math.PI) / 180) * width; - this.setState({wedgeWidth: width}) - this.setState({wedgeHeight: height}) - } - - // update weight position based on updated wedge width/height - let xPos = (this.xMax * 0.2)-this.radius; - let yPos = width * Math.tan((angle * Math.PI) / 180) - this.radius; - - this.setState({startPosX: xPos}); - this.setState({startPosY: this.getDisplayYPos(yPos)}); - this.updateForcesWithFriction( - Number(this.state.coefficientOfStaticFriction), - width, - height - ); - }; - - // Helper function to go between display and real values - getDisplayYPos = (yPos: number) => { - return this.yMax - yPos - 2 * 50 + 5; - }; - - // In review mode, edit force arrow sketch on mouse movement - editForce = (element: PhysicsVectorTemplate) => { - if (!this.state.sketching) { - let sketches = this.state.forceSketches.filter((sketch) => sketch != element); - this.setState({forceSketches: sketches}) - this.setState({currentForceSketch: element}) - this.setState({sketching: true}) - } - }; - - // In review mode, used to delete force arrow sketch on SHIFT+click - deleteForce = (element: PhysicsVectorTemplate) => { - if (!this.state.sketching) { - let sketches = this.state.forceSketches.filter((sketch) => sketch != element); - this.setState({forceSketches: sketches}) - } - }; - - // Remove floor and walls from simulation - removeWalls = () => { - this.setState({wallPositions: []}) - }; - - // Add floor and walls to simulation - addWalls = () => { - if (this.state.wallPositions.length == 0) { - let walls = []; - walls.push({ length: 100, xPos: 0, yPos: 97, angleInDegrees: 0 }); - walls.push({ length: 100, xPos: 0, yPos: 0, angleInDegrees: 90 }); - walls.push({ length: 100, xPos: 97, yPos: 0, angleInDegrees: 90 }); - this.setState({wallPositions: walls}) - } - }; - - - componentDidMount() { - // Add weight - this.addPendulum() - - // Add listener for SHIFT key, which determines if sketch force arrow will be edited or deleted on click - document.addEventListener("keydown", (e) => { - if (e.shiftKey) { - this.setState({deleteMode: true}) - } - }); - document.addEventListener("keyup", (e) => { - if (e.shiftKey) { - this.setState({deleteMode: false}) - } - }); - - // Timer for animating the simulation - setInterval(() => { - this.setState({timer: this.state.timer+1}) - }, 60); - } - - render () { - return ( - <div> - <div className="mechanicsSimulationContainer"> - <div - className="mechanicsSimulationContentContainer" - onPointerMove={(e) => { - // if (sketching) { - // x1 = positionXDisplay + 50; - // y1 = yMax - positionYDisplay - 2 * 50 + 5 + 50; - // x2 = e.clientX; - // y2 = e.clientY; - // height = Math.abs(y1 - y2) + 120; - // width = Math.abs(x1 - x2) + 120; - // top = Math.min(y1, y2) - 60; - // left = Math.min(x1, x2) - 60; - // x1Updated = x1 - left; - // x2Updated = x2 - left; - // y1Updated = y1 - top; - // y2Updated = y2 - top; - // setCurrentForceSketch({ - // top: top, - // left: left, - // width: width, - // height: height, - // x1: x1Updated, - // y1: y1Updated, - // x2: x2Updated, - // y2: y2Updated, - // weightX: positionXDisplay, - // weightY: positionYDisplay, - // }); - // } - }} - onPointerDown={(e) => { - // if (sketching && currentForceSketch) { - // setSketching(false); - // sketches = forceSketches; - // sketches.push(currentForceSketch); - // setForceSketches(sketches); - // setCurrentForceSketch(null); - // } - }} - > - <div className="mechanicsSimulationButtonsAndElements"> - <div className="mechanicsSimulationElements"> - {/* {showForces && currentForceSketch && simulationPaused && ( - <div - style={{ - position: "fixed", - top: currentForceSketch.top, - left: currentForceSketch.left, - }} - > - <svg - width={currentForceSketch.width + "px"} - height={currentForceSketch.height + "px"} - > - <defs> - <marker - id="sketchArrow" - markerWidth="10" - markerHeight="10" - refX="0" - refY="2" - orient="auto" - markerUnits="strokeWidth" - > - <path d="M0,0 L0,4 L6,2 z" fill={color} /> - </marker> - </defs> - <line - x1={currentForceSketch.x1} - y1={currentForceSketch.y1} - x2={currentForceSketch.x2} - y2={currentForceSketch.y2} - stroke={color} - strokeWidth="10" - markerEnd="url(#sketchArrow)" - /> - </svg> - </div> - )} */} - {/* {showForces && - forceSketches.length > 0 && - simulationPaused && - forceSketches.map((element: PhysicsVectorTemplate, index) => { - return ( - <div - key={index} - style={{ - position: "fixed", - top: element.top + (positionYDisplay - element.weightY), - left: - element.left + (positionXDisplay - element.weightX), - }} - > - <svg - width={element.width + "px"} - height={element.height + "px"} - > - <defs> - <marker - id="sketchArrow" - markerWidth="10" - markerHeight="10" - refX="0" - refY="2" - orient="auto" - markerUnits="strokeWidth" - > - <path d="M0,0 L0,4 L6,2 z" fill={color} /> - </marker> - </defs> - <line - x1={element.x1} - y1={element.y1} - x2={element.x2} - y2={element.y2} - stroke={color} - strokeWidth="10" - markerEnd="url(#sketchArrow)" - onClick={() => { - if (deleteMode) { - deleteForce(element); - } else { - editForce(element); - } - }} - /> - </svg> - </div> - ); - })} */} - {this.state.weight && ( - <Weight - adjustPendulumAngle={this.state.adjustPendulumAngle} - color={"red"} - displayXPosition={this.state.positionXDisplay} - displayXVelocity={this.state.velocityXDisplay} - displayYPosition={this.state.positionYDisplay} - displayYVelocity={this.state.velocityYDisplay} - elasticCollisions={this.state.elasticCollisions} - incrementTime={this.state.timer} - mass={1} - paused={this.state.simulationPaused} - pendulum={this.state.pendulum} - pendulumAngle={this.state.pendulumAngle} - pendulumLength={this.state.pendulumLength} - radius={this.radius} - reset={this.state.simulationReset} - showForceMagnitudes={this.state.showForceMagnitudes} - setSketching={(val: boolean) => {this.setState({sketching: val})}} - setDisplayXAcceleration={(val: number) => {this.setState({accelerationXDisplay: val})}} - setDisplayXPosition={(val: number) => {this.setState({positionXDisplay: val})}} - setDisplayXVelocity={(val: number) => {this.setState({velocityXDisplay: val})}} - setDisplayYAcceleration={(val: number) => {this.setState({accelerationYDisplay: val})}} - setDisplayYPosition={(val: number) => {this.setState({positionYDisplay: val})}} - setDisplayYVelocity={(val: number) => {this.setState({velocityYDisplay: val})}} - setPaused={(val: boolean) => {this.setState({simulationPaused: val})}} - setPendulumAngle={(val: number) => {this.setState({pendulumAngle: val})}} - setPendulumLength={(val: number) => {this.setState({pendulumLength: val})}} - setStartPendulumAngle={(val: number) => {this.setState({startPendulumAngle: val})}} - setUpdatedForces={(val: IForce[]) => {this.setState({updatedForces: val})}} - showAcceleration={this.state.showAcceleration} - showForces={this.state.showForces} - showVelocity={this.state.showVelocity} - startForces={this.state.startForces} - startPosX={this.state.startPosX} - startPosY={this.state.startPosY} - timestepSize={0.002} - updateDisplay={this.state.displayChange} - updatedForces={this.state.updatedForces} - walls={this.state.wallPositions} - wedge={this.state.wedge} - wedgeHeight={this.state.wedgeHeight} - wedgeWidth={this.state.wedgeWidth} - coefficientOfKineticFriction={this.state.coefficientOfKineticFriction} - xMax={this.xMax} - yMax={this.yMax} - xMin={this.xMin} - yMin={this.yMin} - /> - )} - {this.state.wedge && ( - <Wedge - startWidth={this.state.wedgeWidth} - startHeight={this.state.wedgeHeight} - startLeft={this.xMax * 0.2} - xMax={this.xMax} - yMax={this.yMax} - /> - )} - </div> - <div> - {this.state.wallPositions.map((element, index) => { - return ( - <div key={index}> - <Wall - length={element.length} - xPos={element.xPos} - yPos={element.yPos} - angleInDegrees={element.angleInDegrees} - /> - </div> - ); - })} - </div> - </div> - </div> - <div className="mechanicsSimulationEquationContainer"> - <div className="mechanicsSimulationControls"> - <div> - {this.state.simulationPaused && ( - <button onClick={() => { - this.setState({simulationPaused: false}); - }} >START</button> - )} - {!this.state.simulationPaused && ( - <button onClick={() => { - this.setState({simulationPaused: true}); - }} >PAUSE</button> - )} - {this.state.simulationPaused && ( - <button onClick={() => { - this.setState({simulationReset: !this.state.simulationReset}); - }} >RESET</button> - )} - <button onClick={() => { - if (!this.state.pendulum && !this.state.wedge) { - this.addWedge() - } - else if (!this.state.pendulum && this.state.wedge) { - this.addPendulum() - } - else { - this.addWeight() - } - }} >TYPE</button> - </div> - </div> - </div> - </div> - </div> - ); - } -} diff --git a/src/client/views/nodes/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsSimulationBox.tsx index 3ea4fba9f..9d91adefb 100644 --- a/src/client/views/nodes/PhysicsSimulationBox.tsx +++ b/src/client/views/nodes/PhysicsSimulationBox.tsx @@ -33,46 +33,6 @@ interface PhysicsVectorTemplate { weightY: number; } -interface IState { - accelerationXDisplay: number, - accelerationYDisplay: number, - adjustPendulumAngle: {angle: number, length: number}, - coefficientOfKineticFriction: number, - coefficientOfStaticFriction: number, - currentForceSketch: PhysicsVectorTemplate | null, - deleteMode: boolean, - displayChange: {xDisplay: number, yDisplay: number}, - elasticCollisions: boolean, - forceSketches: PhysicsVectorTemplate[], - pendulum: boolean, - pendulumAngle: number, - pendulumLength: number, - positionXDisplay: number, - positionYDisplay: number, - showAcceleration: boolean, - showForceMagnitudes: boolean, - showForces: boolean, - showVelocity: boolean, - simulationPaused: boolean, - simulationReset: boolean, - simulationType: "Inclined Plane", - sketching: boolean, - startForces: IForce[], - startPendulumAngle: number, - startPosX: number, - startPosY: number, - stepNumber: number, - timer: number, - updatedForces: IForce[], - velocityXDisplay: number, - velocityYDisplay: number, - wallPositions: IWallProps[], - wedge: boolean, - wedgeAngle: number, - wedgeHeight: number, - wedgeWidth: number, - weight: boolean, -} @observer export default class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @@ -96,7 +56,7 @@ export default class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<Fi super(props); this.dataDoc.accelerationXDisplay = 0; this.dataDoc.accelerationYDisplay = 0; - this.dataDoc.adjustPendulumAngle = {angle: 0, length: 0}; + this.dataDoc.adjustPendulumAngle = true; this.dataDoc.coefficientOfKineticFriction = 0; this.dataDoc.coefficientOfStaticFriction = 0; this.dataDoc.currentForceSketch = []; @@ -181,7 +141,7 @@ export default class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<Fi this.dataDoc.startForces = [this.forceOfGravity, forceOfTension]; this.dataDoc.pendulumAngle = angle; this.dataDoc.pendulumLength = length; - this.dataDoc.adjustPendulumAngle = {angle: angle, length: length}; + this.dataDoc.adjustPendulumAngle = !this.dataDoc.adjustPendulumAngle; this.removeWalls(); }; @@ -329,166 +289,20 @@ export default class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<Fi return ( <div> <div className="mechanicsSimulationContainer"> - <div - className="mechanicsSimulationContentContainer" - onPointerMove={(e) => { - // if (sketching) { - // x1 = positionXDisplay + 50; - // y1 = yMax - positionYDisplay - 2 * 50 + 5 + 50; - // x2 = e.clientX; - // y2 = e.clientY; - // height = Math.abs(y1 - y2) + 120; - // width = Math.abs(x1 - x2) + 120; - // top = Math.min(y1, y2) - 60; - // left = Math.min(x1, x2) - 60; - // x1Updated = x1 - left; - // x2Updated = x2 - left; - // y1Updated = y1 - top; - // y2Updated = y2 - top; - // setCurrentForceSketch({ - // top: top, - // left: left, - // width: width, - // height: height, - // x1: x1Updated, - // y1: y1Updated, - // x2: x2Updated, - // y2: y2Updated, - // weightX: positionXDisplay, - // weightY: positionYDisplay, - // }); - // } - }} - onPointerDown={(e) => { - // if (sketching && currentForceSketch) { - // setSketching(false); - // sketches = forceSketches; - // sketches.push(currentForceSketch); - // setForceSketches(sketches); - // setCurrentForceSketch(null); - // } - }} - > + <div className="mechanicsSimulationContentContainer"> <div className="mechanicsSimulationButtonsAndElements"> <div className="mechanicsSimulationElements"> - {/* {showForces && currentForceSketch && simulationPaused && ( - <div - style={{ - position: "fixed", - top: currentForceSketch.top, - left: currentForceSketch.left, - }} - > - <svg - width={currentForceSketch.width + "px"} - height={currentForceSketch.height + "px"} - > - <defs> - <marker - id="sketchArrow" - markerWidth="10" - markerHeight="10" - refX="0" - refY="2" - orient="auto" - markerUnits="strokeWidth" - > - <path d="M0,0 L0,4 L6,2 z" fill={color} /> - </marker> - </defs> - <line - x1={currentForceSketch.x1} - y1={currentForceSketch.y1} - x2={currentForceSketch.x2} - y2={currentForceSketch.y2} - stroke={color} - strokeWidth="10" - markerEnd="url(#sketchArrow)" - /> - </svg> - </div> - )} */} - {/* {showForces && - forceSketches.length > 0 && - simulationPaused && - forceSketches.map((element: PhysicsVectorTemplate, index) => { - return ( - <div - key={index} - style={{ - position: "fixed", - top: element.top + (positionYDisplay - element.weightY), - left: - element.left + (positionXDisplay - element.weightX), - }} - > - <svg - width={element.width + "px"} - height={element.height + "px"} - > - <defs> - <marker - id="sketchArrow" - markerWidth="10" - markerHeight="10" - refX="0" - refY="2" - orient="auto" - markerUnits="strokeWidth" - > - <path d="M0,0 L0,4 L6,2 z" fill={color} /> - </marker> - </defs> - <line - x1={element.x1} - y1={element.y1} - x2={element.x2} - y2={element.y2} - stroke={color} - strokeWidth="10" - markerEnd="url(#sketchArrow)" - onClick={() => { - if (deleteMode) { - deleteForce(element); - } else { - editForce(element); - } - }} - /> - </svg> - </div> - ); - })} */} {this.dataDoc.weight && ( <Weight - adjustPendulumAngle={this.dataDoc.adjustPendulumAngle} color={"red"} - displayXPosition={this.dataDoc.positionXDisplay} - displayXVelocity={this.dataDoc.velocityXDisplay} - displayYPosition={this.dataDoc.positionYDisplay} - displayYVelocity={this.dataDoc.velocityYDisplay} - elasticCollisions={this.dataDoc.elasticCollisions} - incrementTime={this.dataDoc.timer} + dataDoc={this.dataDoc} mass={1} - paused={this.dataDoc.simulationPaused} pendulum={this.dataDoc.pendulum} pendulumAngle={this.dataDoc.pendulumAngle} pendulumLength={this.dataDoc.pendulumLength} radius={this.radius} reset={this.dataDoc.simulationReset} showForceMagnitudes={this.dataDoc.showForceMagnitudes} - setSketching={(val: boolean) => {this.dataDoc.sketching = val}} - setDisplayXAcceleration={(val: number) => {this.dataDoc.accelerationXDisplay = val}} - setDisplayXPosition={(val: number) => {this.dataDoc.positionXDisplay = val}} - setDisplayXVelocity={(val: number) => {this.dataDoc.velocityXDisplay = val}} - setDisplayYAcceleration={(val: number) => {this.dataDoc.accelerationYDisplay = val}} - setDisplayYPosition={(val: number) => {this.dataDoc.positionYDisplay = val}} - setDisplayYVelocity={(val: number) => {this.dataDoc.velocityYDisplay = val}} - setPaused={(val: boolean) => {this.dataDoc.simulationPaused = val}} - setPendulumAngle={(val: number) => {this.dataDoc.pendulumAngle = val}} - setPendulumLength={(val: number) => {this.dataDoc.pendulumLength = val}} - setStartPendulumAngle={(val: number) => {this.dataDoc.startPendulumAngle = val}} - setUpdatedForces={(val: IForce[]) => {this.dataDoc.updatedForces = val}} showAcceleration={this.dataDoc.showAcceleration} showForces={this.dataDoc.showForces} showVelocity={this.dataDoc.showVelocity} diff --git a/src/client/views/nodes/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsSimulationWeight.tsx index dfd463bbe..fcfb149c9 100644 --- a/src/client/views/nodes/PhysicsSimulationWeight.tsx +++ b/src/client/views/nodes/PhysicsSimulationWeight.tsx @@ -1,4 +1,5 @@ import React = require('react'); +import { Doc } from '../../../fields/Doc'; import { IWallProps } from "./PhysicsSimulationWall"; export interface IForce { @@ -7,35 +8,17 @@ export interface IForce { directionInDegrees: number; } export interface IWeightProps { - adjustPendulumAngle: { angle: number; length: number }; + dataDoc: Doc; color: string; - displayXPosition: number; - displayYPosition: number; - displayXVelocity: number; - displayYVelocity: number; - elasticCollisions: boolean; startForces: IForce[]; - incrementTime: number; mass: number; - paused: boolean; pendulum: boolean; pendulumLength: number; wedge: boolean; radius: number; reset: boolean; - setDisplayXAcceleration: (val: number) => any; - setDisplayXPosition: (val: number) => any; - setDisplayXVelocity: (val: number) => any; - setDisplayYAcceleration: (val: number) => any; - setDisplayYPosition: (val: number) => any; - setDisplayYVelocity: (val: number) => any; - setPaused: (bool: boolean) => any; - setPendulumAngle: (val: number) => any; - setPendulumLength: (val: number) => any; - setStartPendulumAngle: (val: number) => any; showAcceleration: boolean; pendulumAngle: number; - setSketching: (val: boolean) => any; showForces: boolean; showForceMagnitudes: boolean; showVelocity: boolean; @@ -46,7 +29,6 @@ export interface IWeightProps { timestepSize: number; updateDisplay: { xDisplay: number; yDisplay: number }; updatedForces: IForce[]; - setUpdatedForces: (val: IForce[]) => any; walls: IWallProps[]; coefficientOfKineticFriction: number; wedgeWidth: number; @@ -125,16 +107,16 @@ export default class Weight extends React.Component<IWeightProps, IState> { // Set display values based on real values setYPosDisplay = (yPos: number) => { const displayPos = this.getDisplayYPos(yPos); - this.props.setDisplayYPosition(Math.round(displayPos * 100) / 100) + this.props.dataDoc['positionYDisplay'] = Math.round(displayPos * 100) / 100 }; setXPosDisplay = (xPos: number) => { - this.props.setDisplayXPosition(Math.round(xPos * 100) / 100); + this.props.dataDoc['positionXDisplay'] = Math.round(xPos * 100) / 100; }; setYVelDisplay = (yVel: number) => { - this.props.setDisplayYVelocity((-1 * Math.round(yVel * 100)) / 100); + this.props.dataDoc['velocityYDisplay'] = (-1 * Math.round(yVel * 100)) / 100; }; setXVelDisplay = (xVel: number) => { - this.props.setDisplayXVelocity(Math.round(xVel * 100) / 100); + this.props.dataDoc['velocityXDisplay'] = Math.round(xVel * 100) / 100; }; setDisplayValues = ( @@ -147,12 +129,12 @@ export default class Weight extends React.Component<IWeightProps, IState> { this.setXPosDisplay(xPos); this.setYVelDisplay(yVel); this.setXVelDisplay(xVel); - this.props.setDisplayYAcceleration( + this.props.dataDoc['accelerationYDisplay'] = (-1 * Math.round(this.getNewAccelerationY(this.props.updatedForces) * 100)) / 100 - ); - this.props.setDisplayXAcceleration( + ; + this.props.dataDoc['accelerationXDisplay'] = Math.round(this.getNewAccelerationX(this.props.updatedForces) * 100) / 100 - ); + ; }; componentDidUpdate(prevProps: Readonly<IWeightProps>, prevState: Readonly<IState>, snapshot?: any): void { @@ -164,34 +146,34 @@ export default class Weight extends React.Component<IWeightProps, IState> { x = Math.min(x, this.props.xMax - 2 * this.props.radius); this.setState({updatedStartPosX: x}) this.setState({xPosition: x}) - this.props.setDisplayXPosition(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); - this.props.setDisplayYPosition(y); + this.props.dataDoc['positionYDisplay'] = y; let coordinatePosition = this.getYPosFromDisplay(y); this.setState({updatedStartPosY: coordinatePosition}) this.setState({yPosition: coordinatePosition}) } - if (this.props.displayXVelocity != this.state.xVelocity) { - let x = this.props.displayXVelocity; + if (this.props.dataDoc['velocityXDisplay'] != this.state.xVelocity) { + let x = this.props.dataDoc['velocityXDisplay']; this.setState({xVelocity: x}) - this.props.setDisplayXVelocity(x); + this.props.dataDoc['velocityXDisplay'] = x; } - if (this.props.displayYVelocity != this.state.yVelocity) { - let y = this.props.displayYVelocity; + if (this.props.dataDoc['velocityYDisplay'] != this.state.yVelocity) { + let y = this.props.dataDoc['velocityYDisplay']; this.setState({yVelocity: -y}) - this.props.setDisplayXVelocity(y); + this.props.dataDoc['velocityYDisplay'] } } // Update sim - if (this.props.incrementTime != prevProps.incrementTime) { - if (!this.props.paused) { + if (this.props.dataDoc['incrementTime'] != prevProps.dataDoc['incrementTime']) { + if (!this.props.dataDoc['simulationPaused']) { let collisions = false; if (!this.props.pendulum) { const collisionsWithGround = this.checkForCollisionsWithGround(); @@ -229,21 +211,19 @@ export default class Weight extends React.Component<IWeightProps, IState> { this.setState({yVelocity: this.props.startVelY ?? 0}) this.setDisplayValues(); } - if (this.props.adjustPendulumAngle != prevProps.adjustPendulumAngle) { + if (this.props.dataDoc['adjustPendulumAngle'] != prevProps.dataDoc['adjustPendulumAngle']) { // Change pendulum angle based on input field - let length = this.props.adjustPendulumAngle.length; + let length = this.props.dataDoc['pendulumLength'] ?? 0; const x = - length * Math.cos(((90 - this.props.adjustPendulumAngle.angle) * Math.PI) / 180); + length * Math.cos(((90 - this.props.dataDoc['pendulumAngle']) * Math.PI) / 180); const y = - length * Math.sin(((90 - this.props.adjustPendulumAngle.angle) * Math.PI) / 180); + length * Math.sin(((90 - this.props.dataDoc['pendulumAngle']) * 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.setPendulumAngle(this.props.adjustPendulumAngle.angle); - this.props.setPendulumLength(this.props.adjustPendulumAngle.length); } // Update x start position if (this.props.startPosX != prevProps.startPosX) { @@ -314,24 +294,28 @@ export default class Weight extends React.Component<IWeightProps, IState> { getNewAccelerationX = (forceList: IForce[]) => { let newXAcc = 0; - forceList.forEach((force) => { - newXAcc += - (force.magnitude * - Math.cos((force.directionInDegrees * Math.PI) / 180)) / - this.props.mass; - }); + if (forceList) { + forceList.forEach((force) => { + newXAcc += + (force.magnitude * + Math.cos((force.directionInDegrees * Math.PI) / 180)) / + this.props.mass; + }); + } return newXAcc; }; getNewAccelerationY = (forceList: IForce[]) => { let newYAcc = 0; - forceList.forEach((force) => { - newYAcc += - (-1 * - (force.magnitude * - Math.sin((force.directionInDegrees * Math.PI) / 180))) / - this.props.mass; - }); + if (forceList) { + forceList.forEach((force) => { + newYAcc += + (-1 * + (force.magnitude * + Math.sin((force.directionInDegrees * Math.PI) / 180))) / + this.props.mass; + }); + } return newYAcc; }; @@ -356,8 +340,8 @@ export default class Weight extends React.Component<IWeightProps, IState> { } const pendulumLength = Math.sqrt(x * x + y * y); - this.props.setPendulumAngle(oppositeAngle); - this.props.setPendulumLength(Math.sqrt(x * x + y * y)); + this.props.dataDoc['pendulumAngle'] = oppositeAngle; + this.props.dataDoc['pendulumLength'] = Math.sqrt(x * x + y * y); const mag = this.props.mass * 9.81 * Math.cos((oppositeAngle * Math.PI) / 180) + @@ -391,7 +375,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { const wallX = (wall.xPos / 100) * 300; if (wall.xPos < 0.35) { if (minX <= wallX) { - if (this.props.elasticCollisions) { + if (this.props.dataDoc['elasticCollisions']) { this.setState({xVelocity: -this.state.xVelocity}); } else { this.setState({xVelocity: 0}); @@ -401,7 +385,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { } } else { if (maxX >= wallX) { - if (this.props.elasticCollisions) { + if (this.props.dataDoc['elasticCollisions']) { this.setState({xVelocity: -this.state.xVelocity}); } else { this.setState({xVelocity: 0}); @@ -424,7 +408,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { if (wall.angleInDegrees == 0) { const groundY = (wall.yPos / 100) * this.props.yMax; if (maxY >= groundY) { - if (this.props.elasticCollisions) { + if (this.props.dataDoc['elasticCollisions']) { this.setState({yVelocity: -this.state.yVelocity}) } else { this.setState({yVelocity: 0}) @@ -525,7 +509,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { onPointerDown={(e) => { if (this.draggable) { e.preventDefault(); - this.props.setPaused(true); + this.props.dataDoc['simulationPaused'] = true; this.setState({dragging: true}); this.setState({clickPositionX: e.clientX}) this.setState({clickPositionY: e.clientY}) @@ -549,7 +533,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { this.setState({yPosition: newY}) this.setState({updatedStartPosX: newX}) this.setState({updatedStartPosY: newY}) - this.props.setDisplayYPosition(Math.round((this.props.yMax - 2 * this.props.radius - newY + 5) * 100) / 100) + this.props.dataDoc['positionYDisplay'] = Math.round((this.props.yMax - 2 * this.props.radius - newY + 5) * 100) / 100; this.setState({clickPositionX: e.clientX}) this.setState({clickPositionY: e.clientY}) this.setDisplayValues(); @@ -586,8 +570,8 @@ export default class Weight extends React.Component<IWeightProps, IState> { } const pendulumLength = Math.sqrt(x * x + y * y); - this.props.setPendulumAngle(oppositeAngle); - this.props.setPendulumLength(Math.sqrt(x * x + y * y)); + this.props.dataDoc['pendulumAngle'] = oppositeAngle; + this.props.dataDoc['pendulumLength'] = Math.sqrt(x * x + y * y); const mag = 9.81 * Math.cos((oppositeAngle * Math.PI) / 180); const forceOfTension: IForce = { description: "Tension", @@ -629,17 +613,6 @@ export default class Weight extends React.Component<IWeightProps, IState> { </svg> {!this.state.dragging && ( <div> - {/* <p - style={{ - position: "absolute", - zIndex: 5, - left: this.state.xPosition + "px", - top: this.state.yPosition - 70 + "px", - backgroundColor: this.labelBackgroundColor, - }} - > - {Math.round(this.props.pendulumLength)} m - </p> */} <p style={{ position: "absolute", @@ -648,7 +621,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { backgroundColor: this.labelBackgroundColor, }} > - {Math.round(this.props.pendulumAngle * 100) / 100}° + {Math.round(this.props.dataDoc['pendulumAngle'] * 100) / 100}° </p> </div> )} |