diff options
author | brynnchernosky <56202540+brynnchernosky@users.noreply.github.com> | 2023-02-07 12:58:32 -0500 |
---|---|---|
committer | brynnchernosky <56202540+brynnchernosky@users.noreply.github.com> | 2023-02-07 12:58:32 -0500 |
commit | 2387225f18bd63f70569df7039af445064738836 (patch) | |
tree | 69439252d3967dd74d98985b826cd3fa25399a10 | |
parent | 983ffa5e10abd89448e8b3f9be65894c7b775d84 (diff) |
free weight and wedge work
-rw-r--r-- | src/client/views/nodes/PhysicsSimulationApp.tsx | 55 | ||||
-rw-r--r-- | src/client/views/nodes/PhysicsSimulationWall.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/PhysicsSimulationWedge.tsx | 21 | ||||
-rw-r--r-- | src/client/views/nodes/PhysicsSimulationWeight.tsx | 66 |
4 files changed, 68 insertions, 76 deletions
diff --git a/src/client/views/nodes/PhysicsSimulationApp.tsx b/src/client/views/nodes/PhysicsSimulationApp.tsx index a2490cce8..f31d92db2 100644 --- a/src/client/views/nodes/PhysicsSimulationApp.tsx +++ b/src/client/views/nodes/PhysicsSimulationApp.tsx @@ -71,8 +71,7 @@ export default class App extends React.Component<{}, IState> { xMax = 300; yMax = 300; color = `rgba(0,0,0,0.5)`; - radius = 50 - + radius = 0.1*this.yMax constructor(props: any) { super(props) @@ -112,8 +111,8 @@ export default class App extends React.Component<{}, IState> { wallPositions: [], wedge: false, wedgeAngle: 26, - wedgeHeight: Math.tan((26 * Math.PI) / 180) * 400, - wedgeWidth: 400, + wedgeHeight: Math.tan((26 * Math.PI) / 180) * this.xMax*0.6, + wedgeWidth: this.xMax*0.6, weight: false, } } @@ -219,45 +218,27 @@ export default class App extends React.Component<{}, IState> { let width = 0; let height = 0; if (angle < 50) { - width = 400; - height = Math.tan((angle * Math.PI) / 180) * 400; + 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 = 200; - height = Math.tan((angle * Math.PI) / 180) * 200; + width = this.xMax*0.3; + height = Math.tan((angle * Math.PI) / 180) * width; this.setState({wedgeWidth: width}) this.setState({wedgeHeight: height}) } else { - width = 100; - height = Math.tan((angle * Math.PI) / 180) * 100; + 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 yPos = (width - 50) * Math.tan((angle * Math.PI) / 180); - if (angle < 40) { - yPos += Math.sqrt(angle); - } else if (angle < 58) { - yPos += angle / 2; - } else if (angle < 68) { - yPos += angle; - } else if (angle < 70) { - yPos += angle * 1.3; - } else if (angle < 75) { - yPos += angle * 1.5; - } else if (angle < 78) { - yPos += angle * 2; - } else if (angle < 79) { - yPos += angle * 2.25; - } else if (angle < 80) { - yPos += angle * 2.6; - } else { - yPos += angle * 3; - } + let xPos = (this.xMax * 0.2)-this.radius; + let yPos = width * Math.tan((angle * Math.PI) / 180) - this.radius; - this.setState({startPosX: Math.round((this.xMax * 0.5 - 200) * 10) / 10}); + this.setState({startPosX: xPos}); this.setState({startPosY: this.getDisplayYPos(yPos)}); this.updateForcesWithFriction( Number(this.state.coefficientOfStaticFriction), @@ -308,7 +289,7 @@ export default class App extends React.Component<{}, IState> { componentDidMount() { // Add weight - this.addWeight() + this.addWedge() // Add listener for SHIFT key, which determines if sketch force arrow will be edited or deleted on click document.addEventListener("keydown", (e) => { @@ -477,7 +458,7 @@ export default class App extends React.Component<{}, IState> { pendulum={this.state.pendulum} pendulumAngle={this.state.pendulumAngle} pendulumLength={this.state.pendulumLength} - radius={50} + radius={this.radius} reset={this.state.simulationReset} showForceMagnitudes={this.state.showForceMagnitudes} setSketching={(val: boolean) => {this.setState({sketching: val})}} @@ -506,13 +487,19 @@ export default class App extends React.Component<{}, IState> { 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.5 - 200} + startLeft={this.xMax * 0.2} + xMax={this.xMax} + yMax={this.yMax} /> )} </div> diff --git a/src/client/views/nodes/PhysicsSimulationWall.tsx b/src/client/views/nodes/PhysicsSimulationWall.tsx index f6396d6a7..9283e8d46 100644 --- a/src/client/views/nodes/PhysicsSimulationWall.tsx +++ b/src/client/views/nodes/PhysicsSimulationWall.tsx @@ -18,7 +18,7 @@ export default class App extends React.Component<IWallProps> { } wallStyle = { - width: this.props.angleInDegrees == 0 ? this.props.length + "%" : "3%", + width: this.props.angleInDegrees == 0 ? this.props.length + "%" : "3%", height: this.props.angleInDegrees == 0 ? "3%" : this.props.length + "%", position: "absolute" as "absolute", left: this.props.xPos + "%", diff --git a/src/client/views/nodes/PhysicsSimulationWedge.tsx b/src/client/views/nodes/PhysicsSimulationWedge.tsx index b3988221c..43a4d69de 100644 --- a/src/client/views/nodes/PhysicsSimulationWedge.tsx +++ b/src/client/views/nodes/PhysicsSimulationWedge.tsx @@ -5,6 +5,8 @@ export interface IWedgeProps { startHeight: number; startWidth: number; startLeft: number; + xMax: number; + yMax: number; } interface IState { @@ -28,18 +30,19 @@ export default class Wedge extends React.Component<IWedgeProps, IState> { updateCoordinates() { const coordinatePair1 = - Math.round(this.state.left) + "," + Math.round(300 * 0.8) + " "; + Math.round(this.state.left) + "," + Math.round(this.props.yMax) + " "; const coordinatePair2 = Math.round(this.state.left + this.props.startWidth) + "," + - Math.round(300 * 0.8) + + Math.round(this.props.yMax) + " "; const coordinatePair3 = Math.round(this.state.left) + "," + - Math.round(300 * 0.8 - this.props.startHeight); + Math.round(this.props.yMax - this.props.startHeight); const coord = coordinatePair1 + coordinatePair2 + coordinatePair3; this.setState({coordinates: coord}); + console.log("coordinates: ", coord) } componentDidMount() { @@ -47,7 +50,9 @@ export default class Wedge extends React.Component<IWedgeProps, IState> { } componentDidUpdate(prevProps: Readonly<IWedgeProps>, prevState: Readonly<IState>, snapshot?: any): void { - this.updateCoordinates(); + if (prevState.coordinates != this.state.coordinates) { + this.updateCoordinates(); + } if (prevProps.startHeight != this.props.startHeight || prevProps.startWidth != this.props.startWidth) { this.setState({angleInRadians: Math.atan(this.props.startHeight / this.props.startWidth)}); } @@ -56,10 +61,10 @@ export default class Wedge extends React.Component<IWedgeProps, IState> { render() { return ( <div> - <div style={{ position: "absolute", left: "0", top: "0", zIndex: -5 }}> + <div style={{ position: "absolute", left: "0", top: "0" }}> <svg - width={300 * 0.7 + "px"} - height={300 * 0.8 + "px"} + width={this.props.xMax + "px"} + height={this.props.yMax + "px"} > <polygon points={this.state.coordinates} style={{ fill: "burlywood" }} /> </svg> @@ -70,7 +75,7 @@ export default class Wedge extends React.Component<IWedgeProps, IState> { position: "absolute", zIndex: 500, left: Math.round(this.state.left + this.props.startWidth - 80) + "px", - top: Math.round(300 * 0.8 - 40) + "px", + top: Math.round(this.props.yMax - 40) + "px", }} > {Math.round(((this.state.angleInRadians * 180) / Math.PI) * 100) / 100}° diff --git a/src/client/views/nodes/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsSimulationWeight.tsx index 92d65cf3d..63f8c965f 100644 --- a/src/client/views/nodes/PhysicsSimulationWeight.tsx +++ b/src/client/views/nodes/PhysicsSimulationWeight.tsx @@ -52,6 +52,10 @@ export interface IWeightProps { coefficientOfKineticFriction: number; wedgeWidth: number; wedgeHeight: number; + xMax: number; + yMax: number; + xMin: number; + yMin: number; } interface IState { @@ -92,10 +96,6 @@ export default class Weight extends React.Component<IWeightProps, IState> { magnitude: this.props.mass * 9.81, directionInDegrees: 270, }; - xMax = 300; - yMax = 300; - xMin = 0; - yMin = 0; // Var weightStyle = { @@ -116,10 +116,10 @@ export default class Weight extends React.Component<IWeightProps, IState> { // Helper function to go between display and real values getDisplayYPos = (yPos: number) => { - return this.yMax - yPos - 2 * this.props.radius + 5; + return this.props.yMax - yPos - 2 * this.props.radius + 5; }; getYPosFromDisplay = (yDisplay: number) => { - return this.yMax - yDisplay - 2 * this.props.radius + 5; + return this.props.yMax - yDisplay - 2 * this.props.radius + 5; }; // Set display values based on real values @@ -161,7 +161,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { 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); + x = Math.min(x, this.props.xMax - 2 * this.props.radius); this.setState({updatedStartPosX: x}) this.setState({xPosition: x}) this.props.setDisplayXPosition(x); @@ -170,7 +170,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { 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); + y = Math.min(y, this.props.yMax - 2 * this.props.radius); this.props.setDisplayYPosition(y); let coordinatePosition = this.getYPosFromDisplay(y); this.setState({updatedStartPosY: coordinatePosition}) @@ -235,7 +235,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { length * Math.cos(((90 - this.props.adjustPendulumAngle.angle) * Math.PI) / 180); const y = length * Math.sin(((90 - this.props.adjustPendulumAngle.angle) * Math.PI) / 180); - const xPos = this.xMax / 2 - x - this.props.radius; + 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}) @@ -343,7 +343,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { if (!this.props.pendulum) { return this.props.updatedForces; } - const x = this.xMax / 2 - xPos - this.props.radius; + const x = this.props.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) { @@ -423,7 +423,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { if (this.state.yVelocity > 0) { this.props.walls.forEach((wall) => { if (wall.angleInDegrees == 0) { - const groundY = (wall.yPos / 100) * this.yMax; + const groundY = (wall.yPos / 100) * this.props.yMax; if (maxY >= groundY) { console.log('collision with ground ', wall, maxY) if (this.props.elasticCollisions) { @@ -537,13 +537,13 @@ export default class Weight extends React.Component<IWeightProps, IState> { e.preventDefault(); if (this.state.dragging) { let newY = this.state.yPosition + e.clientY - this.state.clickPositionY; - if (newY > this.yMax - 2 * this.props.radius) { - newY = this.yMax - 2 * this.props.radius; + if (newY > this.props.yMax - 2 * this.props.radius) { + newY = this.props.yMax - 2 * this.props.radius; } let newX = this.state.xPosition + e.clientX - this.state.clickPositionX; - if (newX > this.xMax - 2 * this.props.radius) { - newX = this.xMax - 2 * this.props.radius; + if (newX > this.props.xMax - 2 * this.props.radius) { + newX = this.props.xMax - 2 * this.props.radius; } else if (newX < 0) { newX = 0; } @@ -551,7 +551,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.yMax - 2 * this.props.radius - newY + 5) * 100) / 100) + this.props.setDisplayYPosition(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(); @@ -565,18 +565,18 @@ export default class Weight extends React.Component<IWeightProps, IState> { } this.setState({dragging: false}); let newY = this.state.yPosition + e.clientY - this.state.clickPositionY; - if (newY > this.yMax - 2 * this.props.radius) { - newY = this.yMax - 2 * this.props.radius; + if (newY > this.props.yMax - 2 * this.props.radius) { + newY = this.props.yMax - 2 * this.props.radius; } let newX = this.state.xPosition + e.clientX - this.state.clickPositionX; - if (newX > this.xMax - 2 * this.props.radius) { - newX = this.xMax - 2 * this.props.radius; + if (newX > this.props.xMax - 2 * this.props.radius) { + newX = this.props.xMax - 2 * this.props.radius; } else if (newX < 0) { newX = 0; } if (this.props.pendulum) { - const x = this.xMax / 2 - newX - this.props.radius; + const x = this.props.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) { @@ -620,11 +620,11 @@ export default class Weight extends React.Component<IWeightProps, IState> { zIndex: -2, }} > - <svg width={this.xMax + "px"} height={300 + "px"}> + <svg width={this.props.xMax + "px"} height={300 + "px"}> <line x1={this.state.xPosition + this.props.radius} y1={this.state.yPosition + this.props.radius} - x2={this.xMax / 2} + x2={this.props.xMax / 2} y2={-5} stroke={"#deb887"} strokeWidth="10" @@ -647,7 +647,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { style={{ position: "absolute", zIndex: -1, - left: this.xMax / 2 + "px", + left: this.props.xMax / 2 + "px", top: 30 + "px", backgroundColor: this.labelBackgroundColor, }} @@ -669,7 +669,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { top: 0, }} > - <svg width={this.xMax + "px"} height={300 + "px"}> + <svg width={this.props.xMax + "px"} height={300 + "px"}> <defs> <marker id="accArrow" @@ -738,7 +738,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { top: 0, }} > - <svg width={this.xMax + "px"} height={300 + "px"}> + <svg width={this.props.xMax + "px"} height={300 + "px"}> <defs> <marker id="velArrow" @@ -815,10 +815,10 @@ export default class Weight extends React.Component<IWeightProps, IState> { } else { labelTop -= 40; } - 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); + labelTop = Math.min(labelTop, this.props.yMax + 50); + labelTop = Math.max(labelTop, this.props.yMin); + labelLeft = Math.min(labelLeft, this.props.xMax - 60); + labelLeft = Math.max(labelLeft, this.props.xMin); return ( <div key={index}> @@ -827,12 +827,12 @@ export default class Weight extends React.Component<IWeightProps, IState> { pointerEvents: "none", position: "absolute", zIndex: -1, - left: this.xMin, - top: this.yMin, + left: this.props.xMin, + top: this.props.yMin, }} > <svg - width={this.xMax - this.xMin + "px"} + width={this.props.xMax - this.props.xMin + "px"} height={300 + "px"} > <defs> |