aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/nodes/PhysicsSimulationApp.tsx461
-rw-r--r--src/client/views/nodes/PhysicsSimulationWeight.tsx397
2 files changed, 409 insertions, 449 deletions
diff --git a/src/client/views/nodes/PhysicsSimulationApp.tsx b/src/client/views/nodes/PhysicsSimulationApp.tsx
index 414d61809..2277c7875 100644
--- a/src/client/views/nodes/PhysicsSimulationApp.tsx
+++ b/src/client/views/nodes/PhysicsSimulationApp.tsx
@@ -1,8 +1,8 @@
import React = require('react');
import "./PhysicsSimulationBox.scss";
-import { IForce, Weight } from "./PhysicsSimulationWeight";
-import {Wall, IWallProps } from "./PhysicsSimulationWall"
-import {Wedge} from "./PhysicsSimulationWedge"
+import Weight from "./PhysicsSimulationWeight";
+import Wall from "./PhysicsSimulationWall"
+import Wedge from "./PhysicsSimulationWedge"
import { props, any } from 'bluebird';
import { render } from 'react-dom';
@@ -329,235 +329,232 @@ export default class App extends React.Component<{}, IState> {
render () {
return (
- <p>Hello world!</p>
- // <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>
+ <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}
+ 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
+ )}
+ />
+ )} */}
+ {this.state.wedge && (
+ <Wedge
+ startWidth={this.state.wedgeWidth}
+ startHeight={this.state.wedgeHeight}
+ startLeft={this.xMax * 0.5 - 200}
+ />
+ )}
+ </div>
+ <div>
+ {this.state.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>
+ {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>
+ )}
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
);
}
}
diff --git a/src/client/views/nodes/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsSimulationWeight.tsx
index cc024f29a..d234c1395 100644
--- a/src/client/views/nodes/PhysicsSimulationWeight.tsx
+++ b/src/client/views/nodes/PhysicsSimulationWeight.tsx
@@ -1,6 +1,8 @@
+import React from "react";
import { useEffect, useState } from "react";
+import { render } from "react-dom";
import { IWallProps } from "./PhysicsSimulationWall";
-import { Wedge } from "./PhysicsSimulationWedge";
+import Wedge from "./PhysicsSimulationWedge";
export interface IForce {
description: string;
@@ -35,8 +37,6 @@ export interface IWeightProps {
setPendulumLength: (val: number) => any;
setStartPendulumAngle: (val: number) => any;
showAcceleration: boolean;
- mode: string;
- noMovement: boolean;
pendulumAngle: number;
setSketching: (val: boolean) => any;
showForces: boolean;
@@ -56,154 +56,121 @@ export interface IWeightProps {
wedgeHeight: number;
}
-export const Weight = (props: IWeightProps) => {
- const {
- adjustPendulumAngle,
- color,
- displayXPosition,
- displayYPosition,
- displayXVelocity,
- displayYVelocity,
- elasticCollisions,
- startForces,
- incrementTime,
- mass,
- paused,
- pendulum,
- pendulumLength,
- wedge,
- radius,
- mode,
- noMovement,
- pendulumAngle,
- reset,
- setSketching,
- setDisplayXAcceleration,
- setDisplayXPosition,
- setDisplayXVelocity,
- setDisplayYAcceleration,
- setDisplayYPosition,
- setDisplayYVelocity,
- setPaused,
- setPendulumAngle,
- setPendulumLength,
- setStartPendulumAngle,
- showAcceleration,
- showForces,
- showForceMagnitudes,
- showVelocity,
- startPosX,
- startPosY,
- startVelX,
- startVelY,
- timestepSize,
- updateDisplay,
- updatedForces,
- setUpdatedForces,
- walls,
- coefficientOfKineticFriction,
- wedgeWidth,
- wedgeHeight,
- } = props;
+interface IState {
+ dragging: boolean,
+ kineticFriction: boolean,
+ updatedStartPosX: number,
+ updatedStartPosY: number,
+ xPosition: number,
+ yPosition: number,
+ xVelocity: number,
+ yVelocity: number,
+}
+export default class Weight extends React.Component<IWeightProps, IState> {
+
+ constructor(props: any) {
+ super(props)
+ this.state = {
+ dragging: false,
+ kineticFriction: false,
+ updatedStartPosX: this.props.startPosX,
+ updatedStartPosY: this.props.startPosY,
+ xPosition: this.props.startPosX,
+ yPosition: this.props.startPosY,
+ xVelocity: this.props.startVelX ? this.props.startVelX: 0,
+ yVelocity: this.props.startVelY ? this.props.startVelY: 0,
+ }
+ }
// Constants
- const draggable = !wedge && mode == "Freeform";
- const epsilon = 0.0001;
-
- const forceOfGravity: IForce = {
+ draggable = !this.props.wedge;
+ epsilon = 0.0001;
+ forceOfGravity: IForce = {
description: "Gravity",
- magnitude: mass * 9.81,
+ magnitude: this.props.mass * 9.81,
directionInDegrees: 270,
};
- const xMax = window.innerWidth * 0.7;
- const xMin = 0;
- const yMax = window.innerHeight * 0.8;
- const yMin = 0;
-
- // State hooks
- const [dragging, setDragging] = useState(false);
- const [kineticFriction, setKineticFriction] = useState(false);
- const [updatedStartPosX, setUpdatedStartPosX] = useState(startPosX);
- const [updatedStartPosY, setUpdatedStartPosY] = useState(startPosY);
- const [xPosition, setXPosition] = useState(startPosX);
- const [xVelocity, setXVelocity] = useState(startVelX ?? 0);
- const [yPosition, setYPosition] = useState(startPosY);
- const [yVelocity, setYVelocity] = useState(startVelY ?? 0);
+ xMax = window.innerWidth * 0.7;
+ xMin = 0;
+ yMax = window.innerHeight * 0.8;
+ yMin = 0;
// Helper function to go between display and real values
const getDisplayYPos = (yPos: number) => {
- return yMax - yPos - 2 * radius + 5;
+ return this.yMax - yPos - 2 * this.props.radius + 5;
};
const getYPosFromDisplay = (yDisplay: number) => {
- return yMax - yDisplay - 2 * radius + 5;
+ return this.yMax - yDisplay - 2 * this.props.radius + 5;
};
// Set display values based on real values
const setYPosDisplay = (yPos: number) => {
- const displayPos = getDisplayYPos(yPos);
- setDisplayYPosition(Math.round(displayPos * 100) / 100);
+ const displayPos = this.getDisplayYPos(yPos);
+ this.props.setDisplayYPosition(Math.round(displayPos * 100) / 100)
};
const setXPosDisplay = (xPos: number) => {
- setDisplayXPosition(Math.round(xPos * 100) / 100);
+ this.props.setDisplayXPosition(Math.round(xPos * 100) / 100);
};
const setYVelDisplay = (yVel: number) => {
- setDisplayYVelocity((-1 * Math.round(yVel * 100)) / 100);
+ this.props.setDisplayYVelocity((-1 * Math.round(yVel * 100)) / 100);
};
const setXVelDisplay = (xVel: number) => {
- setDisplayXVelocity(Math.round(xVel * 100) / 100);
+ this.props.setDisplayXVelocity(Math.round(xVel * 100) / 100);
};
const setDisplayValues = (
- xPos: number = xPosition,
- yPos: number = yPosition,
- xVel: number = xVelocity,
- yVel: number = yVelocity
+ xPos: number = this.state.xPosition,
+ yPos: number = this.state.yPosition,
+ xVel: number = this.state.xVelocity,
+ yVel: number = this.state.yVelocity
) => {
- setYPosDisplay(yPos);
- setXPosDisplay(xPos);
- setYVelDisplay(yVel);
- setXVelDisplay(xVel);
- setDisplayYAcceleration(
- (-1 * Math.round(getNewAccelerationY(updatedForces) * 100)) / 100
+ this.setYPosDisplay(yPos);
+ this.setXPosDisplay(xPos);
+ this.setYVelDisplay(yVel);
+ this.setXVelDisplay(xVel);
+ this.props.setDisplayYAcceleration(
+ (-1 * Math.round(getNewAccelerationY(this.props.updatedForces) * 100)) / 100
);
- setDisplayXAcceleration(
- Math.round(getNewAccelerationX(updatedForces) * 100) / 100
+ this.props.setDisplayXAcceleration(
+ Math.round(getNewAccelerationX(this.props.updatedForces) * 100) / 100
);
};
// When display values updated by user, update real values
- useEffect(() => {
- if (updateDisplay.xDisplay != xPosition) {
- let x = updateDisplay.xDisplay;
- x = Math.max(0, x);
- x = Math.min(x, xMax - 2 * radius);
- setUpdatedStartPosX(x);
- setXPosition(x);
- setDisplayXPosition(x);
- }
-
- if (updateDisplay.yDisplay != getDisplayYPos(yPosition)) {
- let y = updateDisplay.yDisplay;
- y = Math.max(0, y);
- y = Math.min(y, yMax - 2 * radius);
- setDisplayYPosition(y);
- let coordinatePosition = getYPosFromDisplay(y);
- setUpdatedStartPosY(coordinatePosition);
- setYPosition(coordinatePosition);
- }
-
- if (displayXVelocity != xVelocity) {
- let x = displayXVelocity;
- setXVelocity(x);
- setDisplayXVelocity(x);
- }
-
- if (displayYVelocity != -yVelocity) {
- let y = displayYVelocity;
- setYVelocity(-y);
- setDisplayYVelocity(y);
+ componentDidUpdate(prevProps: Readonly<IWeightProps>, prevState: Readonly<IState>, snapshot?: any): void {
+ if (this.props.updateDisplay != prevProps.updateDisplay) {
+ if (this.props.updateDisplay.xDisplay != this.state.xPosition) {
+ let x = this.props.updateDisplay.xDisplay;
+ x = Math.max(0, x);
+ x = Math.min(x, this.xMax - 2 * this.props.radius);
+ this.setState({updatedStartPosX: x})
+ this.setState({xPosition: x})
+ this.props.setDisplayXPosition(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.yMax - 2 * this.props.radius);
+ this.props.setDisplayYPosition(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;
+ this.setState({xVelocity: x})
+ this.props.setDisplayXVelocity(x);
+ }
+
+ if (this.props.displayYVelocity != this.state.yVelocity) {
+ let y = this.props.displayYVelocity;
+ this.setState({yVelocity: -y})
+ this.props.setDisplayXVelocity(y);
+ }
}
- }, [updateDisplay]);
+ }
// Check for collisions and update
useEffect(() => {
@@ -264,7 +231,7 @@ export const Weight = (props: IWeightProps) => {
newXAcc +=
(force.magnitude *
Math.cos((force.directionInDegrees * Math.PI) / 180)) /
- mass;
+ this.props.mass;
});
return newXAcc;
};
@@ -276,7 +243,7 @@ export const Weight = (props: IWeightProps) => {
(-1 *
(force.magnitude *
Math.sin((force.directionInDegrees * Math.PI) / 180))) /
- mass;
+ this.props.mass;
});
return newYAcc;
};
@@ -287,11 +254,11 @@ export const Weight = (props: IWeightProps) => {
xVel: number,
yVel: number
) => {
- if (!pendulum) {
- return updatedForces;
+ if (!this.props.pendulum) {
+ return this.state.updatedForces;
}
- const x = xMax / 2 - xPos - radius;
- const y = yPos + radius + 5;
+ const x = this.xMax / 2 - xPos - this.props.radius;
+ const y = yPos + this.props.radius + 5;
let angle = (Math.atan(y / x) * 180) / Math.PI;
if (angle < 0) {
angle += 180;
@@ -306,8 +273,8 @@ export const Weight = (props: IWeightProps) => {
setPendulumLength(Math.sqrt(x * x + y * y));
const mag =
- mass * 9.81 * Math.cos((oppositeAngle * Math.PI) / 180) +
- (mass * (xVel * xVel + yVel * yVel)) / pendulumLength;
+ this.props.mass * 9.81 * Math.cos((oppositeAngle * Math.PI) / 180) +
+ (this.props.mass * (xVel * xVel + yVel * yVel)) / pendulumLength;
const forceOfTension: IForce = {
description: "Tension",
@@ -315,24 +282,24 @@ export const Weight = (props: IWeightProps) => {
directionInDegrees: angle,
};
- return [forceOfGravity, forceOfTension];
+ return [this.forceOfGravity, forceOfTension];
};
const getNewPosition = (pos: number, vel: number) => {
- return pos + vel * timestepSize;
+ return pos + vel * this.props.timestepSize;
};
const getNewVelocity = (vel: number, acc: number) => {
- return vel + acc * timestepSize;
+ return vel + acc * this.props.timestepSize;
};
const checkForCollisionsWithWall = () => {
let collision = false;
- const minX = xPosition;
- const maxX = xPosition + 2 * radius;
+ const minX = this.state.xPosition;
+ const maxX = this.state.xPosition + 2 * this.props.radius;
const containerWidth = window.innerWidth;
- if (xVelocity != 0) {
- walls.forEach((wall) => {
+ if (this.state.xVelocity != 0) {
+ this.props.walls.forEach((wall) => {
if (wall.angleInDegrees == 90) {
const wallX = (wall.xPos / 100) * window.innerWidth;
if (wall.xPos < 0.35) {
@@ -542,43 +509,39 @@ export const Weight = (props: IWeightProps) => {
setYPosDisplay(startPosY);
}, [startPosY]);
- return (
+ render () {
+ return (
<div style={{ zIndex: -1000 }}>
<div
className="weightContainer"
onPointerDown={(e) => {
- if (draggable) {
+ if (this.props.draggable) {
e.preventDefault();
- setPaused(true);
- setDragging(true);
+ this.props.setPaused(true);
+ this.setState({dragging: true});
setClickPositionX(e.clientX);
setClickPositionY(e.clientY);
- } else if (mode == "Review") {
- setSketching(true);
}
}}
onPointerMove={(e) => {
e.preventDefault();
- if (dragging) {
- let newY = yPosition + e.clientY - clickPositionY;
- if (newY > yMax - 2 * radius) {
- newY = yMax - 2 * radius;
+ if (this.state.dragging) {
+ let newY = this.state.yPosition + e.clientY - clickPositionY;
+ if (newY > this.yMax - 2 * this.props.radius) {
+ newY = this.yMax - 2 * this.props.radius;
}
- let newX = xPosition + e.clientX - clickPositionX;
- if (newX > xMax - 2 * radius) {
- newX = xMax - 2 * radius;
+ let newX = this.state.xPosition + e.clientX - clickPositionX;
+ if (newX > this.xMax - 2 * this.props.radius) {
+ newX = this.xMax - 2 * this.props.radius;
} else if (newX < 0) {
newX = 0;
}
-
- setXPosition(newX);
- setYPosition(newY);
- setUpdatedStartPosX(newX);
- setUpdatedStartPosY(newY);
- setDisplayYPosition(
- Math.round((yMax - 2 * radius - newY + 5) * 100) / 100
- );
+ this.setState({xPosition: newX})
+ this.setState({yPosition: newY})
+ this.setState({updatedStartPosX: newX})
+ this.setState({updatedStartPosY: newY})
+ this.setState({displayYPosition: Math.round((yMax - 2 * radius - newY + 5) * 100) / 100})
setClickPositionX(e.clientX);
setClickPositionY(e.clientY);
setDisplayValues();
@@ -591,20 +554,20 @@ export const Weight = (props: IWeightProps) => {
resetEverything();
}
setDragging(false);
- let newY = yPosition + e.clientY - clickPositionY;
- if (newY > yMax - 2 * radius) {
- newY = yMax - 2 * radius;
+ let newY = this.state.yPosition + e.clientY - clickPositionY;
+ if (newY > this.yMax - 2 * this.props.radius) {
+ newY = this.yMax - 2 * this.props.radius;
}
let newX = xPosition + e.clientX - clickPositionX;
- if (newX > xMax - 2 * radius) {
- newX = xMax - 2 * radius;
+ if (newX > this.xMax - 2 * this.props.radius) {
+ newX = this.xMax - 2 * this.props.radius;
} else if (newX < 0) {
newX = 0;
}
- if (pendulum) {
- const x = xMax / 2 - newX - radius;
- const y = newY + radius + 5;
+ if (this.state.pendulum) {
+ const x = this.xMax / 2 - newX - this.props.radius;
+ const y = newY + this.props.radius + 5;
let angle = (Math.atan(y / x) * 180) / Math.PI;
if (angle < 0) {
angle += 180;
@@ -615,20 +578,19 @@ export const Weight = (props: IWeightProps) => {
}
const pendulumLength = Math.sqrt(x * x + y * y);
- setPendulumAngle(oppositeAngle);
- setPendulumLength(Math.sqrt(x * x + y * y));
+ this.props.setPendulumAngle(oppositeAngle);
+ this.props.setPendulumLength(Math.sqrt(x * x + y * y));
const mag = 9.81 * Math.cos((oppositeAngle * Math.PI) / 180);
const forceOfTension: IForce = {
description: "Tension",
magnitude: mag,
directionInDegrees: angle,
};
-
- setKineticFriction(false);
- setXVelocity(startVelX ?? 0);
- setYVelocity(startVelY ?? 0);
+ this.setState({kineticFriction: false})
+ this.setState({xVelocity: startVelX ?? 0})
+ this.setState({yVelocity: startVelY ?? 0})
setDisplayValues();
- setUpdatedForces([forceOfGravity, forceOfTension]);
+ this.setState({updatedForces :[forceOfGravity, forceOfTension]});
}
}
}}
@@ -637,7 +599,7 @@ export const Weight = (props: IWeightProps) => {
<p className="weightLabel">{mass} kg</p>
</div>
</div>
- {pendulum && (
+ {this.state.pendulum && (
<div
className="rod"
style={{
@@ -648,45 +610,45 @@ export const Weight = (props: IWeightProps) => {
zIndex: -2,
}}
>
- <svg width={xMax + "px"} height={window.innerHeight + "px"}>
+ <svg width={this.xMax + "px"} height={window.innerHeight + "px"}>
<line
- x1={xPosition + radius}
- y1={yPosition + radius}
- x2={xMax / 2}
+ x1={this.state.xPosition + this.props.radius}
+ y1={this.state.yPosition + this.props.radius}
+ x2={this.xMax / 2}
y2={-5}
stroke={"#deb887"}
strokeWidth="10"
/>
</svg>
- {!dragging && (
+ {!this.state.dragging && (
<div>
<p
style={{
position: "absolute",
zIndex: 5,
- left: xPosition + "px",
- top: yPosition - 70 + "px",
+ left: this.state.xPosition + "px",
+ top: this.state.yPosition - 70 + "px",
backgroundColor: labelBackgroundColor,
}}
>
- {Math.round(pendulumLength)} m
+ {Math.round(this.props.pendulumLength)} m
</p>
<p
style={{
position: "absolute",
zIndex: -1,
- left: xMax / 2 + "px",
+ left: this.xMax / 2 + "px",
top: 30 + "px",
backgroundColor: labelBackgroundColor,
}}
>
- {Math.round(pendulumAngle * 100) / 100}°
+ {Math.round(this.props.pendulumAngle * 100) / 100}°
</p>
</div>
)}
</div>
)}
- {!dragging && showAcceleration && (
+ {!this.state.dragging && this.props.showAcceleration && (
<div>
<div
style={{
@@ -697,7 +659,7 @@ export const Weight = (props: IWeightProps) => {
top: 0,
}}
>
- <svg width={xMax + "px"} height={window.innerHeight + "px"}>
+ <svg width={this.xMax + "px"} height={window.innerHeight + "px"}>
<defs>
<marker
id="accArrow"
@@ -712,10 +674,10 @@ export const Weight = (props: IWeightProps) => {
</marker>
</defs>
<line
- x1={xPosition + radius}
- y1={yPosition + radius}
- x2={xPosition + radius + getNewAccelerationX(updatedForces) * 5}
- y2={yPosition + radius + getNewAccelerationY(updatedForces) * 5}
+ x1={this.state.xPosition + this.props.radius}
+ y1={this.state.yPosition + this.props.radius}
+ x2={this.state.xPosition + this.props.radius + getNewAccelerationX(this.state.updatedForces) * 5}
+ y2={this.state.yPosition + this.props.radius + getNewAccelerationY(this.state.updatedForces) * 5}
stroke={"green"}
strokeWidth="5"
markerEnd="url(#accArrow)"
@@ -726,15 +688,15 @@ export const Weight = (props: IWeightProps) => {
pointerEvents: "none",
position: "absolute",
left:
- xPosition +
- radius +
- getNewAccelerationX(updatedForces) * 5 +
+ this.state.xPosition +
+ this.props.radius +
+ getNewAccelerationX(this.state.updatedForces) * 5 +
25 +
"px",
top:
- yPosition +
- radius +
- getNewAccelerationY(updatedForces) * 5 +
+ this.state.yPosition +
+ this.props.radius +
+ getNewAccelerationY(this.state.updatedForces) * 5 +
25 +
"px",
zIndex: -1,
@@ -745,8 +707,8 @@ export const Weight = (props: IWeightProps) => {
{Math.round(
100 *
Math.sqrt(
- Math.pow(getNewAccelerationX(updatedForces) * 3, 2) +
- Math.pow(getNewAccelerationY(updatedForces) * 3, 2)
+ Math.pow(getNewAccelerationX(this.state.updatedForces) * 3, 2) +
+ Math.pow(getNewAccelerationY(this.state.updatedForces) * 3, 2)
)
) / 100}{" "}
m/s<sup>2</sup>
@@ -755,7 +717,7 @@ export const Weight = (props: IWeightProps) => {
</div>
</div>
)}
- {!dragging && showVelocity && (
+ {!this.state.dragging && this.props.showVelocity && (
<div>
<div
style={{
@@ -766,7 +728,7 @@ export const Weight = (props: IWeightProps) => {
top: 0,
}}
>
- <svg width={xMax + "px"} height={window.innerHeight + "px"}>
+ <svg width={this.xMax + "px"} height={window.innerHeight + "px"}>
<defs>
<marker
id="velArrow"
@@ -781,10 +743,10 @@ export const Weight = (props: IWeightProps) => {
</marker>
</defs>
<line
- x1={xPosition + radius}
- y1={yPosition + radius}
- x2={xPosition + radius + xVelocity * 3}
- y2={yPosition + radius + yVelocity * 3}
+ x1={this.state.xPosition + this.props.radius}
+ y1={this.state.yPosition + this.props.radius}
+ x2={this.state.xPosition + this.props.radius + this.state.xVelocity * 3}
+ y2={this.state.yPosition + this.props.radius + this.state.yVelocity * 3}
stroke={"blue"}
strokeWidth="5"
markerEnd="url(#velArrow)"
@@ -794,15 +756,15 @@ export const Weight = (props: IWeightProps) => {
style={{
pointerEvents: "none",
position: "absolute",
- left: xPosition + radius + xVelocity * 3 + 25 + "px",
- top: yPosition + radius + yVelocity * 3 + "px",
+ left: this.state.xPosition + this.props.radius + this.state.xVelocity * 3 + 25 + "px",
+ top: this.state.yPosition + this.props.radius + this.state.yVelocity * 3 + "px",
zIndex: -1,
lineHeight: 0.5,
}}
>
<p>
{Math.round(
- 100 * Math.sqrt(xVelocity * xVelocity + yVelocity * yVelocity)
+ 100 * Math.sqrt(this.state.xVelocity**2 + this.state.yVelocity**2)
) / 100}{" "}
m/s
</p>
@@ -810,14 +772,14 @@ export const Weight = (props: IWeightProps) => {
</div>
</div>
)}
- {!dragging &&
- showForces &&
- updatedForces.map((force, index) => {
- if (force.magnitude < epsilon) {
+ {!this.state.dragging &&
+ this.props.showForces &&
+ this.props.updatedForces.map((force, index) => {
+ if (force.magnitude < this.epsilon) {
return;
}
- let arrowStartY: number = yPosition + radius;
- const arrowStartX: number = xPosition + radius;
+ let arrowStartY: number = this.state.yPosition + this.props.radius;
+ const arrowStartX: number = this.state.xPosition + this.props.radius;
let arrowEndY: number =
arrowStartY -
Math.abs(force.magnitude) *
@@ -843,10 +805,10 @@ export const Weight = (props: IWeightProps) => {
} else {
labelTop -= 40;
}
- labelTop = Math.min(labelTop, yMax + 50);
- labelTop = Math.max(labelTop, yMin);
- labelLeft = Math.min(labelLeft, xMax - 60);
- labelLeft = Math.max(labelLeft, xMin);
+ labelTop = Math.min(labelTop, this.yMax + 50);
+ labelTop = Math.max(labelTop, this.yMin);
+ labelLeft = Math.min(labelLeft, this.xMax - 60);
+ labelLeft = Math.max(labelLeft, this.xMin);
return (
<div key={index}>
@@ -908,5 +870,6 @@ export const Weight = (props: IWeightProps) => {
);
})}
</div>
- );
+ );
+ }
};