{"id":6296,"date":"2026-03-17T21:44:10","date_gmt":"2026-03-18T00:44:10","guid":{"rendered":"https:\/\/fisica2.fica.unsl.edu.ar\/?page_id=6296"},"modified":"2026-03-18T20:17:17","modified_gmt":"2026-03-18T23:17:17","slug":"movimiento_cargas_campo_electrico","status":"publish","type":"page","link":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/","title":{"rendered":"movimiento_cargas_campo_electrico"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"6296\" class=\"elementor elementor-6296\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-1563226 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"1563226\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-f1486f7\" data-id=\"f1486f7\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-1620d43 elementor-widget elementor-widget-html\" data-id=\"1620d43\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"es\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>Simulador Condensador de Placas<\/title>\r\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\r\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=JetBrains+Mono:wght@400;500;700&family=Space+Grotesk:wght@400;500;600;700&display=swap\" rel=\"stylesheet\">\r\n    <style>\r\n        :root {\r\n            --bg-primary: #050a14;\r\n            --bg-secondary: #0c1525;\r\n            --bg-tertiary: #141d2f;\r\n            --accent-cyan: #00ffcc;\r\n            --accent-orange: #ff6b35;\r\n            --accent-yellow: #eab308;\r\n            --accent-green: #22c55e;\r\n            --positive-color: #ef4444;\r\n            --negative-color: #3b82f6;\r\n            --text-primary: #f1f5f9;\r\n            --text-secondary: #94a3b8;\r\n            --border: #1e293b;\r\n        }\r\n\r\n        body {\r\n            font-family: 'Space Grotesk', sans-serif;\r\n            background-color: var(--bg-primary);\r\n            color: var(--text-primary);\r\n            overflow-y: auto;\r\n            overflow-x: hidden;\r\n        }\r\n\r\n        .font-mono {\r\n            font-family: 'JetBrains Mono', monospace;\r\n        }\r\n\r\n        .canvas-container {\r\n            position: relative;\r\n            background: var(--bg-primary);\r\n            border: 1px solid var(--border);\r\n            box-shadow: inset 0 0 50px rgba(0, 0, 0, 0.5);\r\n        }\r\n\r\n        .control-panel {\r\n            background: var(--bg-secondary);\r\n            border-left: 1px solid var(--border);\r\n            display: flex;\r\n            flex-direction: column;\r\n        }\r\n\r\n        \/* --- INICIO CORRECCI\u00d3N CSS PARA WORDPRESS --- *\/\r\n        input[type=\"number\"], select {\r\n            background: var(--bg-tertiary) !important;\r\n            border: 1px solid var(--border);\r\n            color: var(--text-primary) !important;\r\n            padding: 8px;\r\n            border-radius: 6px;\r\n            font-family: 'JetBrains Mono', monospace;\r\n            font-size: 13px;\r\n            width: 100%;\r\n            transition: border-color 0.2s;\r\n        }\r\n\r\n        input[type=\"number\"]:focus, select:focus {\r\n            outline: none;\r\n            border-color: var(--accent-cyan);\r\n            background: var(--bg-tertiary) !important;\r\n            color: var(--text-primary) !important;\r\n        }\r\n\r\n        input:-webkit-autofill,\r\n        input:-webkit-autofill:hover,\r\n        input:-webkit-autofill:focus {\r\n            -webkit-box-shadow: 0 0 0px 1000px var(--bg-tertiary) inset !important;\r\n            -webkit-text-fill-color: var(--text-primary) !important;\r\n            transition: background-color 5000s ease-in-out 0s;\r\n        }\r\n        \/* --- FIN CORRECCI\u00d3N CSS --- *\/\r\n\r\n        input[type=\"range\"] {\r\n            -webkit-appearance: none;\r\n            width: 100%;\r\n            height: 4px;\r\n            background: var(--bg-tertiary);\r\n            border-radius: 2px;\r\n        }\r\n\r\n        input[type=\"range\"]::-webkit-slider-thumb {\r\n            -webkit-appearance: none;\r\n            width: 16px;\r\n            height: 16px;\r\n            background: var(--accent-cyan);\r\n            border-radius: 50%;\r\n            cursor: pointer;\r\n            box-shadow: 0 0 10px var(--accent-cyan);\r\n        }\r\n\r\n        .btn {\r\n            padding: 10px 16px;\r\n            border-radius: 6px;\r\n            font-weight: 600;\r\n            font-size: 13px;\r\n            cursor: pointer;\r\n            transition: all 0.2s;\r\n            border: none;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 8px;\r\n        }\r\n\r\n        .btn-primary { background: var(--accent-cyan); color: var(--bg-primary); }\r\n        .btn-primary:hover { opacity: 0.9; transform: translateY(-1px); }\r\n        \r\n        .btn-pause { background: var(--accent-yellow); color: var(--bg-primary); }\r\n        .btn-pause:hover { opacity: 0.9; }\r\n        \r\n        .btn-resume { background: var(--accent-green); color: white; }\r\n        .btn-resume:hover { opacity: 0.9; }\r\n\r\n        .btn-secondary { background: var(--bg-tertiary); color: var(--text-primary); border: 1px solid var(--border); }\r\n        .btn-secondary:hover { background: var(--border); }\r\n        \r\n        .btn-apply { background: var(--accent-orange); color: white; }\r\n        .btn-apply:hover { opacity: 0.9; }\r\n\r\n        .data-card {\r\n            background: var(--bg-tertiary);\r\n            border: 1px solid var(--border);\r\n            border-radius: 8px;\r\n            padding: 10px; \r\n        }\r\n\r\n        .state-grid { \r\n            display: grid; \r\n            grid-template-columns: repeat(3, 1fr); \r\n            gap: 8px; \r\n        }\r\n        \r\n        .graph-container {\r\n            background: var(--bg-secondary);\r\n            border: 1px solid var(--border);\r\n            border-radius: 8px;\r\n            overflow: hidden;\r\n            position: relative; \r\n        }\r\n\r\n        .section-compact {\r\n            padding-bottom: 12px;\r\n            margin-bottom: 12px;\r\n            border-bottom: 1px solid var(--border);\r\n        }\r\n\r\n        #tooltip {\r\n            position: absolute;\r\n            background: rgba(0, 0, 0, 0.85);\r\n            border: 1px solid var(--accent-cyan);\r\n            padding: 6px 10px;\r\n            border-radius: 4px;\r\n            pointer-events: none;\r\n            opacity: 0;\r\n            transition: opacity 0.2s;\r\n            z-index: 100;\r\n            font-family: 'JetBrains Mono', monospace;\r\n            font-size: 12px;\r\n            color: var(--text-primary);\r\n            box-shadow: 0 0 10px rgba(0, 255, 204, 0.2);\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body class=\"min-h-screen flex flex-col overflow-y-auto\">\r\n\r\n    <!-- Header -->\r\n    <header class=\"h-14 border-b border-[var(--border)] flex items-center justify-between px-6 bg-[var(--bg-secondary)]\/80 backdrop-blur z-10 shrink-0\">\r\n        <div class=\"flex items-center gap-3\">\r\n            <div class=\"w-8 h-8 rounded bg-[var(--accent-cyan)] flex items-center justify-center text-[var(--bg-primary)] font-bold\">C<\/div>\r\n            <h1 class=\"text-lg font-semibold tracking-tight\">Movimiento de una carga en un campo el\u00e9ctrico<\/h1>\r\n        <\/div>\r\n        <div class=\"flex items-center gap-6\">\r\n            <div class=\"font-mono text-sm\">\r\n                <span class=\"text-[var(--text-secondary)]\">t = <\/span>\r\n                <span id=\"time-display\" class=\"text-black\">0.00 s<\/span>\r\n            <\/div>\r\n            <div id=\"status-indicator\" class=\"flex items-center gap-2 px-3 py-1 rounded-full border border-[var(--border)]\">\r\n                <span id=\"status-dot\" class=\"w-2 h-2 rounded-full bg-gray-500\"><\/span>\r\n                <span id=\"status-text\" class=\"text-xs font-medium uppercase tracking-wider text-black\">Listo<\/span>\r\n            <\/div>\r\n        <\/div>\r\n    <\/header>\r\n\r\n    <!-- Main Content -->\r\n    <main class=\"flex-1 flex flex-col lg:flex-row overflow-y-visible\">\r\n        \r\n        <!-- Canvas Area -->\r\n        <div class=\"flex-1 flex flex-col p-4 gap-4 min-h-[400px]\">\r\n            \r\n            <!-- Canvas de Simulacion -->\r\n            <div class=\"h-[55%] min-h-[300px] canvas-container rounded-lg overflow-hidden relative\">\r\n                <canvas id=\"simCanvas\"><\/canvas>\r\n                <div id=\"tooltip\"><\/div>\r\n                \r\n                <div class=\"absolute top-4 left-4 flex flex-col gap-2\">\r\n                    <div class=\"px-3 py-1.5 bg-black\/60 backdrop-blur rounded text-xs font-mono flex items-center gap-2\">\r\n                        <span class=\"text-[var(--text-secondary)]\">FPS<\/span>\r\n                        <span id=\"fps-counter\" class=\"text-[var(--accent-cyan)]\">60<\/span>\r\n                    <\/div>\r\n                <\/div>\r\n                \r\n                <div class=\"absolute bottom-4 left-4 flex gap-4 px-3 py-2 bg-black\/60 backdrop-blur rounded text-xs\">\r\n                    <div class=\"flex items-center gap-2\"><span class=\"w-3 h-1 bg-[var(--accent-cyan)]\"><\/span> Velocidad<\/div>\r\n                    <div class=\"flex items-center gap-2\"><span class=\"w-3 h-1 bg-[var(--accent-orange)]\"><\/span> Fuerza<\/div>\r\n                <\/div>\r\n            <\/div>\r\n\r\n            <!-- Graphs -->\r\n            <div class=\"h-[45%] min-h-[280px] grid grid-cols-2 grid-rows-2 gap-4\">\r\n                <div class=\"graph-container p-2\">\r\n                    <div class=\"text-[10px] uppercase tracking-wider text-[var(--text-secondary)] mb-1 px-1\">Velocidad Vx<\/div>\r\n                    <div id=\"graph-vx-val\" class=\"absolute top-6 right-2 font-mono text-xs text-[var(--accent-cyan)] opacity-70\">0.00 m\/s<\/div>\r\n                    <canvas id=\"graphVx\"><\/canvas>\r\n                <\/div>\r\n                <div class=\"graph-container p-2\">\r\n                    <div class=\"text-[10px] uppercase tracking-wider text-[var(--text-secondary)] mb-1 px-1\">Aceleraci\u00f3n (Ay)<\/div>\r\n                    <div id=\"graph-ay-val\" class=\"absolute top-6 right-2 font-mono text-xs text-[var(--accent-orange)] opacity-70\">0.00 m\/s\u00b2<\/div>\r\n                    <canvas id=\"graphAcc\"><\/canvas>\r\n                <\/div>\r\n                <div class=\"graph-container p-2\">\r\n                    <div class=\"text-[10px] uppercase tracking-wider text-[var(--text-secondary)] mb-1 px-1\">Posici\u00f3n Y<\/div>\r\n                    <div id=\"graph-y-val\" class=\"absolute top-6 right-2 font-mono text-xs text-[var(--accent-green)] opacity-70\">0.00 m<\/div>\r\n                    <canvas id=\"graphPos\"><\/canvas>\r\n                <\/div>\r\n                <div class=\"graph-container p-2\">\r\n                    <div class=\"text-[10px] uppercase tracking-wider text-[var(--text-secondary)] mb-1 px-1\">Velocidad Vy<\/div>\r\n                    <div id=\"graph-vy-val\" class=\"absolute top-6 right-2 font-mono text-xs text-[var(--accent-yellow)] opacity-70\">0.00 m\/s<\/div>\r\n                    <canvas id=\"graphVel\"><\/canvas>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n\r\n        <!-- Control Panel -->\r\n        <aside class=\"w-full lg:w-[360px] control-panel overflow-y-auto p-4 flex flex-col gap-2 shrink-0\">\r\n            \r\n            <!-- Simulation Controls -->\r\n            <section class=\"section-compact\">\r\n                <h3 class=\"text-xs uppercase tracking-wider text-[var(--text-secondary)] mb-2\">Control<\/h3>\r\n                <div class=\"grid grid-cols-3 gap-2 mb-3\">\r\n                    <button id=\"btn-start\" class=\"btn btn-primary col-span-1\">\r\n                        <svg class=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\"><path d=\"M6.3 2.841A1.5 1.5 0 004 4.11V15.89a1.5 1.5 0 002.3 1.269l9.344-5.89a1.5 1.5 0 000-2.538L6.3 2.84z\"\/><\/svg>\r\n                        Iniciar\r\n                    <\/button>\r\n                    <button id=\"btn-pause\" class=\"btn btn-pause col-span-1\">\r\n                        <svg class=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\"><path d=\"M5.75 3a.75.75 0 00-.75.75v12.5c0 .414.336.75.75.75h1.5a.75.75 0 00.75-.75V3.75A.75.75 0 007.25 3h-1.5zM12.75 3a.75.75 0 00-.75.75v12.5c0 .414.336.75.75.75h1.5a.75.75 0 00.75-.75V3.75a.75.75 0 00-.75-.75h-1.5z\"\/><\/svg>\r\n                        Pausar\r\n                    <\/button>\r\n                    <button id=\"btn-reset\" class=\"btn btn-secondary col-span-1\">\r\n                        <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99\"\/><\/svg>\r\n                        Reset\r\n                    <\/button>\r\n                <\/div>\r\n                \r\n                <div>\r\n                    <label class=\"flex justify-between text-xs text-[var(--text-secondary)] mb-1\">\r\n                        <span>Velocidad Simulacion<\/span>\r\n                        <span id=\"val-speed\" class=\"text-[var(--accent-cyan)]\">1.0x<\/span>\r\n                    <\/label>\r\n                    <input type=\"range\" id=\"input-speed\" min=\"0.1\" max=\"3\" step=\"0.1\" value=\"1\">\r\n                <\/div>\r\n            <\/section>\r\n\r\n            <!-- Particle Configuration -->\r\n            <section class=\"section-compact\">\r\n                <h3 class=\"text-xs uppercase tracking-wider text-[var(--text-secondary)] mb-2\">Particula<\/h3>\r\n                \r\n                <div class=\"grid grid-cols-2 gap-3 mb-3\">\r\n                    <div>\r\n                        <label class=\"text-xs text-[var(--text-secondary)] block mb-1\">Carga (C)<\/label>\r\n                        <input type=\"number\" id=\"input-q\" value=\"1e-8\" step=\"1e-9\">\r\n                    <\/div>\r\n                    <div>\r\n                        <label class=\"text-xs text-[var(--text-secondary)] block mb-1\">Masa (kg)<\/label>\r\n                        <input type=\"number\" id=\"input-m\" value=\"1e-6\" step=\"1e-7\">\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <div class=\"grid grid-cols-2 gap-3 mb-3\">\r\n                    <div>\r\n                        <label class=\"text-xs text-[var(--text-secondary)] block mb-1\">Vel. Inicial X (m\/s)<\/label>\r\n                        <input type=\"number\" id=\"input-vx\" value=\"0\" step=\"0.1\">\r\n                    <\/div>\r\n                    <div>\r\n                        <label class=\"text-xs text-[var(--text-secondary)] block mb-1\">Vel. Inicial Y (m\/s)<\/label>\r\n                        <input type=\"number\" id=\"input-vy\" value=\"0\" step=\"0.1\">\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <div class=\"grid grid-cols-2 gap-3 mb-3\">\r\n                    <div>\r\n                        <label class=\"text-xs text-[var(--text-secondary)] block mb-1\">Posicion Inicial X (m)<\/label>\r\n                        <input type=\"number\" id=\"input-x0\" value=\"0.5\" step=\"0.1\">\r\n                    <\/div>\r\n                    <div>\r\n                        <label class=\"text-xs text-[var(--text-secondary)] block mb-1\">Posicion Inicial Y (m)<\/label>\r\n                        <input type=\"number\" id=\"input-y0\" value=\"1.5\" step=\"0.1\">\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <button id=\"btn-apply\" class=\"btn btn-apply w-full mt-1\">\r\n                    Aplicar Cambios\r\n                <\/button>\r\n            <\/section>\r\n\r\n            <!-- Electric Field Configuration -->\r\n            <section class=\"section-compact\">\r\n                <h3 class=\"text-xs uppercase tracking-wider text-[var(--text-secondary)] mb-2\">Campo Electrico (Entre Placas)<\/h3>\r\n                \r\n                <div>\r\n                    <label class=\"text-xs text-[var(--text-secondary)] block mb-1\">Ey (N\/C)<\/label>\r\n                    <input type=\"number\" id=\"input-ey\" value=\"-5000\" step=\"1000\">\r\n                    <p class=\"text-[10px] text-[var(--text-secondary)] mt-1 opacity-70\">Positivo: Placa(+) arriba. Negativo: Placa(-) arriba.<\/p>\r\n                <\/div>\r\n            <\/section>\r\n\r\n            <!-- State Vectors -->\r\n            <section class=\"pt-2\">\r\n                <h3 class=\"text-xs uppercase tracking-wider text-[var(--text-secondary)] mb-2\">Estado Actual<\/h3>\r\n                <div class=\"state-grid\">\r\n                    <div class=\"data-card text-center\">\r\n                        <div class=\"text-[10px] text-[var(--text-secondary)] mb-1\">X (m)<\/div>\r\n                        <div id=\"out-x\" class=\"font-mono text-sm text-[var(--accent-cyan)]\">0.00<\/div>\r\n                    <\/div>\r\n                    <div class=\"data-card text-center\">\r\n                        <div class=\"text-[10px] text-[var(--text-secondary)] mb-1\">Y (m)<\/div>\r\n                        <div id=\"out-y\" class=\"font-mono text-sm text-[var(--accent-cyan)]\">0.00<\/div>\r\n                    <\/div>\r\n                    <div class=\"data-card text-center\">\r\n                        <div class=\"text-[10px] text-[var(--text-secondary)] mb-1\">En Campo<\/div>\r\n                        <div id=\"out-field\" class=\"font-mono text-sm text-white\">NO<\/div>\r\n                    <\/div>\r\n                    \r\n                    <div class=\"data-card text-center\">\r\n                        <div class=\"text-[10px] text-[var(--text-secondary)] mb-1\">Vx (m\/s)<\/div>\r\n                        <div id=\"out-vx\" class=\"font-mono text-sm text-[var(--accent-orange)]\">0.00<\/div>\r\n                    <\/div>\r\n                    <div class=\"data-card text-center\">\r\n                        <div class=\"text-[10px] text-[var(--text-secondary)] mb-1\">Vy (m\/s)<\/div>\r\n                        <div id=\"out-vy\" class=\"font-mono text-sm text-[var(--accent-orange)]\">0.00<\/div>\r\n                    <\/div>\r\n                    <div class=\"data-card text-center\">\r\n                        <div class=\"text-[10px] text-[var(--text-secondary)] mb-1\">|V| (m\/s)<\/div>\r\n                        <div id=\"out-v\" class=\"font-mono text-sm text-[var(--accent-orange)] font-bold\">0.00<\/div>\r\n                    <\/div>\r\n                <\/div>\r\n\r\n\r\n\r\n                <!-- LOGO AGREGADO AQUI -->\r\n                <div class=\"flex flex-col items-center justify-center w-full mt-4\">\r\n    <a href=\"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/FISAR_SIM\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"transition-transform hover:scale-105\">\r\n        <img decoding=\"async\" src=\"FISAR_SIM_1\" \r\n             alt=\"FISAR Logo\" \r\n             style=\"height: 80px !important; width: auto;\" \r\n             class=\"opacity-80 hover:opacity-100 transition-opacity\">\r\n    <\/a>\r\n    \r\n    <span class=\"mt-2 text-sm font-semibold tracking-widest text-gray-500 uppercase\">\r\n        FICA UNSL\r\n    <\/span>\r\n<\/div>\r\n            <\/section>\r\n        <\/aside>\r\n    <\/main>\r\n\r\n    <script>\r\n        \/\/ ==========================================\r\n        \/\/ CONFIGURACION Y ESTADO\r\n        \/\/ ==========================================\r\n        \r\n        const config = {\r\n            q: 1e-8, m: 1e-6,\r\n            x0: 0.5, y0: 1.5,\r\n            vx0: 0.5, vy0: 0,\r\n            ey: -5000\r\n        };\r\n\r\n        let state = {\r\n            x: config.x0, y: config.y0,\r\n            vx: config.vx0, vy: config.vy0,\r\n            ax: 0, ay: 0, t: 0\r\n        };\r\n\r\n        let isRunning = false;\r\n        let hasCollided = false;\r\n        let simSpeed = 1.0;\r\n        let fpsCount = 0;\r\n        let fpsTime = 0;\r\n        \r\n        const trail = [];\r\n        const MAX_TRAIL = 500;\r\n        const graphData = { t: [], y: [], vy: [], vx: [], ay: [] };\r\n        const MAX_GRAPH_POINTS = 5000; \r\n\r\n        const canvas = document.getElementById('simCanvas');\r\n        const ctx = canvas.getContext('2d');\r\n        const tooltip = document.getElementById('tooltip');\r\n        \r\n        const graphVxCanvas = document.getElementById('graphVx');\r\n        const graphVxCtx = graphVxCanvas.getContext('2d');\r\n        const graphAccCanvas = document.getElementById('graphAcc');\r\n        const graphAccCtx = graphAccCanvas.getContext('2d');\r\n        const graphPosCanvas = document.getElementById('graphPos');\r\n        const graphPosCtx = graphPosCanvas.getContext('2d');\r\n        const graphVelCanvas = document.getElementById('graphVel');\r\n        const graphVelCtx = graphVelCanvas.getContext('2d');\r\n\r\n        const PIXELS_PER_METER = 80; \r\n        const PARTICLE_RADIUS_PX = 10;\r\n        const PLATE_HEIGHT = 15;\r\n        const PLATE_GAP_METERS = 3.0; \r\n        \r\n        let platesMeters = { xStart: 0, xEnd: 0, yBottom: 0, yTop: 3.0 };\r\n\r\n        const btnPause = document.getElementById('btn-pause');\r\n        const statusDot = document.getElementById('status-dot');\r\n        const statusText = document.getElementById('status-text');\r\n\r\n        \/\/ ==========================================\r\n        \/\/ INICIALIZACION\r\n        \/\/ ==========================================\r\n        \r\n        function resizeCanvases() {\r\n            const container = canvas.parentElement;\r\n            canvas.width = container.clientWidth;\r\n            canvas.height = container.clientHeight;\r\n            \r\n            const graphs = [graphVxCanvas, graphAccCanvas, graphPosCanvas, graphVelCanvas];\r\n            graphs.forEach(g => {\r\n                g.width = g.parentElement.clientWidth;\r\n                g.height = g.parentElement.clientHeight - 20;\r\n            });\r\n            \r\n            calculatePlateGeometry();\r\n        }\r\n\r\n        function calculatePlateGeometry() {\r\n            const viewWidthMeters = canvas.width \/ PIXELS_PER_METER;\r\n            const platesWidthMeters = viewWidthMeters * 0.6;\r\n            const xOffsetMeters = (viewWidthMeters - platesWidthMeters) \/ 2;\r\n            platesMeters.xStart = xOffsetMeters;\r\n            platesMeters.xEnd = xOffsetMeters + platesWidthMeters;\r\n\r\n            const viewHeightMeters = canvas.height \/ PIXELS_PER_METER;\r\n            const yOffsetMeters = (viewHeightMeters - PLATE_GAP_METERS) \/ 2;\r\n            platesMeters.yBottom = yOffsetMeters;\r\n            platesMeters.yTop = yOffsetMeters + PLATE_GAP_METERS;\r\n        }\r\n\r\n        function updatePauseButton() {\r\n            if (hasCollided) {\r\n                btnPause.disabled = true;\r\n                btnPause.classList.add('opacity-50', 'cursor-not-allowed');\r\n                btnPause.classList.remove('btn-pause', 'btn-resume');\r\n                btnPause.innerHTML = `<svg class=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\"><path d=\"M5.75 3a.75.75 0 00-.75.75v12.5c0 .414.336.75.75.75h1.5a.75.75 0 00.75-.75V3.75A.75.75 0 007.25 3h-1.5zM12.75 3a.75.75 0 00-.75.75v12.5c0 .414.336.75.75.75h1.5a.75.75 0 00.75-.75V3.75a.75.75 0 00-.75-.75h-1.5z\"\/><\/svg> Fin`;\r\n                return;\r\n            }\r\n\r\n            btnPause.disabled = false;\r\n            btnPause.classList.remove('opacity-50', 'cursor-not-allowed');\r\n            if (isRunning) {\r\n                btnPause.classList.add('btn-pause');\r\n                btnPause.classList.remove('btn-resume');\r\n                btnPause.innerHTML = `<svg class=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\"><path d=\"M5.75 3a.75.75 0 00-.75.75v12.5c0 .414.336.75.75.75h1.5a.75.75 0 00.75-.75V3.75A.75.75 0 007.25 3h-1.5zM12.75 3a.75.75 0 00-.75.75v12.5c0 .414.336.75.75.75h1.5a.75.75 0 00.75-.75V3.75a.75.75 0 00-.75-.75h-1.5z\"\/><\/svg> Pausar`;\r\n            } else {\r\n                btnPause.classList.add('btn-resume');\r\n                btnPause.classList.remove('btn-pause');\r\n                btnPause.innerHTML = `<svg class=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 20 20\"><path d=\"M6.3 2.841A1.5 1.5 0 004 4.11V15.89a1.5 1.5 0 002.3 1.269l9.344-5.89a1.5 1.5 0 000-2.538L6.3 2.84z\"\/><\/svg> Continuar`;\r\n            }\r\n        }\r\n\r\n        function resetSimulation() {\r\n            config.q = parseFloat(document.getElementById('input-q').value) || 1e-8;\r\n            config.m = parseFloat(document.getElementById('input-m').value) || 1e-6;\r\n            config.x0 = parseFloat(document.getElementById('input-x0').value) || 0.5;\r\n            config.y0 = parseFloat(document.getElementById('input-y0').value) || 1.5;\r\n            \r\n            config.vx0 = parseFloat(document.getElementById('input-vx').value); \r\n            if (isNaN(config.vx0)) config.vx0 = 0;\r\n            \r\n            config.vy0 = parseFloat(document.getElementById('input-vy').value);\r\n            if (isNaN(config.vy0)) config.vy0 = 0;\r\n\r\n            state.x = config.x0; state.y = config.y0;\r\n            state.vx = config.vx0; state.vy = config.vy0;\r\n            state.ax = 0; state.ay = 0; state.t = 0;\r\n            \r\n            hasCollided = false; isRunning = false;\r\n            trail.length = 0;\r\n            \r\n            graphData.t.length = 0; graphData.y.length = 0; \r\n            graphData.vy.length = 0; graphData.vx.length = 0; graphData.ay.length = 0;\r\n            \r\n            graphData.t.push(0);\r\n            graphData.y.push(state.y);\r\n            graphData.vy.push(state.vy);\r\n            graphData.vx.push(state.vx);\r\n            graphData.ay.push(0); \r\n\r\n            statusText.innerText = 'Listo';\r\n            statusDot.className = 'w-2 h-2 rounded-full bg-gray-500';\r\n            \r\n            checkFieldStatus();\r\n            updatePauseButton();\r\n            draw();\r\n        }\r\n\r\n        function checkFieldStatus() {\r\n            const insideX = state.x >= platesMeters.xStart && state.x <= platesMeters.xEnd;\r\n            const insideY = state.y >= platesMeters.yBottom && state.y <= platesMeters.yTop;\r\n            const insideField = insideX && insideY;\r\n            document.getElementById('out-field').innerText = insideField ? \"SI\" : \"NO\";\r\n            document.getElementById('out-field').className = `font-mono text-sm ${insideField ? 'text-[var(--accent-orange)]' : 'text-white'}`;\r\n        }\r\n\r\n        \/\/ ==========================================\r\n        \/\/ FISICA\r\n        \/\/ ==========================================\r\n\r\n        function updatePhysics(dt) {\r\n            if (hasCollided) return;\r\n            const particleRadiusM = PARTICLE_RADIUS_PX \/ PIXELS_PER_METER;\r\n\r\n            const insideX = state.x >= platesMeters.xStart && state.x <= platesMeters.xEnd;\r\n            const insideY = state.y >= platesMeters.yBottom && state.y <= platesMeters.yTop;\r\n            const insideField = insideX && insideY;\r\n\r\n            document.getElementById('out-field').innerText = insideField ? \"SI\" : \"NO\";\r\n            document.getElementById('out-field').className = `font-mono text-sm ${insideField ? 'text-[var(--accent-orange)]' : 'text-white'}`;\r\n\r\n            if (insideField) {\r\n                const fy = config.q * config.ey;\r\n                state.ay = fy \/ config.m;\r\n            } else {\r\n                state.ay = 0; \r\n            }\r\n            \r\n            state.vy += state.ay * dt;\r\n            state.y += state.vy * dt;\r\n            \r\n            state.vx = config.vx0; \r\n            state.x += state.vx * dt;\r\n            \r\n            state.t += dt;\r\n\r\n            if (insideX) {\r\n                if (state.y - particleRadiusM <= platesMeters.yBottom) {\r\n                    state.y = platesMeters.yBottom + particleRadiusM;\r\n                    handleCollision(\"Placa Inferior\");\r\n                }\r\n                else if (state.y + particleRadiusM >= platesMeters.yTop) {\r\n                    state.y = platesMeters.yTop - particleRadiusM;\r\n                    handleCollision(\"Placa Superior\");\r\n                }\r\n            }\r\n\r\n            if (!hasCollided) {\r\n                if (state.y - particleRadiusM < 0) {\r\n                    state.y = particleRadiusM;\r\n                    handleCollision(\"Suelo\");\r\n                }\r\n                const globalTop = canvas.height \/ PIXELS_PER_METER;\r\n                if (state.y + particleRadiusM > globalTop) {\r\n                    state.y = globalTop - particleRadiusM;\r\n                    handleCollision(\"Techo\");\r\n                }\r\n            }\r\n\r\n            if (!hasCollided) {\r\n                const px = state.x * PIXELS_PER_METER;\r\n                const py = canvas.height - (state.y * PIXELS_PER_METER);\r\n                trail.push({ x: px, y: py });\r\n                if (trail.length > MAX_TRAIL) trail.shift();\r\n\r\n                graphData.t.push(state.t);\r\n                graphData.y.push(state.y);\r\n                graphData.vy.push(state.vy);\r\n                graphData.vx.push(state.vx);\r\n                graphData.ay.push(state.ay);\r\n            }\r\n        }\r\n\r\n        function handleCollision(surface) {\r\n            state.vx = 0; state.vy = 0;\r\n            state.ax = 0; state.ay = 0;\r\n            hasCollided = true; isRunning = false;\r\n            statusText.innerText = 'Detenido';\r\n            statusDot.className = 'w-2 h-2 rounded-full bg-[var(--accent-orange)]';\r\n            updatePauseButton();\r\n        }\r\n\r\n        \/\/ ==========================================\r\n        \/\/ RENDERIZADO\r\n        \/\/ ==========================================\r\n\r\n        function draw() {\r\n            ctx.fillStyle = '#050a14';\r\n            ctx.fillRect(0, 0, canvas.width, canvas.height);\r\n            drawReferenceSystem();\r\n            drawPlates();\r\n            drawFieldLines();\r\n            drawTrail();\r\n            drawParticle();\r\n            if (!hasCollided) drawVectors();\r\n            updateDataUI();\r\n            drawGraphs();\r\n        }\r\n\r\n        function drawPlates() {\r\n            const xStartPx = platesMeters.xStart * PIXELS_PER_METER;\r\n            const xEndPx = platesMeters.xEnd * PIXELS_PER_METER;\r\n            const yBottomPx = canvas.height - (platesMeters.yBottom * PIXELS_PER_METER);\r\n            const yTopPx = canvas.height - (platesMeters.yTop * PIXELS_PER_METER);\r\n            const plateWidthPx = xEndPx - xStartPx;\r\n\r\n            let topColor, bottomColor;\r\n            if (config.ey < 0) {\r\n                topColor = '#ef4444'; bottomColor = '#3b82f6';\r\n            } else {\r\n                topColor = '#3b82f6'; bottomColor = '#ef4444';\r\n            }\r\n\r\n            ctx.fillStyle = topColor;\r\n            ctx.fillRect(xStartPx, yTopPx - PLATE_HEIGHT, plateWidthPx, PLATE_HEIGHT);\r\n            ctx.fillStyle = bottomColor;\r\n            ctx.fillRect(xStartPx, yBottomPx, plateWidthPx, PLATE_HEIGHT);\r\n            \r\n            ctx.fillStyle = 'white';\r\n            ctx.font = 'bold 12px Space Grotesk';\r\n            ctx.textAlign = 'center';\r\n            const symbolTop = config.ey < 0 ? '+' : '-';\r\n            const symbolBottom = config.ey < 0 ? '-' : '+';\r\n            \r\n            for(let x = xStartPx + 20; x < xEndPx; x += 40) {\r\n                ctx.fillText(symbolTop, x, yTopPx - 4);\r\n                ctx.fillText(symbolBottom, x, yBottomPx + 12);\r\n            }\r\n        }\r\n\r\n        function drawReferenceSystem() {\r\n            const startX = 30;\r\n            ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';\r\n            ctx.lineWidth = 1;\r\n            ctx.beginPath();\r\n            ctx.moveTo(startX, 20);\r\n            ctx.lineTo(startX, canvas.height - 20);\r\n            ctx.stroke();\r\n\r\n            ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';\r\n            ctx.font = '10px JetBrains Mono';\r\n            ctx.textAlign = 'right';\r\n\r\n            for (let i = 0; i <= (canvas.height\/PIXELS_PER_METER); i += 0.5) {\r\n                const yPos = canvas.height - (i * PIXELS_PER_METER);\r\n                ctx.beginPath();\r\n                ctx.moveTo(startX, yPos);\r\n                ctx.lineTo(startX + 6, yPos);\r\n                ctx.stroke();\r\n                ctx.fillText(i.toFixed(1) + \" m\", startX - 4, yPos + 3);\r\n            }\r\n        }\r\n\r\n        function drawFieldLines() {\r\n            const xStartPx = platesMeters.xStart * PIXELS_PER_METER;\r\n            const xEndPx = platesMeters.xEnd * PIXELS_PER_METER;\r\n            const yBottomPx = canvas.height - (platesMeters.yBottom * PIXELS_PER_METER);\r\n            const yTopPx = canvas.height - (platesMeters.yTop * PIXELS_PER_METER);\r\n\r\n            const startX = xStartPx + 10;\r\n            const endX = xEndPx - 10;\r\n            const startY = yTopPx + 5;\r\n            const endY = yBottomPx - 5;\r\n            \r\n            ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';\r\n            ctx.lineWidth = 1;\r\n\r\n            for (let x = startX; x < endX; x += 40) {\r\n                ctx.beginPath();\r\n                ctx.moveTo(x, startY);\r\n                ctx.lineTo(x, endY);\r\n                ctx.stroke();\r\n\r\n                if (config.ey !== 0) {\r\n                    const arrowY = config.ey < 0 ? endY : startY; \r\n                    const dir = config.ey < 0 ? 1 : -1; \r\n                    ctx.beginPath();\r\n                    ctx.moveTo(x, arrowY);\r\n                    ctx.lineTo(x - 4, arrowY - 8 * dir);\r\n                    ctx.lineTo(x + 4, arrowY - 8 * dir);\r\n                    ctx.closePath();\r\n                    ctx.fillStyle = 'rgba(255, 255, 255, 0.15)';\r\n                    ctx.fill();\r\n                }\r\n            }\r\n        }\r\n\r\n        function drawTrail() {\r\n            if (trail.length > 1) {\r\n                ctx.beginPath();\r\n                ctx.moveTo(trail[0].x, trail[0].y);\r\n                for (let i = 1; i < trail.length; i++) {\r\n                    ctx.lineTo(trail[i].x, trail[i].y);\r\n                }\r\n                ctx.strokeStyle = 'rgba(0, 255, 204, 0.4)';\r\n                ctx.lineWidth = 2;\r\n                ctx.stroke();\r\n            }\r\n        }\r\n\r\n        function drawParticle() {\r\n            const px = state.x * PIXELS_PER_METER;\r\n            const py = canvas.height - (state.y * PIXELS_PER_METER);\r\n\r\n            const gradient = ctx.createRadialGradient(px, py, 0, px, py, PARTICLE_RADIUS_PX * 2);\r\n            const color = config.q > 0 ? 'rgba(239, 68, 68, 0.6)' : 'rgba(59, 130, 246, 0.6)';\r\n            gradient.addColorStop(0, color);\r\n            gradient.addColorStop(1, 'transparent');\r\n            ctx.fillStyle = gradient;\r\n            ctx.beginPath();\r\n            ctx.arc(px, py, PARTICLE_RADIUS_PX * 2, 0, Math.PI * 2);\r\n            ctx.fill();\r\n\r\n            ctx.fillStyle = config.q > 0 ? '#ef4444' : '#3b82f6';\r\n            ctx.beginPath();\r\n            ctx.arc(px, py, PARTICLE_RADIUS_PX, 0, Math.PI * 2);\r\n            ctx.fill();\r\n\r\n            ctx.fillStyle = 'white';\r\n            ctx.font = 'bold 12px Space Grotesk';\r\n            ctx.textAlign = 'center';\r\n            ctx.textBaseline = 'middle';\r\n            ctx.fillText(config.q > 0 ? '+' : '-', px, py);\r\n        }\r\n\r\n        function drawVectors() {\r\n            const px = state.x * PIXELS_PER_METER;\r\n            const py = canvas.height - (state.y * PIXELS_PER_METER);\r\n            \r\n            const speed = Math.hypot(state.vx, state.vy);\r\n            const V_SCALE = 40;\r\n            \r\n            if (speed > 0.01) {\r\n                const vDrawX = state.vx * V_SCALE;\r\n                const vDrawY = -(state.vy * V_SCALE); \r\n                \r\n                ctx.strokeStyle = '#00ffcc';\r\n                ctx.fillStyle = '#00ffcc';\r\n                ctx.lineWidth = 2;\r\n                drawArrow(ctx, px, py, px + vDrawX, py + vDrawY, 8);\r\n            }\r\n\r\n            if (state.ay !== 0) {\r\n                const fy = config.q * config.ey;\r\n                const magnitude = Math.abs(fy);\r\n                const order = Math.log10(magnitude);\r\n                \r\n                const visualLength = 60 + (order + 5) * 20; \r\n                const fDrawY = Math.sign(fy) * visualLength;\r\n\r\n                ctx.strokeStyle = '#ff6b35';\r\n                ctx.fillStyle = '#ff6b35';\r\n                ctx.lineWidth = 2;\r\n                drawArrow(ctx, px, py, px, py - fDrawY, 8);\r\n            }\r\n        }\r\n\r\n        function drawArrow(ctx, fromX, fromY, toX, toY, headSize) {\r\n            const angle = Math.atan2(toY - fromY, toX - fromX);\r\n            ctx.beginPath();\r\n            ctx.moveTo(fromX, fromY);\r\n            ctx.lineTo(toX, toY);\r\n            ctx.stroke();\r\n            ctx.beginPath();\r\n            ctx.moveTo(toX, toY);\r\n            ctx.lineTo(toX - headSize * Math.cos(angle - Math.PI \/ 6), toY - headSize * Math.sin(angle - Math.PI \/ 6));\r\n            ctx.lineTo(toX - headSize * Math.cos(angle + Math.PI \/ 6), toY - headSize * Math.sin(angle + Math.PI \/ 6));\r\n            ctx.closePath();\r\n            ctx.fill();\r\n        }\r\n\r\n        function drawGraphs() {\r\n            const padding = { left: 40, right: 10, top: 10, bottom: 20 };\r\n\r\n            const contexts = [graphVxCtx, graphAccCtx, graphPosCtx, graphVelCtx];\r\n            contexts.forEach(c => {\r\n                c.fillStyle = '#0c1525';\r\n                c.fillRect(0, 0, c.canvas.width, c.canvas.height);\r\n            });\r\n\r\n            if (graphData.t.length < 1) return;\r\n\r\n            const plotGraph = (ctx, data, color, label, isZeroBased) => {\r\n                const w = ctx.canvas.width;\r\n                const h = ctx.canvas.height;\r\n                const graphW = w - padding.left - padding.right;\r\n                const graphH = h - padding.top - padding.bottom;\r\n\r\n                let minT = 0;\r\n                let maxT = graphData.t[graphData.t.length - 1];\r\n                \r\n                if (maxT === 0) maxT = 1; \r\n\r\n                let minV = Math.min(...data);\r\n                let maxV = Math.max(...data);\r\n\r\n                if(minV === maxV) {\r\n                    minV -= 1; maxV += 1;\r\n                } else {\r\n                    const range = maxV - minV;\r\n                    minV -= range * 0.1;\r\n                    maxV += range * 0.1;\r\n                }\r\n                \r\n                if (!isZeroBased) {\r\n                     if (minV < 0 && maxV > 0) {\r\n                         const maxAbs = Math.max(Math.abs(minV), Math.abs(maxV));\r\n                         minV = -maxAbs;\r\n                         maxV = maxAbs;\r\n                     } else if (minV >= 0) {\r\n                         minV = 0; \r\n                     } else {\r\n                         maxV = 0;\r\n                     }\r\n                }\r\n                \r\n                const rangeV = maxV - minV || 1; \r\n\r\n                ctx.strokeStyle = 'rgba(255,255,255,0.2)';\r\n                ctx.lineWidth = 1;\r\n                ctx.beginPath();\r\n                ctx.moveTo(padding.left, padding.top);\r\n                ctx.lineTo(padding.left, h - padding.bottom);\r\n                ctx.lineTo(w - padding.right, h - padding.bottom);\r\n                ctx.stroke();\r\n\r\n                ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';\r\n                ctx.font = '9px JetBrains Mono';\r\n                ctx.textAlign = 'right';\r\n                ctx.textBaseline = 'middle';\r\n                \r\n                for(let i=0; i<=4; i++) {\r\n                    const val = minV + (rangeV * i \/ 4);\r\n                    const y = h - padding.bottom - (graphH * i \/ 4);\r\n                    ctx.fillText(val.toFixed(1), padding.left - 5, y);\r\n                }\r\n\r\n                if (minV < 0 && maxV > 0) {\r\n                    const zeroY = h - padding.bottom - ((0 - minV) \/ rangeV) * graphH;\r\n                    ctx.strokeStyle = 'rgba(255, 255, 255, 0.15)';\r\n                    ctx.setLineDash([4, 4]);\r\n                    ctx.beginPath();\r\n                    ctx.moveTo(padding.left, zeroY);\r\n                    ctx.lineTo(w - padding.right, zeroY);\r\n                    ctx.stroke();\r\n                    ctx.setLineDash([]);\r\n                }\r\n\r\n                ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';\r\n                ctx.textAlign = 'center';\r\n                ctx.fillText(minT.toFixed(1) + \"s\", padding.left, h - padding.bottom + 12);\r\n                ctx.fillText(maxT.toFixed(1) + \"s\", w - padding.right, h - padding.bottom + 12);\r\n\r\n                ctx.strokeStyle = color;\r\n                ctx.lineWidth = 1.5;\r\n                ctx.beginPath();\r\n\r\n                const rangeT = maxT - minT || 1;\r\n\r\n                data.forEach((val, i) => {\r\n                    const t = graphData.t[i];\r\n                    const x = padding.left + ((t - minT) \/ rangeT) * graphW;\r\n                    const y = h - padding.bottom - ((val - minV) \/ rangeV) * graphH;\r\n                    if (i === 0) ctx.moveTo(x, y);\r\n                    else ctx.lineTo(x, y);\r\n                });\r\n                ctx.stroke();\r\n            };\r\n\r\n            plotGraph(graphVxCtx, graphData.vx, '#00ffcc', \"Vx\", false);\r\n            plotGraph(graphAccCtx, graphData.ay, '#ff6b35', \"Ay\", false); \r\n            plotGraph(graphPosCtx, graphData.y, '#22c55e', \"Y\", true);\r\n            plotGraph(graphVelCtx, graphData.vy, '#eab308', \"Vy\", false);\r\n        }\r\n\r\n        function updateDataUI() {\r\n            document.getElementById('time-display').innerText = state.t.toFixed(2) + ' s';\r\n            document.getElementById('out-x').innerText = state.x.toFixed(2);\r\n            document.getElementById('out-y').innerText = state.y.toFixed(2);\r\n            document.getElementById('out-vx').innerText = state.vx.toFixed(2);\r\n            document.getElementById('out-vy').innerText = state.vy.toFixed(2);\r\n            \r\n            const speed = Math.hypot(state.vx, state.vy);\r\n            document.getElementById('out-v').innerText = speed.toFixed(2);\r\n            \r\n            document.getElementById('graph-vx-val').innerText = state.vx.toFixed(2) + \" m\/s\";\r\n            document.getElementById('graph-ay-val').innerText = state.ay.toExponential(2) + \" m\/s\u00b2\";\r\n            document.getElementById('graph-y-val').innerText = state.y.toFixed(2) + \" m\";\r\n            document.getElementById('graph-vy-val').innerText = state.vy.toFixed(2) + \" m\/s\";\r\n            \r\n            if (isRunning) {\r\n                statusText.innerText = 'Ejecutando';\r\n                statusDot.className = 'w-2 h-2 rounded-full bg-[var(--accent-green)]';\r\n            } else if (!hasCollided) {\r\n                statusText.innerText = 'Pausado';\r\n                statusDot.className = 'w-2 h-2 rounded-full bg-[var(--accent-yellow)]';\r\n            }\r\n        }\r\n\r\n        \/\/ ==========================================\r\n        \/\/ INTERACTIVIDAD (TOOLTIP)\r\n        \/\/ ==========================================\r\n\r\n        canvas.addEventListener('mousemove', (e) => {\r\n            const rect = canvas.getBoundingClientRect();\r\n            const mouseX = e.clientX - rect.left;\r\n            const mouseY = e.clientY - rect.top;\r\n\r\n            const px = state.x * PIXELS_PER_METER;\r\n            const py = canvas.height - (state.y * PIXELS_PER_METER);\r\n\r\n            const dist = Math.hypot(mouseX - px, mouseY - py);\r\n\r\n            if (dist < PARTICLE_RADIUS_PX * 2) {\r\n                tooltip.style.opacity = '1';\r\n                tooltip.style.left = (px + 20) + 'px';\r\n                tooltip.style.top = (py - 10) + 'px';\r\n                tooltip.innerHTML = `X: ${state.x.toFixed(2)} m<br>Y: ${state.y.toFixed(2)} m`;\r\n            } else {\r\n                tooltip.style.opacity = '0';\r\n            }\r\n        });\r\n\r\n        canvas.addEventListener('mouseleave', () => {\r\n            tooltip.style.opacity = '0';\r\n        });\r\n\r\n        \/\/ ==========================================\r\n        \/\/ LOOP PRINCIPAL\r\n        \/\/ ==========================================\r\n\r\n        function loop(timestamp) {\r\n            if (timestamp - fpsTime >= 1000) {\r\n                document.getElementById('fps-counter').innerText = fpsCount;\r\n                fpsCount = 0;\r\n                fpsTime = timestamp;\r\n            }\r\n            fpsCount++;\r\n\r\n            if (isRunning) {\r\n                const dt = 0.016 * simSpeed; \r\n                updatePhysics(dt);\r\n            }\r\n            \r\n            updatePauseButton();\r\n            draw();\r\n            requestAnimationFrame(loop);\r\n        }\r\n\r\n        \/\/ ==========================================\r\n        \/\/ EVENT LISTENERS\r\n        \/\/ ==========================================\r\n\r\n        window.addEventListener('resize', resizeCanvases);\r\n        document.getElementById('btn-start').addEventListener('click', () => {\r\n            if (!hasCollided) {\r\n                isRunning = true;\r\n                updatePauseButton();\r\n            }\r\n        });\r\n\r\n        btnPause.addEventListener('click', () => {\r\n            if (hasCollided) return;\r\n            isRunning = !isRunning;\r\n            updatePauseButton();\r\n        });\r\n\r\n        document.getElementById('btn-reset').addEventListener('click', resetSimulation);\r\n        document.getElementById('btn-apply').addEventListener('click', resetSimulation);\r\n\r\n        document.getElementById('input-speed').addEventListener('input', (e) => {\r\n            simSpeed = parseFloat(e.target.value);\r\n            document.getElementById('val-speed').innerText = simSpeed.toFixed(1) + 'x';\r\n        });\r\n\r\n        document.getElementById('input-ey').addEventListener('input', (e) => {\r\n            config.ey = parseFloat(e.target.value) || 0;\r\n            draw(); \r\n        });\r\n\r\n        \/\/ ==========================================\r\n        \/\/ INICIO\r\n        \/\/ ==========================================\r\n        \r\n        resizeCanvases();\r\n        resetSimulation();\r\n        requestAnimationFrame(loop);\r\n\r\n    <\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Simulador Condensador de Placas C Movimiento de una carga en un campo el\u00e9ctrico t = 0.00 s Listo FPS 60 Velocidad Fuerza Velocidad Vx 0.00&hellip;<\/p>\n","protected":false},"author":7,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"class_list":["post-6296","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>movimiento_cargas_campo_electrico - F\u00edsica 2<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"movimiento_cargas_campo_electrico - F\u00edsica 2\" \/>\n<meta property=\"og:description\" content=\"Simulador Condensador de Placas C Movimiento de una carga en un campo el\u00e9ctrico t = 0.00 s Listo FPS 60 Velocidad Fuerza Velocidad Vx 0.00&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/\" \/>\n<meta property=\"og:site_name\" content=\"F\u00edsica 2\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-18T23:17:17+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minuto\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/\",\"url\":\"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/\",\"name\":\"movimiento_cargas_campo_electrico - F\u00edsica 2\",\"isPartOf\":{\"@id\":\"https:\/\/fisica2.fica.unsl.edu.ar\/#website\"},\"datePublished\":\"2026-03-18T00:44:10+00:00\",\"dateModified\":\"2026-03-18T23:17:17+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/#breadcrumb\"},\"inLanguage\":\"es-AR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Inicio\",\"item\":\"https:\/\/fisica2.fica.unsl.edu.ar\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"movimiento_cargas_campo_electrico\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fisica2.fica.unsl.edu.ar\/#website\",\"url\":\"https:\/\/fisica2.fica.unsl.edu.ar\/\",\"name\":\"F\u00edsica 2\",\"description\":\"FICA - UNSL\",\"publisher\":{\"@id\":\"https:\/\/fisica2.fica.unsl.edu.ar\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fisica2.fica.unsl.edu.ar\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es-AR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/fisica2.fica.unsl.edu.ar\/#organization\",\"name\":\"SAC- Secretar\u00eda General FICA\",\"url\":\"https:\/\/fisica2.fica.unsl.edu.ar\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es-AR\",\"@id\":\"https:\/\/fisica2.fica.unsl.edu.ar\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/fisica2.fica.unsl.edu.ar\/wp-content\/uploads\/2021\/11\/SG-Logo.png\",\"contentUrl\":\"https:\/\/fisica2.fica.unsl.edu.ar\/wp-content\/uploads\/2021\/11\/SG-Logo.png\",\"width\":4483,\"height\":1231,\"caption\":\"SAC- Secretar\u00eda General FICA\"},\"image\":{\"@id\":\"https:\/\/fisica2.fica.unsl.edu.ar\/#\/schema\/logo\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"movimiento_cargas_campo_electrico - F\u00edsica 2","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/","og_locale":"es_ES","og_type":"article","og_title":"movimiento_cargas_campo_electrico - F\u00edsica 2","og_description":"Simulador Condensador de Placas C Movimiento de una carga en un campo el\u00e9ctrico t = 0.00 s Listo FPS 60 Velocidad Fuerza Velocidad Vx 0.00&hellip;","og_url":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/","og_site_name":"F\u00edsica 2","article_modified_time":"2026-03-18T23:17:17+00:00","twitter_card":"summary_large_image","twitter_misc":{"Tiempo de lectura":"1 minuto"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/","url":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/","name":"movimiento_cargas_campo_electrico - F\u00edsica 2","isPartOf":{"@id":"https:\/\/fisica2.fica.unsl.edu.ar\/#website"},"datePublished":"2026-03-18T00:44:10+00:00","dateModified":"2026-03-18T23:17:17+00:00","breadcrumb":{"@id":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/#breadcrumb"},"inLanguage":"es-AR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/movimiento_cargas_campo_electrico\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Inicio","item":"https:\/\/fisica2.fica.unsl.edu.ar\/"},{"@type":"ListItem","position":2,"name":"movimiento_cargas_campo_electrico"}]},{"@type":"WebSite","@id":"https:\/\/fisica2.fica.unsl.edu.ar\/#website","url":"https:\/\/fisica2.fica.unsl.edu.ar\/","name":"F\u00edsica 2","description":"FICA - UNSL","publisher":{"@id":"https:\/\/fisica2.fica.unsl.edu.ar\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fisica2.fica.unsl.edu.ar\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es-AR"},{"@type":"Organization","@id":"https:\/\/fisica2.fica.unsl.edu.ar\/#organization","name":"SAC- Secretar\u00eda General FICA","url":"https:\/\/fisica2.fica.unsl.edu.ar\/","logo":{"@type":"ImageObject","inLanguage":"es-AR","@id":"https:\/\/fisica2.fica.unsl.edu.ar\/#\/schema\/logo\/image\/","url":"https:\/\/fisica2.fica.unsl.edu.ar\/wp-content\/uploads\/2021\/11\/SG-Logo.png","contentUrl":"https:\/\/fisica2.fica.unsl.edu.ar\/wp-content\/uploads\/2021\/11\/SG-Logo.png","width":4483,"height":1231,"caption":"SAC- Secretar\u00eda General FICA"},"image":{"@id":"https:\/\/fisica2.fica.unsl.edu.ar\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/wp-json\/wp\/v2\/pages\/6296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/wp-json\/wp\/v2\/comments?post=6296"}],"version-history":[{"count":46,"href":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/wp-json\/wp\/v2\/pages\/6296\/revisions"}],"predecessor-version":[{"id":6355,"href":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/wp-json\/wp\/v2\/pages\/6296\/revisions\/6355"}],"wp:attachment":[{"href":"https:\/\/fisica2.fica.unsl.edu.ar\/index.php\/wp-json\/wp\/v2\/media?parent=6296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}