From c2a49f4f0005ea12a7664ea69911e1301a3a514b Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 18 May 2024 21:04:49 -0400 Subject: [PATCH 1/4] working on rocket interception --- frontend/src/pages/scenario.jsx | 87 ++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 17 deletions(-) diff --git a/frontend/src/pages/scenario.jsx b/frontend/src/pages/scenario.jsx index 8f95126..c111915 100644 --- a/frontend/src/pages/scenario.jsx +++ b/frontend/src/pages/scenario.jsx @@ -16,6 +16,7 @@ const CANVAS_HEIGHT = window.innerHeight; const EARTH_X = CANVAS_WIDTH - 100; const EARTH_Y = CANVAS_HEIGHT / 2; const SIMULATION_AREA_MULTIPLIER = 2; // Extend the simulation area +const ROCKET_SPEED = 0.1; // Speed of the rocket function Scenario() { const [asteroid, setAsteroid] = useState({ @@ -35,6 +36,7 @@ function Scenario() { const [simulationResult, setSimulationResult] = useState(''); const [strategy, setStrategy] = useState(''); // State for selected strategy const [timeStep, setTimeStep] = useState(100); // State for time step + const [rocket, setRocket] = useState({ active: false, x: EARTH_X, y: EARTH_Y, trajectory: [], targetX: 0, targetY: 0 }); useEffect(() => { const fetchAsteroids = async () => { @@ -72,23 +74,13 @@ function Scenario() { }); setTrajectoryPoints([]); calculateForecastPath(size, speed, Math.PI / 9, mass); // Calculate the forecast path once + setRocket({ active: false, x: EARTH_X, y: EARTH_Y, trajectory: [], targetX: 0, targetY: 0 }); }; const handleAsteroidSelect = (event) => { setAsteroidData(event.target.value); }; - const applyDeflectionStrategy = (vx, vy) => { - if (strategy === 'Nuclear Detonation') { - vx += 0.5; // Example effect - } else if (strategy === 'Kinetic Impact') { - vx += 0.25; // Example effect - } else if (strategy === 'Gravity Tractor') { - vy -= 0.1; // Example effect - } - return { vx, vy }; - }; - const calculateForecastPath = (size, speed, angle, mass) => { let x = 100; let y = CANVAS_HEIGHT / 2 - 100; @@ -135,6 +127,31 @@ function Scenario() { setForecastPoints(points); }; + const calculateInterceptionPoint = (rocketSpeed, asteroidX, asteroidY, asteroidVX, asteroidVY) => { + let interceptX = asteroidX; + let interceptY = asteroidY; + let closestApproach = Infinity; + + for (let t = 0; t < 5000; t += timeStep) { + const futureAsteroidX = asteroidX + asteroidVX * t; + const futureAsteroidY = asteroidY + asteroidVY * t; + + const dx = futureAsteroidX - EARTH_X; + const dy = futureAsteroidY - EARTH_Y; + const distanceToAsteroid = Math.sqrt(dx * dx + dy * dy); + + const timeToIntercept = distanceToAsteroid / rocketSpeed; + if (Math.abs(timeToIntercept - t) < closestApproach) { + closestApproach = Math.abs(timeToIntercept - t); + interceptX = futureAsteroidX; + interceptY = futureAsteroidY; + } + } + + console.log(`Calculated interception point: (${interceptX}, ${interceptY})`); + return { x: interceptX, y: interceptY }; + }; + const simulate = () => { let { x, y, speed, angle, mass } = asteroid; @@ -162,11 +179,37 @@ function Scenario() { vx += ax * timeStep; vy += ay * timeStep; - ({ vx, vy } = applyDeflectionStrategy(vx, vy)); - x += vx * timeStep; y += vy * timeStep; + // Calculate the interception point for the rocket in real-time + const { x: interceptX, y: interceptY } = calculateInterceptionPoint(ROCKET_SPEED, x, y, vx, vy); + setRocket((prev) => ({ ...prev, targetX: interceptX, targetY: interceptY })); + + console.log(`Rocket target updated to: (${interceptX}, ${interceptY})`); + + // Update rocket position + const rocketDx = rocket.targetX - rocket.x; + const rocketDy = rocket.targetY - rocket.y; + const rocketDistance = Math.sqrt(rocketDx * rocketDx + rocketDy * rocketDy); + + if (rocketDistance > 1) { + const rocketAngle = Math.atan2(rocketDy, rocketDx); + const rocketVX = ROCKET_SPEED * Math.cos(rocketAngle); + const rocketVY = ROCKET_SPEED * Math.sin(rocketAngle); + + setRocket((prev) => ({ + ...prev, + x: prev.x + rocketVX * timeStep, + y: prev.y + rocketVY * timeStep, + trajectory: [...prev.trajectory, prev.x + rocketVX * timeStep, prev.y + rocketVY * timeStep], + })); + } else { + setSimulationResult('Rocket intercepted the asteroid!'); + setIsSimulating(false); + return; + } + if (y > CANVAS_HEIGHT * SIMULATION_AREA_MULTIPLIER || x > CANVAS_WIDTH * SIMULATION_AREA_MULTIPLIER || y < -CANVAS_HEIGHT * SIMULATION_AREA_MULTIPLIER || x < -CANVAS_WIDTH * SIMULATION_AREA_MULTIPLIER) { setSimulationResult('Asteroid missed Earth!'); setIsSimulating(false); @@ -184,8 +227,13 @@ function Scenario() { }; const handleSimulate = () => { - if (isSimulating) return; - simulate(); + if (isSimulating) { + setIsSimulating(false); + window.cancelAnimationFrame(animationRef.current); + setSimulationResult('Simulation stopped.'); + } else { + simulate(); + } }; const handleTimeStepChange = (event, newValue) => { @@ -216,10 +264,9 @@ function Scenario() { variant="contained" color="primary" onClick={handleSimulate} - disabled={isSimulating} style={{ marginTop: '10px' }} > - Simulate + {isSimulating ? 'Stop Simulation' : 'Simulate'} {simulationResult && (
@@ -270,6 +317,12 @@ function Scenario() { {forecastPoints.length > 0 && ( )} + {rocket.active && ( + + )} + {rocket.trajectory.length > 0 && ( + + )} From aaa20177c5d042972b42e6364674fdfa4d891141 Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 19 May 2024 01:12:29 -0400 Subject: [PATCH 2/4] ugh --- frontend/src/pages/scenario.jsx | 95 +++++++++++++++------------------ 1 file changed, 44 insertions(+), 51 deletions(-) diff --git a/frontend/src/pages/scenario.jsx b/frontend/src/pages/scenario.jsx index c111915..258d3b8 100644 --- a/frontend/src/pages/scenario.jsx +++ b/frontend/src/pages/scenario.jsx @@ -16,7 +16,7 @@ const CANVAS_HEIGHT = window.innerHeight; const EARTH_X = CANVAS_WIDTH - 100; const EARTH_Y = CANVAS_HEIGHT / 2; const SIMULATION_AREA_MULTIPLIER = 2; // Extend the simulation area -const ROCKET_SPEED = 0.1; // Speed of the rocket +const ROCKET_SPEED = 0.025; // Reduced speed of the rocket function Scenario() { const [asteroid, setAsteroid] = useState({ @@ -36,7 +36,15 @@ function Scenario() { const [simulationResult, setSimulationResult] = useState(''); const [strategy, setStrategy] = useState(''); // State for selected strategy const [timeStep, setTimeStep] = useState(100); // State for time step - const [rocket, setRocket] = useState({ active: false, x: EARTH_X, y: EARTH_Y, trajectory: [], targetX: 0, targetY: 0 }); + const [rocket, setRocket] = useState({ + active: false, + x: EARTH_X, + y: EARTH_Y, + trajectory: [], + vx: 0, vy: 0 + }); + const rocketDistanceRef = useRef(10000); + useEffect(() => { const fetchAsteroids = async () => { @@ -51,6 +59,8 @@ function Scenario() { fetchAsteroids(); }, []); + + const estimateMass = (diameter) => { const radius = diameter / 2; const volume = (4 / 3) * Math.PI * Math.pow(radius, 3); @@ -74,7 +84,8 @@ function Scenario() { }); setTrajectoryPoints([]); calculateForecastPath(size, speed, Math.PI / 9, mass); // Calculate the forecast path once - setRocket({ active: false, x: EARTH_X, y: EARTH_Y, trajectory: [], targetX: 0, targetY: 0 }); + setRocket({ active: false, x: EARTH_X, y: EARTH_Y, trajectory: [], vx: 0, vy: 0 }); + }; const handleAsteroidSelect = (event) => { @@ -127,30 +138,9 @@ function Scenario() { setForecastPoints(points); }; - const calculateInterceptionPoint = (rocketSpeed, asteroidX, asteroidY, asteroidVX, asteroidVY) => { - let interceptX = asteroidX; - let interceptY = asteroidY; - let closestApproach = Infinity; - - for (let t = 0; t < 5000; t += timeStep) { - const futureAsteroidX = asteroidX + asteroidVX * t; - const futureAsteroidY = asteroidY + asteroidVY * t; - - const dx = futureAsteroidX - EARTH_X; - const dy = futureAsteroidY - EARTH_Y; - const distanceToAsteroid = Math.sqrt(dx * dx + dy * dy); - - const timeToIntercept = distanceToAsteroid / rocketSpeed; - if (Math.abs(timeToIntercept - t) < closestApproach) { - closestApproach = Math.abs(timeToIntercept - t); - interceptX = futureAsteroidX; - interceptY = futureAsteroidY; - } - } - - console.log(`Calculated interception point: (${interceptX}, ${interceptY})`); - return { x: interceptX, y: interceptY }; - }; + // useEffect(() => { + // + // }, [rocketDistanceRef]); const simulate = () => { let { x, y, speed, angle, mass } = asteroid; @@ -159,8 +149,6 @@ function Scenario() { let vy = speed * Math.sin(angle); const updateFrame = () => { - console.log(`Asteroid position: (${x}, ${y}), velocity: (${vx}, ${vy})`); - const dx = EARTH_X - x; const dy = EARTH_Y - y; const distance = Math.sqrt(dx * dx + dy * dy); @@ -182,34 +170,39 @@ function Scenario() { x += vx * timeStep; y += vy * timeStep; - // Calculate the interception point for the rocket in real-time - const { x: interceptX, y: interceptY } = calculateInterceptionPoint(ROCKET_SPEED, x, y, vx, vy); - setRocket((prev) => ({ ...prev, targetX: interceptX, targetY: interceptY })); + rocketDistanceRef.current = 1000; - console.log(`Rocket target updated to: (${interceptX}, ${interceptY})`); + setRocket((prev) => { + // Update rocket position + const rocketDx = x - prev.x; + const rocketDy = y - prev.y; - // Update rocket position - const rocketDx = rocket.targetX - rocket.x; - const rocketDy = rocket.targetY - rocket.y; - const rocketDistance = Math.sqrt(rocketDx * rocketDx + rocketDy * rocketDy); - - if (rocketDistance > 1) { + const rocketDist = Math.sqrt(rocketDx * rocketDx + rocketDy* rocketDy); const rocketAngle = Math.atan2(rocketDy, rocketDx); const rocketVX = ROCKET_SPEED * Math.cos(rocketAngle); - const rocketVY = ROCKET_SPEED * Math.sin(rocketAngle); + const rocketVY = ROCKET_SPEED * Math.sin(rocketAngle) ; - setRocket((prev) => ({ - ...prev, - x: prev.x + rocketVX * timeStep, - y: prev.y + rocketVY * timeStep, - trajectory: [...prev.trajectory, prev.x + rocketVX * timeStep, prev.y + rocketVY * timeStep], - })); - } else { - setSimulationResult('Rocket intercepted the asteroid!'); - setIsSimulating(false); - return; - } + const newX = prev.x + rocketVX * timeStep; + const newY = prev.y + rocketVY * timeStep; + rocketDistanceRef.current=rocketDist; + const temprocket = { + x: newX, + y: newY, + vx: rocketVX, + vy: rocketVY, + trajectory: [...prev.trajectory, newX, newY], + }; + + return temprocket; + }); + + console.log('rocketDistance:', rocketDistanceRef); + if (rocketDistanceRef < asteroid.size * ASTEROID_DISPLAY_SCALE) { + setSimulationResult('Rocket intercepted the asteroid!'); + setIsSimulating(false); + return; + } if (y > CANVAS_HEIGHT * SIMULATION_AREA_MULTIPLIER || x > CANVAS_WIDTH * SIMULATION_AREA_MULTIPLIER || y < -CANVAS_HEIGHT * SIMULATION_AREA_MULTIPLIER || x < -CANVAS_WIDTH * SIMULATION_AREA_MULTIPLIER) { setSimulationResult('Asteroid missed Earth!'); setIsSimulating(false); From 1711936609a7b0eb8767008daaae54198702ecfc Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 19 May 2024 03:19:04 -0400 Subject: [PATCH 3/4] added ignore for pycache --- backend/deep_impact_proj/.env.sample | 2 +- .../__pycache__/__init__.cpython-311.pyc | Bin 205 -> 183 bytes .../api_app/__pycache__/admin.cpython-311.pyc | Bin 260 -> 238 bytes .../api_app/__pycache__/apps.cpython-311.pyc | Bin 577 -> 555 bytes .../__pycache__/models.cpython-311.pyc | Bin 257 -> 235 bytes .../api_app/__pycache__/urls.cpython-311.pyc | Bin 574 -> 552 bytes .../api_app/__pycache__/utils.cpython-311.pyc | Bin 1470 -> 1448 bytes .../api_app/__pycache__/views.cpython-311.pyc | Bin 1509 -> 1487 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 216 -> 194 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 214 -> 192 bytes .../__pycache__/settings.cpython-311.pyc | Bin 3138 -> 3116 bytes .../__pycache__/urls.cpython-311.pyc | Bin 1215 -> 1193 bytes .../__pycache__/wsgi.cpython-311.pyc | Bin 754 -> 732 bytes frontend/src/pages/scenario.jsx | 167 +++++++++++------- 14 files changed, 101 insertions(+), 68 deletions(-) diff --git a/backend/deep_impact_proj/.env.sample b/backend/deep_impact_proj/.env.sample index cc3ccc3..8530af4 100644 --- a/backend/deep_impact_proj/.env.sample +++ b/backend/deep_impact_proj/.env.sample @@ -3,4 +3,4 @@ SENTRY_API_KEY=<"Your NASA Sentry API Key"> OPENAI_API_KEY=<"Your OpenAI API Key"> HOST_CLIENT=<"Your FrontEnd URL"> ALLOWED_HOSTS=<"Your Server URL"> -DEBUG=<"True for Deployment | False for Development"> \ No newline at end of file +DEBUG=<"True for Deployment | False for Development"> diff --git a/backend/deep_impact_proj/api_app/__pycache__/__init__.cpython-311.pyc b/backend/deep_impact_proj/api_app/__pycache__/__init__.cpython-311.pyc index 96988ff71f38bf0c6b8560700a111b4f43c01318..a4b76cd0ac8ec337eb651ff858de8d432fe1455d 100644 GIT binary patch delta 86 zcmX@hxSf$}IWI340}ym|P2@6j@N%|_2`x@7DvohU%!_gMcX5qzNlh)#^~^0uOfHE@ kN=(j9%}a?%0gAL(Ut#wQjO=ud1g F2LQF~CUyV- diff --git a/backend/deep_impact_proj/api_app/__pycache__/admin.cpython-311.pyc b/backend/deep_impact_proj/api_app/__pycache__/admin.cpython-311.pyc index aea8442fdadc0c70c26abb6af27a5dad74013807..c8277e49588c3c603681f68937057a2662df13bb 100644 GIT binary patch delta 89 zcmZo+ddJASoR^o20SLOfJky*e^2R&3J6pws7N-^!$G9Zs#W?%BxW>4orWWXW<`yI- nm&7C`CTFMSrNpEF#o{x;V(|q<`B^cE1)1@Q1qCq^4>XM)Az3xEps6ALoq6AKFT IC$4b<03u~4wg3PC diff --git a/backend/deep_impact_proj/api_app/__pycache__/apps.cpython-311.pyc b/backend/deep_impact_proj/api_app/__pycache__/apps.cpython-311.pyc index 331dfe9342775916acc0358aa155b548271fbfaf..4f326809a6838103a49ad4527dcab38f73da4713 100644 GIT binary patch delta 91 zcmX@evYLf=IWI340}ym|d8SR@$Sc6;;O1-<6Iz^FR2<`ym>1*h@8TNclA2ne>zP}S pm|PN*l$e~InwJuj0u+nS1dGKN6y;~dBo<`GCl(aMOfF_T2LK<{AFcoZ delta 113 zcmZ3@a*&00IWI340}$K`@JySykyn5*EJi;gKQ~oBE59fuF|RT)H!&qq-#I@eH6SOk zBtJh-KcFZ-D>b>KSl=ZzwLsT1w;(aOL_aApIXg8kMLz{77M}?gi!T5w)K4tPj87~m K(4QR3cn$zt4orWWXW<`yI- nm&7C`CTFMSrNpEF#o{x;V(|q<`B^cE1)1@Q1qCq^_c;Rq>q8$m delta 111 zcmaFO*vQ1YoR^o20SN8|c&1rSXM)Az3xEps6ALoq6AKFT IC$4Y?033rSqyPW_ diff --git a/backend/deep_impact_proj/api_app/__pycache__/urls.cpython-311.pyc b/backend/deep_impact_proj/api_app/__pycache__/urls.cpython-311.pyc index 0ae640f6adea968cced25167392cda285fee29d2..152c84f32c809b12655208e8faaccaa26de3f60b 100644 GIT binary patch delta 91 zcmdnTvVw(oIWI340}ym|d8VD*$ZOB&;O1-<6Iz^FR2<`ym>1*h@8TNclA2ne>zP}S pm|PN*l$e~InwJuj0u+nS1dGKN6y;~dBo<`GCl(aMOkTt|2LL&dAO-*c delta 113 zcmZ3%vX6y#IWI340}vQhd!`-O$ZO9S7Neh$pPQL(Ut#wQjO K=uhrpoC5$!!zb(j diff --git a/backend/deep_impact_proj/api_app/__pycache__/utils.cpython-311.pyc b/backend/deep_impact_proj/api_app/__pycache__/utils.cpython-311.pyc index 11ac1dfd41a0e5ad244ac5795daa8fa01f3cf409..bce4ab9e5e75c695baea10bd1d4f87c2b93e3f1e 100644 GIT binary patch delta 92 zcmdnTy@H!}IWI340}ym|d8RGf$Scq6;O=Y{6Iz^FR2<`ym>1*h@8TNclA2ne>zP}S qm|PN*l$e~InwJuj0u+nS1dGKN6y;~dBo<`GCl(aMY;IzL(Ut#wQjO L=x@$pwqXJQU)3jH diff --git a/backend/deep_impact_proj/api_app/__pycache__/views.cpython-311.pyc b/backend/deep_impact_proj/api_app/__pycache__/views.cpython-311.pyc index 23785c7594b1c58c245b2fae9e78f0d2fe0780af..44d1d2def8b045488a40de56d0f0b4490191095d 100644 GIT binary patch delta 92 zcmaFLeV&_lIWI340}ym|d8XNKii`CD_&rQ|O$}dVu%&SbyO-xDDcg{~q4ai9> z$G55=%1k^NM38E;I)K4viw# delta 119 zcmW;Cu?@m75Jq9rTFNNsIv4;NI&Wb8_)g#i`%aFV%s`bX*n=skm<5YhetPfWGq~3{ zx?S(IWI340}ym|P2@8340g7P2`x@7DvohU%!_gMcX5qzNlh)#^~^0uOfHE@ dN=(j9%}a?%0gAku||S#IWI340}ym|d8S43ZRGpO=^5;76%$&VT2vh4l9(6c?C;_ltlL8cr&jgFb7Zl}ZVG3+cEay7K<+cD#R4n9Kdyl F5ddTMEa3nE diff --git a/backend/deep_impact_proj/deep_impact_proj/__pycache__/urls.cpython-311.pyc b/backend/deep_impact_proj/deep_impact_proj/__pycache__/urls.cpython-311.pyc index 3a1cce68992e9f10c24f4519503be19b67e5e13f..3b3441502540674b1fe43ff250f123f0f9babb8e 100644 GIT binary patch delta 100 zcmdnbxssE2IWI340}ym|d8YYqF;b66Iz^FR2<`ym>1*h@8TNclA2ne>zP}S im|PN*l$e~InwJuj0u+nS1dGKN6y;}O3QSgKnE?QEm?LKZ delta 122 zcmZ3KQ~oBE59fuF|RT)H!&qq-#I@eH6SOk zBtJh-KcFZ-D>b>KSl=ZzwLsT1w;(aOL_aApIXg8kMLz{77M}?gi!T5w#1xn;$T9-} D`CBWk diff --git a/backend/deep_impact_proj/deep_impact_proj/__pycache__/wsgi.cpython-311.pyc b/backend/deep_impact_proj/deep_impact_proj/__pycache__/wsgi.cpython-311.pyc index 7caa192654ff434fff9d2d5a42e63cc01cad6072..39afbf7477136705e23436962e8f11ef97183eec 100644 GIT binary patch delta 100 zcmeywdWV&FIWI340}ym|d8V!0$jim#>F;b66Iz^FR2<`ym>1*h@8TNclA2ne>zP}S im|PN*l$e~InwJuj0u+nS1dGKN6y;}O3QR6zssR9gRwJGO delta 122 zcmcb^`iYfyIWI340}$K`@JySzk(Y}pK2<*>KQ~oBE59fuF|RT)H!&qq-#I@eH6SOk zBtJh-KcFZ-D>b>KSl=ZzwLsT1w;(aOL_aApIXg8kMLz{77M}?gi!T5w#1xpEz*GYO D53wu$ diff --git a/frontend/src/pages/scenario.jsx b/frontend/src/pages/scenario.jsx index b974f4b..3f13923 100644 --- a/frontend/src/pages/scenario.jsx +++ b/frontend/src/pages/scenario.jsx @@ -1,9 +1,8 @@ import React, { useState, useEffect, useRef } from 'react'; import { Stage, Layer, Circle, Text, Line } from 'react-konva'; -import { Slider, Button } from '@mui/material'; +import { Slider, Button, MenuItem, Select, Typography, Box } from '@mui/material'; import axios from 'axios'; - const EARTH_RADIUS_KM = 6371; // Earth's radius in kilometers const EARTH_DISPLAY_SCALE = 0.01; // Display scale for Earth const ASTEROID_DISPLAY_SCALE = 0.3; // Display scale for asteroids @@ -41,15 +40,16 @@ function Scenario() { x: EARTH_X, y: EARTH_Y, trajectory: [], - vx: 0, vy: 0 + vx: 0, + vy: 0, }); - const rocketDistanceRef = useRef(10000); - + const [rocketDistance, setRocketDistance] = useState(10000); + const [collisionOccurred, setCollisionOccurred] = useState(false); useEffect(() => { - const fetchAsteroids = async (self, request) => { + const fetchAsteroids = async () => { try { - const response = await axios.get(`http://localhost:8000/api/sentry/`); + const response = await axios.get('http://localhost:8080/api/sentry/'); asteroidsData.current = response.data.near_earth_objects; setAsteroidData(0); // Set initial asteroid } catch (error) { @@ -59,8 +59,6 @@ function Scenario() { fetchAsteroids(); }, []); - - const estimateMass = (diameter) => { const radius = diameter / 2; const volume = (4 / 3) * Math.PI * Math.pow(radius, 3); @@ -85,7 +83,8 @@ function Scenario() { setTrajectoryPoints([]); calculateForecastPath(size, speed, Math.PI / 9, mass); // Calculate the forecast path once setRocket({ active: false, x: EARTH_X, y: EARTH_Y, trajectory: [], vx: 0, vy: 0 }); - + setRocketDistance(10000); + setCollisionOccurred(false); }; const handleAsteroidSelect = (event) => { @@ -138,9 +137,19 @@ function Scenario() { setForecastPoints(points); }; - // useEffect(() => { - // - // }, [rocketDistanceRef]); + const applyVelocityImpulse = (asteroid, strategy, rocketDx, rocketDy) => { + let impulseX = 0; + let impulseY = 0; + const angle = Math.atan2(rocketDy, rocketDx); + if (strategy === 'Nuclear Detonation') { + impulseX = 0.01 * Math.cos(angle); + impulseY = 0.01 * Math.sin(angle); + } else if (strategy === 'Kinetic Impact') { + impulseX = 0.005 * Math.cos(angle); + impulseY = 0.005 * Math.sin(angle); + } + return { vx: asteroid.vx + impulseX, vy: asteroid.vy + impulseY }; + }; const simulate = () => { let { x, y, speed, angle, mass } = asteroid; @@ -170,47 +179,54 @@ function Scenario() { x += vx * timeStep; y += vy * timeStep; - rocketDistanceRef.current = 1000; - + // Update rocket position setRocket((prev) => { - // Update rocket position const rocketDx = x - prev.x; const rocketDy = y - prev.y; - - const rocketDist = Math.sqrt(rocketDx * rocketDx + rocketDy* rocketDy); + const rocketDistance = Math.sqrt(rocketDx * rocketDx + rocketDy * rocketDy); const rocketAngle = Math.atan2(rocketDy, rocketDx); + const rocketVX = ROCKET_SPEED * Math.cos(rocketAngle); - const rocketVY = ROCKET_SPEED * Math.sin(rocketAngle) ; + const rocketVY = ROCKET_SPEED * Math.sin(rocketAngle); const newX = prev.x + rocketVX * timeStep; const newY = prev.y + rocketVY * timeStep; - rocketDistanceRef.current=rocketDist; - const temprocket = { + if (rocketDistance <= asteroid.size * ASTEROID_DISPLAY_SCALE && !collisionOccurred) { + const newVelocity = applyVelocityImpulse({ vx, vy }, strategy, rocketDx, rocketDy); + vx = newVelocity.vx; + vy = newVelocity.vy; + setSimulationResult('Rocket intercepted the asteroid!'); + setCollisionOccurred(true); // Mark collision occurred + return { ...prev, active: false, x: newX, y: newY, vx: 0, vy: 0 }; // Stop the rocket + } + + return { + ...prev, x: newX, y: newY, - vx: rocketVX, - vy: rocketVY, + vx: prev.active ? rocketVX : 0, // Stop velocity if inactive + vy: prev.active ? rocketVY : 0, // Stop velocity if inactive trajectory: [...prev.trajectory, newX, newY], }; - - return temprocket; }); - console.log('rocketDistance:', rocketDistanceRef); - if (rocketDistanceRef < asteroid.size * ASTEROID_DISPLAY_SCALE) { - setSimulationResult('Rocket intercepted the asteroid!'); - setIsSimulating(false); - return; - } + setRocketDistance(rocketDistance); + + if (rocketDistance <= asteroid.size * ASTEROID_DISPLAY_SCALE && !collisionOccurred) { + setSimulationResult('Rocket intercepted the asteroid!'); + setIsSimulating(false); + return; + } + if (y > CANVAS_HEIGHT * SIMULATION_AREA_MULTIPLIER || x > CANVAS_WIDTH * SIMULATION_AREA_MULTIPLIER || y < -CANVAS_HEIGHT * SIMULATION_AREA_MULTIPLIER || x < -CANVAS_WIDTH * SIMULATION_AREA_MULTIPLIER) { setSimulationResult('Asteroid missed Earth!'); setIsSimulating(false); return; } - setAsteroid(prev => ({ ...prev, x, y })); - setTrajectoryPoints(prev => [...prev, x, y]); + setAsteroid((prev) => ({ ...prev, x, y })); + setTrajectoryPoints((prev) => [...prev, x, y]); animationRef.current = window.requestAnimationFrame(updateFrame); }; @@ -234,50 +250,67 @@ function Scenario() { }; const handleAngleChange = (event, newValue) => { - setAsteroid(prev => ({ ...prev, angle: newValue })); + setAsteroid((prev) => ({ ...prev, angle: newValue })); calculateForecastPath(asteroid.size, asteroid.speed, newValue, asteroid.mass); }; return ( <> -
-

Asteroid Collision Scenario

- - + + + Asteroid Collision Scenario + + + + + + + {simulationResult && ( -
-

Simulation Result

-

{simulationResult}

-
+ + Simulation Result + {simulationResult} + )} {asteroid.name && ( -
-

Asteroid Information

-

Name: {asteroid.name}

-

Size: {asteroid.size.toFixed(3)} kilometers

-

Speed: {(asteroid.speed * 1000).toFixed(3)} km/s

-

Mass: {asteroid.mass.toExponential(3)} kg

-
+ + Asteroid Information + Name: {asteroid.name} + Size: {asteroid.size.toFixed(3)} kilometers + Speed: {(asteroid.speed * 1000).toFixed(3)} km/s + Mass: {asteroid.mass.toExponential(3)} kg + )} -
-

Time Step: {timeStep}

+ + Time Step: {timeStep} -
-
-

Initial Angle: {(asteroid.angle * 180 / Math.PI).toFixed(2)}°

+ + + Initial Angle: {(asteroid.angle * 180 / Math.PI).toFixed(2)}° -
-
+ + @@ -314,7 +347,7 @@ function Scenario() { )} {rocket.trajectory.length > 0 && ( - + )} From ee810c04d1c08d082af7734a3ed95c5106bb84d3 Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 19 May 2024 03:22:30 -0400 Subject: [PATCH 4/4] add ignored pycache --- backend/deep_impact_proj/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/deep_impact_proj/.gitignore b/backend/deep_impact_proj/.gitignore index c66ba3a..b741592 100644 --- a/backend/deep_impact_proj/.gitignore +++ b/backend/deep_impact_proj/.gitignore @@ -1,2 +1,3 @@ .env -.venv \ No newline at end of file +.venv +/__pycache__/ \ No newline at end of file