aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/PhysicsSimulationApp.tsx
diff options
context:
space:
mode:
authorbrynnchernosky <56202540+brynnchernosky@users.noreply.github.com>2023-02-13 16:55:24 -0500
committerbrynnchernosky <56202540+brynnchernosky@users.noreply.github.com>2023-02-13 16:55:24 -0500
commitac98c1e9b6a2370569113e64514dd1240a2adf7e (patch)
treec757485c16fd00bbe226b3f3332c72b52b864018 /src/client/views/nodes/PhysicsSimulationApp.tsx
parentcb19032c67d810d3683e101896e20df7eecec77c (diff)
keep converting to persistent
Diffstat (limited to 'src/client/views/nodes/PhysicsSimulationApp.tsx')
-rw-r--r--src/client/views/nodes/PhysicsSimulationApp.tsx557
1 files changed, 0 insertions, 557 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>
- );
- }
-}