diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/nodes/PhysicsSimulationApp.tsx | 1130 |
1 files changed, 427 insertions, 703 deletions
diff --git a/src/client/views/nodes/PhysicsSimulationApp.tsx b/src/client/views/nodes/PhysicsSimulationApp.tsx index 0a39b3291..2a314a723 100644 --- a/src/client/views/nodes/PhysicsSimulationApp.tsx +++ b/src/client/views/nodes/PhysicsSimulationApp.tsx @@ -1,10 +1,12 @@ -import React, { useEffect, useState } from "react"; +import React = require('react'); import "./PhysicsSimulationBox.scss"; import { IForce, Weight } from "./PhysicsSimulationWeight"; import {Wall, IWallProps } from "./PhysicsSimulationWall" import {Wedge} from "./PhysicsSimulationWedge" +import { props, any } from 'bluebird'; +import { render } from 'react-dom'; -interface VectorTemplate { +interface PhysicsVectorTemplate { top: number; left: number; width: number; @@ -16,170 +18,169 @@ interface VectorTemplate { weightX: number; weightY: number; } -interface QuestionTemplate { - questionSetup: string[]; - variablesForQuestionSetup: string[]; - question: string; - answerParts: string[]; - answerSolutionDescriptions: string[]; - goal: string; - hints: { description: string; content: string }[]; -} -interface TutorialTemplate { - question: string; - steps: { - description: string; - content: string; - forces: { - description: string; - magnitude: number; - directionInDegrees: number; - }[]; - showMagnitude: boolean; - }[]; +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> { -function App() { // Constants - const gravityMagnitude = 9.81; - const forceOfGravity: IForce = { + gravityMagnitude = 9.81; + forceOfGravity: IForce = { description: "Gravity", - magnitude: gravityMagnitude, + magnitude: this.gravityMagnitude, directionInDegrees: 270, }; - const xMin = 0; - const yMin = 0; - const xMax = window.innerWidth * 0.7; - const yMax = window.innerHeight * 0.8; - const color = `rgba(0,0,0,0.5)`; - - // Variables - let questionVariables: number[] = []; - let reviewCoefficient: number = 0; - - // State variables - const [startPosX, setStartPosX] = useState(0); - const [startPosY, setStartPosY] = useState(0); - const [accelerationXDisplay, setAccelerationXDisplay] = useState(0); - const [accelerationYDisplay, setAccelerationYDisplay] = useState(0); - const [positionXDisplay, setPositionXDisplay] = useState(0); - const [positionYDisplay, setPositionYDisplay] = useState(0); - const [velocityXDisplay, setVelocityXDisplay] = useState(0); - const [velocityYDisplay, setVelocityYDisplay] = useState(0); + xMin = 0; + yMin = 0; + xMax = window.innerWidth * 0.7; + yMax = window.innerHeight * 0.8; + color = `rgba(0,0,0,0.5)`; + radius = 50 - const [startPosX2, setStartPosX2] = useState(0); - const [startPosY2, setStartPosY2] = useState(0); - const [accelerationXDisplay2, setAccelerationXDisplay2] = useState(0); - const [accelerationYDisplay2, setAccelerationYDisplay2] = useState(0); - const [positionXDisplay2, setPositionXDisplay2] = useState(0); - const [positionYDisplay2, setPositionYDisplay2] = useState(0); - const [velocityXDisplay2, setVelocityXDisplay2] = useState(0); - const [velocityYDisplay2, setVelocityYDisplay2] = useState(0); - const [adjustPendulumAngle, setAdjustPendulumAngle] = useState<{ - angle: number; - length: number; - }>({ angle: 0, length: 0 }); - const [answerInputFields, setAnswerInputFields] = useState(<div></div>); - const [coefficientOfKineticFriction, setCoefficientOfKineticFriction] = - React.useState<number | string | Array<number | string>>(0); - const [coefficientOfStaticFriction, setCoefficientOfStaticFriction] = - React.useState<number | string | Array<number | string>>(0); - const [currentForceSketch, setCurrentForceSketch] = - useState<VectorTemplate | null>(null); - const [deleteMode, setDeleteMode] = useState(false); - const [displayChange, setDisplayChange] = useState<{ - xDisplay: number; - yDisplay: number; - }>({ xDisplay: 0, yDisplay: 0 }); - const [elasticCollisions, setElasticCollisions] = useState<boolean>(false); - const [forceSketches, setForceSketches] = useState<VectorTemplate[]>([]); - const [questionPartOne, setQuestionPartOne] = useState<string>(""); - const [hintDialogueOpen, setHintDialogueOpen] = useState<boolean>(false); - const [mode, setMode] = useState<string>("Freeform"); - const [noMovement, setNoMovement] = useState(false); - const [weight, setWeight] = useState(false); - const [pendulum, setPendulum] = useState(false); - const [pendulumAngle, setPendulumAngle] = useState(0); - const [pendulumLength, setPendulumLength] = useState(300); - const [questionNumber, setQuestionNumber] = useState<number>(0); - const [reviewGravityAngle, setReviewGravityAngle] = useState<number>(0); - const [reviewGravityMagnitude, setReviewGravityMagnitude] = - useState<number>(0); - const [reviewNormalAngle, setReviewNormalAngle] = useState<number>(0); - const [reviewNormalMagnitude, setReviewNormalMagnitude] = useState<number>(0); - const [reviewStaticAngle, setReviewStaticAngle] = useState<number>(0); - const [reviewStaticMagnitude, setReviewStaticMagnitude] = useState<number>(0); - const [questionPartTwo, setQuestionPartTwo] = useState<string>(""); - const [selectedSolutions, setSelectedSolutions] = useState<number[]>([]); - const [showAcceleration, setShowAcceleration] = useState<boolean>(false); - const [showForces, setShowForces] = useState<boolean>(true); - const [showVelocity, setShowVelocity] = useState<boolean>(false); - const [simulationPaused, setSimulationPaused] = useState<boolean>(true); - const [simulationReset, setSimulationReset] = useState<boolean>(false); - const [simulationType, setSimulationType] = - useState<string>("Inclined Plane"); - const [sketching, setSketching] = useState(false); - const [startForces, setStartForces] = useState<IForce[]>([forceOfGravity]); - const [startPendulumAngle, setStartPendulumAngle] = useState(0); - const [stepNumber, setStepNumber] = useState<number>(0); - const [timer, setTimer] = useState<number>(0); - const [updatedForces, setUpdatedForces] = useState<IForce[]>([ - forceOfGravity, - ]); - const [wallPositions, setWallPositions] = useState<IWallProps[]>([]); - const [wedge, setWedge] = useState(false); - const [wedgeAngle, setWedgeAngle] = React.useState< - number | string | Array<number | string> - >(26); - const [wedgeHeight, setWedgeHeight] = useState( - Math.tan((26 * Math.PI) / 180) * 400 - ); - const [wedgeWidth, setWedgeWidth] = useState(400); - const [twoWeights, setTwoWeights] = useState(false); + 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: false, + 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) * 400, + wedgeWidth: 400, + weight: false, + } + } // Add one weight to the simulation - const addWeight = () => { - setWeight(true); - setTwoWeights(false); - setWedge(false); - setPendulum(false); - }; - - // Add two weights to the simulation - const addTwoWeights = () => { - setWeight(true); - setTwoWeights(true); - setWedge(false); - setPendulum(false); + 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 - const addWedge = () => { - setWeight(true); - setTwoWeights(false); - setWedge(true); - setPendulum(false); + 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 - const addPendulum = () => { - setWeight(true); - setTwoWeights(false); - setPendulum(true); - setWedge(false); + addPendulum = () => { + this.setState({weight: true}) + this.setState({wedge: false}) + this.setState({pendulum: true}) + let length = 300; + let angle = 50; + let x = length * Math.cos(((90 - angle) * Math.PI) / 180); + let y = length * Math.sin(((90 - angle) * Math.PI) / 180); + let xPos = xMax / 2 - x - 50; + let yPos = y - 50 - 5; + this.addPendulum(); + this.setState({startPosX: xPos}) + this.setState({startPosY: yPos}) + let mag = 9.81 * Math.cos((50 * 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: 50}) + this.setState({pendulumLength: 300}) + this.setState({adjustPendulumAngle: {angle: 50, length: 300}}) + this.removeWalls(); }; // Update forces when coefficient of static friction changes in freeform mode - const updateForcesWithFriction = ( + updateForcesWithFriction ( coefficient: number, - width: number = wedgeWidth, - height: number = wedgeHeight - ) => { - const normalForce: IForce = { + width: number = this.state.wedgeWidth, + height: number = this.state.wedgeHeight + ) { + let normalForce = { description: "Normal Force", - magnitude: forceOfGravity.magnitude * Math.cos(Math.atan(height / width)), + magnitude: this.forceOfGravity.magnitude * Math.cos(Math.atan(height / width)), directionInDegrees: 180 - 90 - (Math.atan(height / width) * 180) / Math.PI, }; @@ -187,12 +188,12 @@ function App() { description: "Static Friction Force", magnitude: coefficient * - forceOfGravity.magnitude * + 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 = -forceOfGravity.magnitude; + let yForce = -this.forceOfGravity.magnitude; yForce += normalForce.magnitude * Math.sin((normalForce.directionInDegrees * Math.PI) / 180); @@ -203,37 +204,37 @@ function App() { frictionForce.magnitude = (-normalForce.magnitude * Math.sin((normalForce.directionInDegrees * Math.PI) / 180) + - forceOfGravity.magnitude) / + this.forceOfGravity.magnitude) / Math.sin((frictionForce.directionInDegrees * Math.PI) / 180); } if (coefficient != 0) { - setStartForces([forceOfGravity, normalForce, frictionForce]); - setUpdatedForces([forceOfGravity, normalForce, frictionForce]); + this.setState({startForces: [this.forceOfGravity, normalForce, frictionForce]}) + this.setState({updatedForces: [this.forceOfGravity, normalForce, frictionForce]}); } else { - setStartForces([forceOfGravity, normalForce]); - setUpdatedForces([forceOfGravity, normalForce]); + 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 - const changeWedgeBasedOnNewAngle = (angle: number) => { + changeWedgeBasedOnNewAngle = (angle: number) => { let width = 0; let height = 0; if (angle < 50) { width = 400; height = Math.tan((angle * Math.PI) / 180) * 400; - setWedgeWidth(width); - setWedgeHeight(height); + this.setState({wedgeWidth: width}) + this.setState({wedgeHeight: height}) } else if (angle < 70) { width = 200; height = Math.tan((angle * Math.PI) / 180) * 200; - setWedgeWidth(width); - setWedgeHeight(height); + this.setState({wedgeWidth: width}) + this.setState({wedgeHeight: height}) } else { width = 100; height = Math.tan((angle * Math.PI) / 180) * 100; - setWedgeWidth(width); - setWedgeHeight(height); + this.setState({wedgeWidth: width}) + this.setState({wedgeHeight: height}) } // update weight position based on updated wedge width/height @@ -258,582 +259,305 @@ function App() { yPos += angle * 3; } - setStartPosX(Math.round((xMax * 0.5 - 200) * 10) / 10); - setStartPosY(getDisplayYPos(yPos)); - if (mode == "Freeform") { - updateForcesWithFriction( - Number(coefficientOfStaticFriction), - width, - height - ); - } + this.setState({startPosX: Math.round((this.xMax * 0.5 - 200) * 10) / 10}); + this.setState({startPosY: this.getDisplayYPos(yPos)}); + this.updateForcesWithFriction( + Number(this.state.coefficientOfStaticFriction), + width, + height + ); }; // Helper function to go between display and real values - const getDisplayYPos = (yPos: number) => { - return yMax - yPos - 2 * 50 + 5; + getDisplayYPos = (yPos: number) => { + return this.yMax - yPos - 2 * 50 + 5; }; // In review mode, edit force arrow sketch on mouse movement - const editForce = (element: VectorTemplate) => { - if (!sketching) { - const sketches = forceSketches.filter((sketch) => sketch != element); - setForceSketches(sketches); - setCurrentForceSketch(element); - setSketching(true); + 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 - const deleteForce = (element: VectorTemplate) => { - if (!sketching) { - const sketches = forceSketches.filter((sketch) => sketch != element); - setForceSketches(sketches); + 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 - const removeWalls = () => { - setWallPositions([]); + removeWalls = () => { + this.setState({wallPositions: []}) }; // Add floor and walls to simulation - const addWalls = () => { - if (wallPositions.length == 0) { - const walls: IWallProps[] = []; + addWalls = () => { + if (this.state.wallPositions.length == 0) { + let walls = []; walls.push({ length: 70, xPos: 0, yPos: 80, angleInDegrees: 0 }); walls.push({ length: 80, xPos: 0, yPos: 0, angleInDegrees: 90 }); walls.push({ length: 80, xPos: 69.5, yPos: 0, angleInDegrees: 90 }); - setWallPositions(walls); - } - }; - - // Use effect hook to handle mode/topic change - useEffect(() => { - if (mode == "Freeform") { - setShowForceMagnitudes(true); - if (simulationType == "One Weight") { - addWeight(); - setStartPosY(yMin + 50); - setStartPosX((xMax + xMin - 50) / 2); - setUpdatedForces([forceOfGravity]); - setStartForces([forceOfGravity]); - addWalls(); - setSimulationReset(!simulationReset); - } else if (simulationType == "Two Weights") { - addTwoWeights(); - setStartPosY(yMax - 100); - setStartPosX((xMax + xMin - 200) / 2); - setStartPosY2(yMax - 100); - setStartPosX2((xMax + xMin + 200) / 2); - setUpdatedForces([forceOfGravity]); - setStartForces([forceOfGravity]); - addWalls(); - setSimulationReset(!simulationReset); - // TODO - } else if (simulationType == "Inclined Plane") { - addWedge(); - changeWedgeBasedOnNewAngle(26); - addWalls(); - setStartForces([forceOfGravity]); - updateForcesWithFriction(Number(coefficientOfStaticFriction)); - } else if (simulationType == "Pendulum") { - const length = 300; - const angle = 50; - const x = length * Math.cos(((90 - angle) * Math.PI) / 180); - const y = length * Math.sin(((90 - angle) * Math.PI) / 180); - const xPos = xMax / 2 - x - 50; - const yPos = y - 50 - 5; - addPendulum(); - setStartPosX(xPos); - setStartPosY(yPos); - const mag = 9.81 * Math.cos((50 * Math.PI) / 180); - const forceOfTension: IForce = { - description: "Tension", - magnitude: mag, - directionInDegrees: 90 - angle, - }; - setUpdatedForces([forceOfGravity, forceOfTension]); - setStartForces([forceOfGravity, forceOfTension]); - setPendulumAngle(50); - setPendulumLength(300); - setAdjustPendulumAngle({ angle: 50, length: 300 }); - removeWalls(); - } + this.setState({wallPositions: walls}) } - }, [simulationType, mode]); - - const [showForceMagnitudes, setShowForceMagnitudes] = useState<boolean>(true); - - const getForceFromJSON = ( - json: { - description: string; - magnitude: number; - directionInDegrees: number; - }[] - ): IForce[] => { - const forces: IForce[] = []; - for (let i = 0; i < json.length; i++) { - const force: IForce = { - description: json[i].description, - magnitude: json[i].magnitude, - directionInDegrees: json[i].directionInDegrees, - }; - forces.push(force); - } - return forces; }; - // Use effect hook to handle force change in review mode - useEffect(() => { - if (mode == "Review") { - const forceOfGravityReview: IForce = { - description: "Gravity", - magnitude: reviewGravityMagnitude, - directionInDegrees: reviewGravityAngle, - }; - const normalForceReview: IForce = { - description: "Normal Force", - magnitude: reviewNormalMagnitude, - directionInDegrees: reviewNormalAngle, - }; - const staticFrictionForceReview: IForce = { - description: "Static Friction Force", - magnitude: reviewStaticMagnitude, - directionInDegrees: reviewStaticAngle, - }; - setStartForces([ - forceOfGravityReview, - normalForceReview, - staticFrictionForceReview, - ]); - setUpdatedForces([ - forceOfGravityReview, - normalForceReview, - staticFrictionForceReview, - ]); - } - }, [ - reviewGravityMagnitude, - reviewGravityAngle, - reviewNormalMagnitude, - reviewNormalAngle, - reviewStaticMagnitude, - reviewStaticAngle, - ]); - - // Use effect to add listener for SHIFT key, which determines if sketch force arrow will be edited or deleted on click - useEffect(() => { + + componentDidMount() { + // 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) { - setDeleteMode(true); + this.setState({deleteMode: true}) } }); document.addEventListener("keyup", (e) => { if (e.shiftKey) { - setDeleteMode(false); + this.setState({deleteMode: false}) } }); - }, []); - // Timer for animating the simulation - setInterval(() => { - setTimer(timer + 1); - }, 60); + // Timer for animating the simulation + setInterval(() => { + this.setState({timer: this.state.timer+1}) + }, 60); + } - return ( - <div> - <div className="mechanicsSimulationContainer"> - <div - className="mechanicsSimulationContentContainer" - onPointerMove={(e) => { - if (sketching) { - const x1 = positionXDisplay + 50; - const y1 = yMax - positionYDisplay - 2 * 50 + 5 + 50; - const x2 = e.clientX; - const y2 = e.clientY; - const height = Math.abs(y1 - y2) + 120; - const width = Math.abs(x1 - x2) + 120; - const top = Math.min(y1, y2) - 60; - const left = Math.min(x1, x2) - 60; - const x1Updated = x1 - left; - const x2Updated = x2 - left; - const y1Updated = y1 - top; - const 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); - const sketches = forceSketches; - sketches.push(currentForceSketch); - setForceSketches(sketches); - setCurrentForceSketch(null); - } - }} - > - <div className="mechanicsSimulationButtonsAndElements"> - <div className="mechanicsSimulationButtons"> - {!simulationPaused && ( - <div - style={{ - position: "fixed", - left: "10vw", - top: "95vh", - width: "50vw", - }} - > - <p>SIMULATION IN PROGRESS</p> - </div> - )} - <div - style={{ - position: "fixed", - top: 1 + "em", - left: xMin + 12 + "px", - }} - > - <div className="dropdownMenu"> - <select - value={simulationType} - onChange={(event) => { - setSimulationType(event.target.value); - }} - style={{ height: "2em", width: "100%", fontSize: "16px" }} - > - <option value="One Weight">One Weight</option> - <option value="Two Weights">Two Weights</option> - <option value="Inclined Plane">Inclined Plane</option> - <option value="Pendulum">Pendulum</option> - </select> - </div> - </div> - </div> - <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: VectorTemplate, 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> - ); - })} - {weight && ( - <Weight - adjustPendulumAngle={adjustPendulumAngle} - color={"red"} - displayXPosition={positionXDisplay} - displayXVelocity={velocityXDisplay} - displayYPosition={positionYDisplay} - displayYVelocity={velocityYDisplay} - elasticCollisions={elasticCollisions} - incrementTime={timer} - mass={1} - mode={mode} - noMovement={noMovement} - paused={simulationPaused} - pendulum={pendulum} - pendulumAngle={pendulumAngle} - pendulumLength={pendulumLength} - radius={50} - reset={simulationReset} - showForceMagnitudes={showForceMagnitudes} - setSketching={setSketching} - setDisplayXAcceleration={setAccelerationXDisplay} - setDisplayXPosition={setPositionXDisplay} - setDisplayXVelocity={setVelocityXDisplay} - setDisplayYAcceleration={setAccelerationYDisplay} - setDisplayYPosition={setPositionYDisplay} - setDisplayYVelocity={setVelocityYDisplay} - setPaused={setSimulationPaused} - setPendulumAngle={setPendulumAngle} - setPendulumLength={setPendulumLength} - setStartPendulumAngle={setStartPendulumAngle} - setUpdatedForces={setUpdatedForces} - showAcceleration={showAcceleration} - showForces={showForces} - showVelocity={showVelocity} - startForces={startForces} - startPosX={startPosX} - startPosY={startPosY} - timestepSize={0.002} - updateDisplay={displayChange} - updatedForces={updatedForces} - walls={wallPositions} - wedge={wedge} - wedgeHeight={wedgeHeight} - wedgeWidth={wedgeWidth} - coefficientOfKineticFriction={Number( - coefficientOfKineticFriction - )} - /> - )} - {twoWeights && ( - <Weight - adjustPendulumAngle={adjustPendulumAngle} - color={"blue"} - displayXPosition={positionXDisplay2} - displayXVelocity={velocityXDisplay2} - displayYPosition={positionYDisplay2} - displayYVelocity={velocityYDisplay2} - elasticCollisions={elasticCollisions} - incrementTime={timer} - mass={1} - mode={mode} - noMovement={noMovement} - paused={simulationPaused} - pendulum={pendulum} - pendulumAngle={pendulumAngle} - pendulumLength={pendulumLength} - radius={50} - reset={simulationReset} - showForceMagnitudes={showForceMagnitudes} - setSketching={setSketching} - setDisplayXAcceleration={setAccelerationXDisplay2} - setDisplayXPosition={setPositionXDisplay2} - setDisplayXVelocity={setVelocityXDisplay2} - setDisplayYAcceleration={setAccelerationYDisplay2} - setDisplayYPosition={setPositionYDisplay2} - setDisplayYVelocity={setVelocityYDisplay2} - setPaused={setSimulationPaused} - setPendulumAngle={setPendulumAngle} - setPendulumLength={setPendulumLength} - setStartPendulumAngle={setStartPendulumAngle} - setUpdatedForces={setUpdatedForces} - showAcceleration={showAcceleration} - showForces={showForces} - showVelocity={showVelocity} - startForces={startForces} - startPosX={startPosX2} - startPosY={startPosY2} - timestepSize={0.002} - updateDisplay={displayChange} - updatedForces={updatedForces} - walls={wallPositions} - wedge={wedge} - wedgeHeight={wedgeHeight} - wedgeWidth={wedgeWidth} - coefficientOfKineticFriction={Number( - coefficientOfKineticFriction - )} - /> - )} - {wedge && ( - <Wedge - startWidth={wedgeWidth} - startHeight={wedgeHeight} - startLeft={xMax * 0.5 - 200} - /> - )} - </div> - <div> - {wallPositions.map((element, index) => { - return ( - <Wall - key={index} - length={element.length} - xPos={element.xPos} - yPos={element.yPos} - angleInDegrees={element.angleInDegrees} - /> - ); - })} - </div> - </div> - </div> - <div className="mechanicsSimulationEquationContainer"> - <div className="mechanicsSimulationControls"> - <div> - {simulationPaused && ( - <button onClick={() => { - setSimulationPaused(false); - }} >START</button> - )} - {!simulationPaused && ( - <button onClick={() => { - setSimulationPaused(true); - }} >PAUSE</button> - )} - {simulationPaused && ( - <button onClick={() => { - setSimulationReset(!simulationReset); - }} >RESET</button> - )} - </div> - <div className="dropdownMenu"> - <select - value={mode} - onChange={(event) => { - setMode(event.target.value); - }} - style={{ height: "2em", width: "100%", fontSize: "16px" }} - > - <option value="Freeform">Freeform Mode</option> - <option value="Review">Review Mode</option> - <option value="Tutorial">Tutorial Mode</option> - </select> - </div> - </div> - {/* {mode == "Freeform" && - simulationElements.length > 0 && - simulationElements[0].pendulum && ( - <div className="mechanicsSimulationEquation"> - <table> - <tbody> - <tr> - <td> </td> - <td>Value</td> - </tr> - <tr> - <td>Potential Energy</td> - <td> - {Math.round( - pendulumLength * - (1 - Math.cos(pendulumAngle)) * - 9.81 * - 10 - ) / 10}{" "} - J - </td> - </tr> - <tr> - <td>Kinetic Energy</td> - <td> - {Math.round( - (Math.round( - pendulumLength * - (1 - Math.cos(startPendulumAngle)) * - 9.81 * - 10 - ) / - 10 - - Math.round( - pendulumLength * - (1 - Math.cos(pendulumAngle)) * - 9.81 * - 10 - ) / - 10) * - 10 - ) / 10}{" "} - J - </td> - </tr> - <tr> - <td> - <b>Total Energy</b> - </td> - <td> - {Math.round( - pendulumLength * - (1 - Math.cos(startPendulumAngle)) * - 9.81 * - 10 - ) / 10}{" "} - J - </td> - </tr> - </tbody> - </table> - </div> - )}*/} - </div> - </div> - {/* <CoordinateSystem top={window.innerHeight - 120} right={xMin + 90} /> */} - </div> - ); + render () { + return ( + <div><p>Hello world!</p></div> + ); + } + // <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> + // ); + // })} */} + // {weight && ( + // <Weight + // adjustPendulumAngle={adjustPendulumAngle} + // color={"red"} + // displayXPosition={positionXDisplay} + // displayXVelocity={velocityXDisplay} + // displayYPosition={positionYDisplay} + // displayYVelocity={velocityYDisplay} + // elasticCollisions={elasticCollisions} + // incrementTime={timer} + // mass={1} + // mode={mode} + // noMovement={noMovement} + // paused={simulationPaused} + // pendulum={pendulum} + // pendulumAngle={pendulumAngle} + // pendulumLength={pendulumLength} + // radius={50} + // reset={simulationReset} + // showForceMagnitudes={showForceMagnitudes} + // setSketching={setSketching} + // setDisplayXAcceleration={setAccelerationXDisplay} + // setDisplayXPosition={setPositionXDisplay} + // setDisplayXVelocity={setVelocityXDisplay} + // setDisplayYAcceleration={setAccelerationYDisplay} + // setDisplayYPosition={setPositionYDisplay} + // setDisplayYVelocity={setVelocityYDisplay} + // setPaused={setSimulationPaused} + // setPendulumAngle={setPendulumAngle} + // setPendulumLength={setPendulumLength} + // setStartPendulumAngle={setStartPendulumAngle} + // setUpdatedForces={setUpdatedForces} + // showAcceleration={showAcceleration} + // showForces={showForces} + // showVelocity={showVelocity} + // startForces={startForces} + // startPosX={startPosX} + // startPosY={startPosY} + // timestepSize={0.002} + // updateDisplay={displayChange} + // updatedForces={updatedForces} + // walls={wallPositions} + // wedge={wedge} + // wedgeHeight={wedgeHeight} + // wedgeWidth={wedgeWidth} + // coefficientOfKineticFriction={Number( + // coefficientOfKineticFriction + // )} + // /> + // )} + // {wedge && ( + // <Wedge + // startWidth={wedgeWidth} + // startHeight={wedgeHeight} + // startLeft={xMax * 0.5 - 200} + // /> + // )} + // </div> + // <div> + // {wallPositions.map((element, index) => { + // return ( + // <Wall + // key={index} + // length={element.length} + // xPos={element.xPos} + // yPos={element.yPos} + // angleInDegrees={element.angleInDegrees} + // /> + // ); + // })} + // </div> + // </div> + // </div> + // <div className="mechanicsSimulationEquationContainer"> + // <div className="mechanicsSimulationControls"> + // <div> + // {simulationPaused && ( + // <button onClick={() => { + // setSimulationPaused(false); + // }} >START</button> + // )} + // {!simulationPaused && ( + // <button onClick={() => { + // setSimulationPaused(true); + // }} >PAUSE</button> + // )} + // {simulationPaused && ( + // <button onClick={() => { + // setSimulationReset(!simulationReset); + // }} >RESET</button> + // )} + // </div> + // </div> + // </div> + // </div> + // </div> } - -export default App; |