large_hadron_collider / index.html
adnannovus's picture
Update index.html
fbd9df9 verified
raw
history blame
13.8 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced Particle Accelerator</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #000;
color: #00ff00;
font-family: monospace;
overflow: hidden;
}
canvas {
position: fixed;
}
.controls {
position: fixed;
top: 10px;
left: 10px;
background: rgba(0, 20, 0, 0.8);
padding: 15px;
border: 1px solid #00ff00;
z-index: 100;
}
.data {
position: fixed;
top: 10px;
right: 10px;
background: rgba(0, 20, 0, 0.8);
padding: 15px;
border: 1px solid #00ff00;
z-index: 100;
}
button {
background: #001400;
color: #00ff00;
border: 1px solid #00ff00;
padding: 5px 10px;
margin: 5px;
cursor: pointer;
font-family: monospace;
transition: all 0.3s;
}
button:hover {
background: #00ff00;
color: #000;
}
.separator {
height: 1px;
background: #00ff00;
margin: 10px 0;
}
.detector {
position: fixed;
border: 1px solid #00ff00;
pointer-events: none;
}
</style>
</head>
<body>
<canvas id="mainCanvas"></canvas>
<canvas id="effectCanvas"></canvas>
<div class="controls">
<button onclick="initializeAccelerator()">Initialize</button>
<button onclick="injectParticles()">Inject Particles</button>
<button onclick="toggleAcceleration()">Toggle Acceleration</button>
<button onclick="toggleCollisions()">Toggle Collisions</button>
<div class="separator"></div>
<div>Energy Level: <span id="energyLevel">0</span> TeV</div>
<div>Collisions: <span id="collisionCount">0</span></div>
<div>Particles: <span id="particleCount">0</span></div>
</div>
<div class="data">
<div>Detector Data:</div>
<div id="detectorData"></div>
</div>
<script>
const mainCanvas = document.getElementById('mainCanvas');
const effectCanvas = document.getElementById('effectCanvas');
const mainCtx = mainCanvas.getContext('2d');
const effectCtx = effectCanvas.getContext('2d');
// Set canvas sizes
function resizeCanvases() {
mainCanvas.width = window.innerWidth;
mainCanvas.height = window.innerHeight;
effectCanvas.width = window.innerWidth;
effectCanvas.height = window.innerHeight;
}
resizeCanvases();
window.addEventListener('resize', resizeCanvases);
// Simulation state
const state = {
particles: [],
detectors: [],
collisions: [],
acceleratorActive: false,
collisionsEnabled: false,
collisionCount: 0,
maxEnergy: 13, // TeV
centerX: window.innerWidth / 2,
centerY: window.innerHeight / 2,
ringRadius: Math.min(window.innerWidth, window.innerHeight) * 0.35,
time: 0
};
class Particle {
constructor(clockwise = true) {
this.clockwise = clockwise;
this.angle = clockwise ? 0 : Math.PI;
this.energy = 0.1;
this.velocity = 0.01;
this.radius = state.ringRadius;
this.size = 3;
this.trail = [];
this.maxTrailLength = 50;
this.collided = false;
this.updatePosition();
this.detectedBy = new Set();
}
updatePosition() {
this.x = state.centerX + Math.cos(this.angle) * this.radius;
this.y = state.centerY + Math.sin(this.angle) * this.radius;
this.trail.push({ x: this.x, y: this.y });
if (this.trail.length > this.maxTrailLength) {
this.trail.shift();
}
}
accelerate() {
if (state.acceleratorActive && this.energy < state.maxEnergy) {
this.energy += 0.01;
this.velocity = 0.01 + (this.energy / state.maxEnergy) * 0.04;
}
}
update() {
this.accelerate();
this.angle += this.clockwise ? this.velocity : -this.velocity;
this.updatePosition();
this.checkDetectors();
}
checkDetectors() {
state.detectors.forEach(detector => {
if (!this.detectedBy.has(detector) &&
this.x > detector.x &&
this.x < detector.x + detector.width &&
this.y > detector.y &&
this.y < detector.y + detector.height) {
this.detectedBy.add(detector);
detector.detect(this);
}
});
}
draw(ctx) {
// Draw trail
ctx.beginPath();
ctx.strokeStyle = this.clockwise ?
`rgba(0, ${155 + this.energy * 10}, 255, 0.5)` :
`rgba(255, ${155 + this.energy * 10}, 0, 0.5)`;
ctx.lineWidth = 2;
for (let i = 0; i < this.trail.length; i++) {
if (i === 0) {
ctx.moveTo(this.trail[i].x, this.trail[i].y);
} else {
ctx.lineTo(this.trail[i].x, this.trail[i].y);
}
}
ctx.stroke();
// Draw particle
ctx.beginPath();
ctx.fillStyle = this.clockwise ? '#00ffff' : '#ff9900';
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
// Energy indicator
ctx.beginPath();
ctx.strokeStyle = `rgba(255, 255, 255, ${this.energy / state.maxEnergy})`;
ctx.arc(this.x, this.y, this.size + 3, 0, Math.PI * 2);
ctx.stroke();
}
}
class Detector {
constructor(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.detections = [];
this.element = document.createElement('div');
this.element.className = 'detector';
this.element.style.left = `${x}px`;
this.element.style.top = `${y}px`;
this.element.style.width = `${width}px`;
this.element.style.height = `${height}px`;
document.body.appendChild(this.element);
}
detect(particle) {
this.detections.push({
time: state.time,
energy: particle.energy,
direction: particle.clockwise ? 'clockwise' : 'counterclockwise'
});
this.element.style.backgroundColor = 'rgba(0, 255, 0, 0.2)';
setTimeout(() => {
this.element.style.backgroundColor = 'transparent';
}, 100);
}
}
function createDetectors() {
const detectorSize = 40;
const positions = [
{ angle: 0, label: 'East' },
{ angle: Math.PI / 2, label: 'South' },
{ angle: Math.PI, label: 'West' },
{ angle: 3 * Math.PI / 2, label: 'North' }
];
positions.forEach(pos => {
const x = state.centerX + Math.cos(pos.angle) * state.ringRadius - detectorSize/2;
const y = state.centerY + Math.sin(pos.angle) * state.ringRadius - detectorSize/2;
state.detectors.push(new Detector(x, y, detectorSize, detectorSize));
});
}
function drawAccelerator() {
mainCtx.beginPath();
mainCtx.strokeStyle = '#333';
mainCtx.lineWidth = 20;
mainCtx.arc(state.centerX, state.centerY, state.ringRadius, 0, Math.PI * 2);
mainCtx.stroke();
// Energy sections
for (let i = 0; i < 8; i++) {
const angle = (i / 8) * Math.PI * 2;
mainCtx.beginPath();
mainCtx.strokeStyle = '#0f0';
mainCtx.lineWidth = 2;
const x = state.centerX + Math.cos(angle) * state.ringRadius;
const y = state.centerY + Math.sin(angle) * state.ringRadius;
mainCtx.arc(x, y, 10, 0, Math.PI * 2);
mainCtx.stroke();
}
}
function checkCollisions() {
if (!state.collisionsEnabled) return;
for (let i = 0; i < state.particles.length; i++) {
for (let j = i + 1; j < state.particles.length; j++) {
const p1 = state.particles[i];
const p2 = state.particles[j];
if (p1.clockwise !== p2.clockwise) {
const dx = p1.x - p2.x;
const dy = p1.y - p2.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 10 && p1.energy > 1 && p2.energy > 1) {
createCollisionEffect(p1.x, p1.y, p1.energy + p2.energy);
p1.collided = true;
p2.collided = true;
state.collisionCount++;
}
}
}
}
state.particles = state.particles.filter(p => !p.collided);
}
function createCollisionEffect(x, y, energy) {
const particles = 50;
const speed = 5;
for (let i = 0; i < particles; i++) {
const angle = (i / particles) * Math.PI * 2;
const velocity = {
x: Math.cos(angle) * speed * (Math.random() + 0.5),
y: Math.sin(angle) * speed * (Math.random() + 0.5)
};
state.collisions.push({
x, y,
velocity,
life: 1,
color: `hsl(${Math.random() * 60 + 30}, 100%, 50%)`
});
}
}
function updateCollisionEffects() {
state.collisions.forEach(p => {
p.x += p.velocity.x;
p.y += p.velocity.y;
p.life -= 0.02;
});
state.collisions = state.collisions.filter(p => p.life > 0);
}
function drawCollisionEffects() {
effectCtx.clearRect(0, 0, effectCanvas.width, effectCanvas.height);
state.collisions.forEach(p => {
effectCtx.beginPath();
effectCtx.fillStyle = p.color.replace(')', `, ${p.life})`);
effectCtx.arc(p.x, p.y, 2, 0, Math.PI * 2);
effectCtx.fill();
});
}
function updateUI() {
document.getElementById('energyLevel').textContent =
state.particles.length > 0 ?
state.particles[0].energy.toFixed(2) : '0.00';
document.getElementById('collisionCount').textContent = state.collisionCount;
document.getElementById('particleCount').textContent = state.particles.length;
// Update detector data
const detectorData = state.detectors.map((detector, i) => {
const recent = detector.detections.slice(-3);
return `Detector ${i + 1}: ${recent.length} recent detections`;
}).join('<br>');
document.getElementById('detectorData').innerHTML = detectorData;
}
// Control functions
function initializeAccelerator() {
state.particles = [];
state.collisions = [];
state.collisionCount = 0;
state.detectors.forEach(d => d.detections = []);
}
function injectParticles() {
state.particles.push(new Particle(true));
state.particles.push(new Particle(false));
}
function toggleAcceleration() {
state.acceleratorActive = !state.acceleratorActive;
}
function toggleCollisions() {
state.collisionsEnabled = !state.collisionsEnabled;
}
function animate() {
state.time++;
// Clear main canvas
mainCtx.fillStyle = 'rgba(0, 0, 0, 0.1)';
mainCtx.fillRect(0, 0, mainCanvas.width, mainCanvas.height);
drawAccelerator();
state.particles.forEach(particle => {
particle.update();
particle.draw(mainCtx);
});
checkCollisions();
updateCollisionEffects();
drawCollisionEffects();
updateUI();
requestAnimationFrame(animate);
}
// Initialize and start
createDetectors();
animate();
</script>
</body>
</html>