```jsx
import React, { useState, useEffect, useRef } from 'react';
import { Canvas, useFrame, useLoader } from '@react-three/fiber';
import { OrbitControls, Stars, useTexture } from '@react-three/drei';
import * as THREE from 'three';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, AreaChart, Area } from 'recharts';
import { Clock, AlertTriangle, Info, Star, Meteor, Satellite } from 'lucide-react';
const SolarSystem = () => {
const sunRef = useRef();
const planets = [
{ name: 'Mercury', distance: 15, size: 0.3, color: '#8C7853', period: 88 },
{ name: 'Venus', distance: 25, size: 0.8, color: '#FFC649', period: 225 },
{ name: 'Earth', distance: 35, size: 1, color: '#6CBBF0', period: 365 },
{ name: 'Mars', distance: 45, size: 0.5, color: '#FF3B30', period: 687 },
{ name: 'Jupiter', distance: 70, size: 3, color: '#D8CA9D', period: 4333 },
{ name: 'Saturn', distance: 90, size: 2.5, color: '#FAD5A5', period: 10759 },
{ name: 'Uranus', distance: 110, size: 1.8, color: '#A5F2F3', period: 30687 },
{ name: 'Neptune', distance: 130, size: 1.7, color: '#4B70DD', period: 60190 },
];
const meteors = [
{ id: 1, position: [50, 10, -30], velocity: [-0.05, 0.02, 0.01], size: 0.1, color: '#FFD700' },
{ id: 2, position: [-40, -20, 60], velocity: [0.03, -0.01, -0.02], size: 0.08, color: '#FF6347' },
{ id: 3, position: [80, 5, -15], velocity: [-0.02, 0.03, 0.01], size: 0.12, color: '#00CED1' },
];
const satellites = [
{ name: 'ISS', position: [38, 2, 5], velocity: [0, 0.1, 0.05], size: 0.05, color: '#FFFFFF' },
{ name: 'Hubble', position: [42, -3, -8], velocity: [0, -0.08, 0.06], size: 0.04, color: '#FFD700' },
];
useFrame((state, delta) => {
// Animate Sun
if (sunRef.current) {
sunRef.current.rotation.y += 0.001;
}
// Update meteor positions using physics equations
meteors.forEach(meteor => {
// Basic physics: position = position + velocity * time
meteor.position[0] += meteor.velocity[0] * 50;
meteor.position[1] += meteor.velocity[1] * 50;
meteor.position[2] += meteor.velocity[2] * 50;
// Apply gravitational influence from Sun (simplified inverse square law)
const dx = 0 - meteor.position[0];
const dy = 0 - meteor.position[1];
const dz = 0 - meteor.position[2];
const distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
if (distance > 0) {
const force = 0.0001 / (distance * distance);
meteor.velocity[0] += dx * force;
meteor.velocity[1] += dy * force;
meteor.velocity[2] += dz * force;
}
// Boundary conditions - wrap around
if (Math.abs(meteor.position[0]) > 200 || Math.abs(meteor.position[1]) > 200 || Math.abs(meteor.position[2]) > 200) {
meteor.position[0] = Math.random() * 100 - 50;
meteor.position[1] = Math.random() * 50 - 25;
meteor.position[2] = Math.random() * 100 - 50;
}
});
// Update satellite positions
satellites.forEach(satellite => {
// Circular orbit approximation
const angle = state.clock.elapsedTime / satellite.velocity[1] * 0.5;
satellite.position[0] = 35 * Math.cos(angle);
satellite.position[2] = 35 * Math.sin(angle);
satellite.position[1] = 3 * Math.sin(angle * 2);
});
});
return (
<>
{/* Sun */}
<mesh ref={sunRef}>
<sphereGeometry args={[5, 32, 32]} />
<meshStandardMaterial
emissive="#FFFF00"
emissiveIntensity={1}
roughness={0.5}
metalness={0.8}
/>
</mesh>
{/* Planet orbits and planets */}
{planets.map((planet, index) => (
<group key={planet.name}>
{/* Orbit path */}
<mesh rotation={[Math.PI / 2, 0, 0]}>
<ringGeometry args={[planet.distance - 0.1, planet.distance + 0.1, 64]} />
<meshBasicMaterial color="#333" transparent opacity={0.3} />
</mesh>
{/* Planet */}
<mesh position={[planet.distance, 0, 0]}>
<sphereGeometry args={[planet.size, 32, 32]} />
<meshStandardMaterial color={planet.color} roughness={0.7} metalness={0.2} />
</mesh>
</group>
))}
{/* Meteors */}
{meteors.map(meteor => (
<mesh key={meteor.id} position={meteor.position}>
<sphereGeometry args={[meteor.size, 16, 16]} />
<meshStandardMaterial color={meteor.color} emissive={meteor.color} emissiveIntensity={0.8} />
{/* Meteor trail */}
<points>
<bufferGeometry>
<bufferAttribute
attach="attributes-position"
count={5}
itemSize={3}
array={new Float32Array([
meteor.position[0], meteor.position[1], meteor.position[2],
meteor.position[0] + meteor.velocity[0] * 200, meteor.position[1] + meteor.velocity[1] * 200, meteor.position[2] + meteor.velocity[2] * 200,
meteor.position[0] + meteor.velocity[0] * 150, meteor.position[1] + meteor.velocity[1] * 150, meteor.position[2] + meteor.velocity[2] * 150,
meteor.position[0] + meteor.velocity[0] * 100, meteor.position[1] + meteor.velocity[1] * 100, meteor.position[2] + meteor.velocity[2] * 100,
meteor.position[0] + meteor.velocity[0] * 50, meteor.position[1] + meteor.velocity[1] * 50, meteor.position[2] + meteor.velocity[2] * 50,
])}
/>
</bufferGeometry>
<pointsMaterial color={meteor.color} size={0.5} sizeAttenuation />
</points>
</mesh>
))}
{/* Satellites */}
{satellites.map(satellite => (
<mesh key={satellite.name} position={satellite.position}>
<boxGeometry args={[satellite.size * 2, satellite.size, satellite.size * 1.5]} />
<meshStandardMaterial color={satellite.color} metalness={1} roughness={0.2} />
</mesh>
))}
{/* Distant stars */}
<Stars radius={100} depth={50} count={5000} factor={4} saturation={0} fade />
</>
);
};
const PhysicsEquations = () => {
const equations = [
{
title: "Newton's Law of Universal Gravitation",
formula: "F = G × (m₁ × m₂) / r²",
description: "Calculates gravitational force between two masses",
variables: "F: Force, G: Gravitational constant, m: masses, r: distance"
},
{
title: "Kepler's Third Law",
formula: "T² = (4π² / GM) × a³",
description: "Relates orbital period to semi-major axis",
variables: "T: Period, a: semi-major axis, M: central mass"
},
{
title: "Orbital Velocity",
formula: "v = √(GM / r)",
description: "Calculates velocity for circular orbit",
variables: "v: velocity, G: gravitational constant, M: mass, r: radius"
},
{
title: "Position Update",
formula: "x(t) = x₀ + v₀t + ½at²",
description: "Calculates position using initial conditions",
variables: "x: position, v: velocity, a: acceleration, t: time"
},
{
title: "Escape Velocity",
formula: "vₑ = √(2GM / r)",
description: "Minimum speed to escape gravitational pull",
variables: "vₑ: escape velocity, G: gravitational constant, M: mass, r: distance"
}
];
return (
<div className="bg-gray-900 text-white p-6 rounded-lg border border-gray-700">
<h3 className="text-xl font-bold mb-6 flex items-center">
<Info className="mr-2 text-blue-400" /> Fundamental Physics Equations
</h3>
<div className="space-y-4">
{equations.map((eq, index) => (
<div key={index} className="border-b border-gray-700 pb-4 last:border-b-0">
<h4 className="font-semibold text-lg text-blue-300 mb-2">{eq.title}</h4>
<div className="bg-gray-800 p-3 rounded mb-2 font-mono text-center">
{eq.formula}
</div>
<p className="text-sm text-gray-300 mb-1">{eq.description}</p>
<p className="text-xs text-gray-400 italic">{eq.variables}</p>
</div>
))}
</div>
</div>
);
};
const TrajectoryChart = () => {
const data = Array.from({ length: 24 }, (_, i) => ({
time: i,
x: 50 * Math.cos(i * 0.26) + Math.random() * 5,
y: 30 * Math.sin(i * 0.26) + Math.random() * 3,
z: 20 * Math.sin(i * 0.13) + Math.random() * 2
}));
return (
<div className="bg-gray-900 text-white p-6 rounded-lg border border-gray-700">
<h3 className="text-xl font-bold mb-6 flex items-center">
<Star className="mr-2 text-yellow-400" /> Meteor Trajectory Analysis
</h3>
<div className="h-80">
<ResponsiveContainer width="100%" height="100%">
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" stroke="#374151" />
<XAxis dataKey="time" stroke="#9CA3AF" />
<YAxis stroke="#9CA3AF" />
<Tooltip
contentStyle={{ backgroundColor: '#1F2937', border: '1px solid #374151' }}
labelStyle={{ color: '#F9FAFB' }}
/>
<Line type="monotone" dataKey="x" stroke="#3B82F6" name="X Position" />
<Line type="monotone" dataKey="y" stroke="#10B981" name="Y Position" />
<Line type="monotone" dataKey="z" stroke="#F59E0B" name="Z Position" />
</LineChart>
</ResponsiveContainer>
</div>
</div>
);
};
const RiskAssessment = () => {
const [riskLevel, setRiskLevel] = useState(2);
const [closestApproach, setClosestApproach] = useState(150000);
useEffect(() => {
const interval = setInterval(() => {
setRiskLevel(prev => {
const change = Math.random() > 0.7 ? (Math.random() > 0.5 ? 1 : -1) : 0;
return Math.max(1, Math.min(5, prev + change));
});
setClosestApproach(prev => Math.max(50000, prev + (Math.random() - 0.5) * 20000));
}, 3000);
return () => clearInterval(interval);
}, []);
const riskColors = ['text-green-400', 'text-green-300', 'text-yellow-300', 'text-orange-400', 'text-red-400'];
const riskLabels = ['Low', 'Moderate', 'Elevated', 'High', 'Critical'];
return (
<div className="bg-gray-900 text-white p-6 rounded-lg border border-gray-700">
<h3 className="text-xl font-bold mb-6 flex items-center">
<AlertTriangle className="mr-2 text-red-400" /> Impact Risk Assessment
</h3>
<div className="space-y-6">
<div>
<div className="flex justify-between mb-2">
<span className="text-sm font-medium">Current Risk Level</span>
<span className={`font-bold ${riskColors[riskLevel - 1]}`}>
{riskLabels[riskLevel - 1]}
</span>
</div>
<div className="w-full bg-gray-700 rounded-full h-3">
<div
className={`h-3 rounded-full transition-all duration-1000 ${
riskLevel === 1 ? 'bg-green-500' :
riskLevel === 2 ? 'bg-green-400' :
riskLevel === 3 ? 'bg-yellow-400' :
riskLevel === 4 ? 'bg-orange-500' : 'bg-red-500'
}`}
style={{ width: `${(riskLevel / 5) * 100}%` }}
></div>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="bg-gray-800 p-4 rounded-lg">
<div className="text-2xl font-bold text-blue-400">{closestApproach.toLocaleString()} km</div>
<div className="text-sm text-gray-300">Closest Approach</div>
</div>
<div className="bg-gray-800 p-4 rounded-lg">
<div className="text-2xl font-bold text-purple-400">78.4°</div>
<div className="text-sm text-gray-300">Inclination</div>
</div>
<div className="bg-gray-800 p-4 rounded-lg">
<div className="text-2xl font-bold text-green-400">12.3 km/s</div>
<div className="text-sm text-gray-300">Velocity</div>
</div>
<div className="bg-gray-800 p-4 rounded-lg">
<div className="text-2xl font-bold text-red-400">45 m</div>
<div className="text-sm text-gray-300">Estimated Size</div>
</div>
</div>
<div className="text-sm text-gray-400 italic">
* Real-time calculations based on orbital mechanics and gravitational interactions
</div>
</div>
</div>
);
};
const RealTimeData = () => {
const [currentTime, setCurrentTime] = useState(new Date());
useEffect(() => {
const timer = setInterval(() => {
setCurrentTime(new Date());
}, 1000);
return () => clearInterval(timer);
}, []);
const dataPoints = [
{ label: 'Objects Tracked', value: '2,847', change: '+12', color: 'text-blue-400' },
{ label: 'New Discoveries', value: '14', change: '+3', color: 'text-green-400' },
{ label: 'Orbits Calculated', value: '1.2M', change: '+847', color: 'text-purple-400' },
{ label: 'Calculations/sec', value: '4.7M', change: '+12K', color: 'text-orange-400' },
];
return (
<div className="bg-gray-900 text-white p-6 rounded-lg border border-gray-700">
<div className="flex items-center justify-between mb-6">
<h3 className="text-xl font-bold flex items-center">
<Clock className="mr-2 text-cyan-400" /> Real-Time Data
</h3>
<div className="text-sm text-gray-400">
{currentTime.toLocaleTimeString()}
</div>
</div>
<div className="grid grid-cols-2 gap-4">
{dataPoints.map((item, index) => (
<div key={index} className="bg-gray-800 p-4 rounded-lg">
<div className="text-sm text-gray-300 mb-1">{item.label}</div>
<div className={`text-2xl font-bold ${item.color}`}>{item.value}</div>
<div className="text-xs text-green-400">↑ {item.change}</div>
</div>
))}
</div>
<div className="mt-6 pt-6 border-t border-gray-700">
<h4 className="font-semibold mb-3">Recent Activity</h4>
<div className="space-y-2 text-sm">
<div className="flex justify-between text-gray-300">
<span>Meteoroid 2023-XA7 detected</span>
<span className="text-green-400">2m ago</span>
</div>
<div className="flex justify-between text-gray-300">
<span>Orbit calculation updated</span>
<span className="text-green-400">5m ago</span>
</div>
<div className="flex justify-between text-gray-300">
<span>New asteroid trajectory confirmed</span>
<span className="text-green-400">8m ago</span>
</div>
</div>
</div>
</div>
);
};
const App = () => {
return (
<div className="min-h-screen bg-black text-white">
{/* Header */}
<header className="bg-gray-900 border-b border-gray-800 p-6">
<div className="max-w-7xl mx-auto">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<div className="text-3xl">🌌</div>
<div>
<h1 className="text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-500 bg-clip-text text-transparent">
Cosmic Tracker Pro
</h1>
<p className="text-gray-400 text-sm">Real-time Astronomical Object Positioning System</p>
</div>
</div>
<div className="flex items-center space-x-4">
<div className="flex items-center text-green-400">
<div className="w-2 h-2 bg-green-400 rounded-full mr-2 animate-pulse"></div>
<span className="text-sm">SYSTEM ACTIVE</span>
</div>
</div>
</div>
</div>
</header>
<div className="max-w-7xl mx-auto p-6">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
{/* 3D Visualization */}
<div className="lg:col-span-2 h-96 lg:h-screen rounded-lg overflow-hidden bg-black border border-gray-800">
<Canvas camera={{ position: [0, 30, 100], fov: 50 }}>
<ambientLight intensity={0.3} />
<pointLight position={[100, 100, 100]} intensity={1} />
<SolarSystem />
<OrbitControls />
</Canvas>
</div>
{/* Right Sidebar */}
<div className="space-y-6">
<RealTimeData />
<RiskAssessment />
<PhysicsEquations />
<TrajectoryChart />
</div>
</div>
{/* Footer */}
<footer className="text-center text-gray-500 text-sm py-6 border-t border-gray-800">
<p>
Cosmic Tracker Pro uses advanced mathematical models including Newtonian mechanics,
Kepler's laws, and numerical integration to calculate real-time positions of celestial objects.
</p>
<p className="mt-2">
Data updated continuously • Calculations performed using gravitational physics equations
</p>
</footer>
</div>
</div>
);
};
export default App;
```