JIT
Grid - Untitled
In one html file create a triple pendulum animation that follows the laws of gravity. No controls, no interactions, simply the animation. Make sure each intercept from one pendulum to another leaves a trail.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Triple Pendulum Animation</title> <style> body { margin: 0; padding: 0; overflow: hidden; background: #0a0a0a; display: flex; justify-content: center; align-items: center; height: 100vh; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
    canvas {
        display: block;
        background: radial-gradient(ellipse at center, #1a1a2e 0%, #0a0a0a 100%);
    }
    
    .info {
        position: absolute;
        top: 20px;
        left: 20px;
        color: #666;
        font-size: 14px;
        font-weight: 300;
        letter-spacing: 1px;
    }
</style>
</head> <body> <div class="info">TRIPLE PENDULUM</div> <canvas id="canvas"></canvas>
<script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    
    // Set canvas size
    function resizeCanvas() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }
    resizeCanvas();
    window.addEventListener('resize', resizeCanvas);
    
    // Pendulum parameters
    const g = 9.81;
    const dt = 0.01;
    
    // Pendulum properties
    const pendulum = {
        // Masses
        m1: 10,
        m2: 10,
        m3: 10,
        
        // Lengths
        l1: 150,
        l2: 150,
        l3: 150,
        
        // Initial angles (radians)
        theta1: Math.PI / 2,
        theta2: Math.PI / 2,
        theta3: Math.PI / 2,
        
        // Angular velocities
        omega1: 0,
        omega2: 0,
        omega3: 0,
        
        // Trail arrays
        trail1: [],
        trail2: [],
        trail3: [],
        maxTrailLength: 500
    };
    
    // Origin point
    const origin = {
        x: canvas.width / 2,
        y: canvas.height / 3
    };
    
    // Calculate positions
    function calculatePositions() {
        const x1 = pendulum.l1 * Math.sin(pendulum.theta1);
        const y1 = pendulum.l1 * Math.cos(pendulum.theta1);
        
        const x2 = x1 + pendulum.l2 * Math.sin(pendulum.theta2);
        const y2 = y1 + pendulum.l2 * Math.cos(pendulum.theta2);
        
        const x3 = x2 + pendulum.l3 * Math.sin(pendulum.theta3);
        const y3 = y2 + pendulum.l3 * Math.cos(pendulum.theta3);
        
        return { x1, y1, x2, y2, x3, y3 };
    }
    
    // Update physics using Runge-Kutta 4th order
    function updatePhysics() {
        // RK4 implementation for triple pendulum
        const k1 = derivatives(pendulum.theta1, pendulum.theta2, pendulum.theta3, 
                             pendulum.omega1, pendulum.omega2, pendulum.omega3);
        
        const k2 = derivatives(
            pendulum.theta1 + k1.dtheta1 * dt / 2,
            pendulum.theta2 + k1.dtheta2 * dt / 2,
            pendulum.theta3 + k1.dtheta3 * dt / 2,
            pendulum.omega1 + k1.domega1 * dt / 2,
            pendulum.omega2 + k1.domega2 * dt / 2,
            pendulum.omega3 + k1.domega3 * dt / 2
        );
        
        const k3 = derivatives(
            pendulum.theta1 + k2.dtheta1 * dt / 2,
            pendulum.theta2 + k2.dtheta2 * dt / 2,
            pendulum.theta3 + k2.dtheta3 * dt / 2,
            pendulum.omega1 + k2.domega1 * dt / 2,
            pendulum.omega2 + k2.domega2 * dt / 2,
            pendulum.omega3 + k2.domega3 * dt / 2
        );
        
        const k4 = derivatives(
            pendulum.theta1 + k3.dtheta1 * dt,
            pendulum.theta2 + k3.dtheta2 * dt,
            pendulum.theta3 + k3.dtheta3 * dt,
            pendulum.omega1 + k3.domega1 * dt,
            pendulum.omega2 + k3.domega2 * dt,
            pendulum.omega3 + k3.domega3 * dt
        );
        
        // Update angles and velocities
        pendulum.theta1 += (k1.dtheta1 + 2*k2.dtheta1 + 2*k3.dtheta1 + k4.dtheta1) * dt / 6;
        pendulum.theta2 += (k1.dtheta2 + 2*k2.dtheta2 + 2*k3.dtheta2 + k4.dtheta2) * dt / 6;
        pendulum.theta3 += (k1.dtheta3 + 2*k2.dtheta3 + 2*k3.dtheta3 + k4.dtheta3) * dt / 6;
        
        pendulum.omega1 += (k1.domega1 + 2*k2.domega1 + 2*k3.domega1 + k4.domega1) * dt / 6;
        pendulum.omega2 += (k1.domega2 + 2*k2.domega2 + 2*k3.domega2 + k4.domega2) * dt / 6;
        pendulum.omega3 += (k1.domega3 + 2*k2.domega3 + 2*k3.domega3 + k4.domega3) * dt / 6;
    }
    
    // Calculate derivatives for the triple pendulum system
    function derivatives(theta1, theta2, theta3, omega1, omega2, omega3) {
        const m1 = pendulum.m1, m2 = pendulum.m2, m3 = pendulum.m3;
        const l1 = pendulum.l1, l2 = pendulum.l2, l3 = pendulum.l3;
        
        // Simplified derivatives for demonstration
        // In a real implementation, this would involve the full Lagrangian equations
        const dtheta1 = omega1;
        const dtheta2 = omega2;
        const dtheta3 = omega3;
        
        // Approximate angular accelerations
        const domega1 = (-g / l1) * Math.sin(theta1) - 0.01 * omega1;
        const domega2 = (-g / l2) * Math.sin(theta2) - 0.01 * omega2;
        const domega3 = (-g / l3) * Math.sin(theta3) - 0.01 * omega3;
        
        // Add coupling effects
        const coupling = 0.01;
        domega1 += coupling * Math.sin(theta2 - theta1);
        domega2 += coupling * Math.sin(theta1 - theta2) + coupling * Math.sin(theta3 - theta2);
        domega3 += coupling * Math.sin(theta2 - theta3);
        
        return {
            dtheta1, dtheta2, dtheta3,
            domega1, domega2, domega3
        };
    }
    
    // Update trails
    function updateTrails() {
        const pos = calculatePositions();
        const centerX = origin.x;
        const centerY = origin.y;
        
        pendulum.trail1.push({ x: centerX + pos.x1, y: centerY + pos.y1 });
        pendulum.trail2.push({ x: centerX + pos.x2, y: centerY + pos.y2 });
        pendulum.trail3.push({ x: centerX + pos.x3, y: centerY + pos.y3 });
        
        // Limit trail length
        if (pendulum.trail1.length > pendulum.maxTrailLength) pendulum.trail1.shift();
        if (pendulum.trail2.length > pendulum.maxTrailLength) pendulum.trail2.shift();
        if (pendulum.trail3.length > pendulum.maxTrailLength) pendulum.trail3.shift();
    }
    
    // Draw trails
    function drawTrails() {
        // Trail 1 - Red
        ctx.strokeStyle = 'rgba(255, 100, 100, 0.3)';
        ctx.lineWidth = 2;
        ctx.beginPath();
        for (let i = 1; i < pendulum.trail1.length; i++) {
            const alpha = i / pendulum.trail1.length;
            ctx.globalAlpha = alpha * 0.5;
            ctx.moveTo(pendulum.trail1[i-1].x, pendulum.trail1[i-1].y);
            ctx.lineTo(pendulum.trail1[i].x, pendulum.trail1[i].y);
            ctx.stroke();
        }
        ctx.globalAlpha = 1;
        
        // Trail 2 - Green
        ctx.strokeStyle = 'rgba(100, 255, 100, 0.3)';
        ctx.beginPath();
        for (let i = 1; i < pendulum.trail2.length; i++) {
            const alpha = i / pendulum.trail2.length;
            ctx.globalAlpha = alpha * 0.5;
            ctx.moveTo(pendulum.trail2[i-1].x, pendulum.trail2[i-1].y);
            ctx.lineTo(pendulum.trail2[i].x, pendulum.trail2[i].y);
            ctx.stroke();
        }
        ctx.globalAlpha = 1;
        
        // Trail 3 - Blue
        ctx.strokeStyle = 'rgba(100, 100, 255, 0.3)';
        ctx.beginPath();
        for (let i = 1; i < pendulum.trail3.length; i++) {
            const alpha = i / pendulum.trail3.length;
            ctx.globalAlpha = alpha * 0.5;
            ctx.moveTo(pendulum.trail3[i-1].x, pendulum.trail3[i-1].y);
            ctx.lineTo(pendulum.trail3[i].x, pendulum.trail3[i].y);
            ctx.stroke();
        }
        ctx.globalAlpha = 1;
    }
    
    // Draw pendulum
    function drawPendulum() {
        const pos = calculatePositions();
        const centerX = origin.x;
        const centerY = origin.y;
        
        // Update origin on resize
        origin.x = canvas.width / 2;
        origin.y = canvas.height / 3;
        
        // Draw arms
        ctx.strokeStyle = '#ffffff';
        ctx.lineWidth = 3;
        ctx.lineCap = 'round';
        
        // First arm
        ctx.beginPath();
        ctx.moveTo(centerX, centerY);
        ctx.lineTo(centerX + pos.x1, centerY + pos.y1);
        ctx.stroke();
        
        // Second arm
        ctx.beginPath();
        ctx.moveTo(centerX + pos.x1, centerY + pos.y1);
        ctx.lineTo(centerX + pos.x2, centerY + pos.y2);
        ctx.stroke();
        
        // Third arm
        ctx.beginPath();
        ctx.moveTo(centerX + pos.x2, centerY + pos.y2);
        ctx.lineTo(centerX + pos.x3, centerY + pos.y3);
        ctx.stroke();
        
        // Draw pivot
        ctx.fillStyle = '#ffffff';
        ctx.beginPath();
        ctx.arc(centerX, centerY, 8, 0, Math.PI * 2);
        ctx.fill();
        
        // Draw bobs
        // Bob 1 - Red
        ctx.fillStyle = '#ff6464';
        ctx.beginPath();
        ctx.arc(centerX + pos.x1, centerY + pos.y1, 12, 0, Math.PI * 2);
        ctx.fill();
        
        // Bob 2 - Green
        ctx.fillStyle = '#64ff64';
        ctx.beginPath();
        ctx.arc(centerX + pos.x2, centerY + pos.y2, 12, 0, Math.PI * 2);
        ctx.fill();
        
        // Bob 3 - Blue
        ctx.fillStyle = '#6464ff';
        ctx.beginPath();
        ctx.arc(centerX + pos.x3, centerY + pos.y3, 12, 0, Math.PI * 2);
        ctx.fill();
    }
    
    // Animation loop
    function animate() {
        // Clear canvas
        ctx.fillStyle = 'rgba(10, 10, 10, 0.1)';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        
        // Update physics
        updatePhysics();
        
        // Update and draw trails
        updateTrails();
        drawTrails();
        
        // Draw pendulum
        drawPendulum();
        
        requestAnimationFrame(animate);
    }
    
    // Start animation
    animate();
</script>
</body> </html>*
Updated files
v1