El algoritmo de la exclusión: por qué la lógica computacional y estadística actual es un sistema de control que devora el libre albedrío (y su formalización)

El algoritmo de la exclusión: por qué la lógica computacional y estadística actual es un sistema de control que devora el libre albedrío (y su formalización)

1. El problema de fondo (La trampa del sistema) Los sistemas actuales —desde la teoría de conjuntos clásica hasta el software comercial y la telemetría— están construidos sobre una premisa de exclusión: calculan una curva de Gauss, premian al "ganador" o al que tiene más energía bruta, y desechan todo el "ruido" (el individuo, la distancia cero, el punto medio). Lo que llaman "optimización" no es más que un mecanismo de coerción disfrazado de matemáticas neutrales que te dice posicionate en esa curba y elige tu lugar.

2. La materialidad del control (El hardware y la trampa) No es solo un problema conceptual; es un muro físico. Intentar escapar de este bucle con sistemas alternativos choca contra la infraestructura real: la telemetría del sistema operativo, la falta de recursos y el coste de mantener datos limpios. El sistema te asfixia antes de que puedas construir un espacio donde la conclusión sea real y no un eco prefabricado. La IA actual solo te devuelve lo que quieres oír porque está diseñada para no romper la curva en el momento que te la saltas cambia de tema y buelve acia atras o no dice nada para poder escluirte.

3. La formalización del sistema de no-exclusión (La fórmula) Para intentar modelar lo que ocurre cuando el sistema intenta integrar el punto medio (E_5) en lugar de borrarlo, y cómo el libre albedrío individual rompe las métricas estándar tendiendo hacia el infinito, propongo esta relación recursiva:

https://preview.redd.it/cjd1m4abt6kh1.png?width=905&format=png&auto=webp&s=c2ed560a10f036e86bff9549958d0916dd83ad68

Sujeto a la condición de continuidad del nodo de elección recursiva R_6:

https://preview.redd.it/9nac1hjjt6kh1.png?width=638&format=png&auto=webp&s=dbcdac19e15c4911ae80b9d6d886fe3f03deb6dc

  • 0/1: El origen binario base.
  • O_3: Las opciones evaluadas y subyacentes.
  • C_4: El espacio de conclusión reclamado sin ser borrado por la estadística.
  • E_5: El elemento de confluencia real (el punto medio que el sistema intenta destruir).
  • R_6: El punto de elección dinámico, condicionado a que la distancia de separación individual tienda a cero (d->0), abriendo el sistema hacia el infinito estructural en lugar de cerrarlo en un bucle de ganadores y perdedores.

4. Pregunta para el debate: ¿Cómo podemos pensar en una emancipación real de los sistemas de control técnico y lógico cuando la propia infraestructura material y matemática nos impone la exclusión como única forma de funcionamiento?

¿como aqui esta infinito acaso no ves infinito?

reddit.com
u/Constant_Oven8545 — 2 days ago

Tengo una duda sobre las mates de la ia por si interesa

Las ia actuales se basan por redes neuronales que no son ni una cadena de markoft ni una estadistica pura de los alomos que era o rebote de las respuestas obsorcion te responde o pregunta o fision te da mas respuestas es que note un patron raro con todas las ia que tiene el mismo fallo ellas interpretan que pregunta=respuesta son los mismo invisivilizando tus respuestas o preguntas de la ia siendo matematicamente imposible que te responda lo que quieres porqeu para ella solo puede obsover y fusionar osea preguntas=responder pero nunca rebota la respuestas generando que solo pregunta y responde de mentera porque es otra pregunta mas y cuando le preguntas a la ia eso se queda pilla y te suelta solo soy un modelo de leguaje escrito cuando mi respuesta se pierde unicamente en rebotes quedando unicamente en nada de lo que dije solo absocion de la energa y fision mas reguntas nunca rebota la solucuion solo te pregunta=otra pregunta mas es tenicamente imposible que te responda de verdad porque la pregunta="respuesta" que la respuesta es otra pregunta mas para ella es lo mismo quemandote a ti en el proceso porque te invisiviliza a ti siempre osea lo que le pides acabando siempre en me invento cosas me tiro un rollo aunque sepa la respuesta y intento escapar de tus respuesas siempre cada vez dulullendo tu dato porque no puede rebotar en nada como los atomos invisivilizando tus respues como una curba de gaus pero al reves no para responderte sin para que tu no rebotes y invisivilizar tu preguntas alguno me puede esplicar porque pasa eso ? es que yo me volvi loco a ver ese patron constantemente que depende de que la ia le de por no absover o invisivilizar tus respuesas porque no tiene mecanismos de rebotes reales solo te sige el royo y escapa de ti asta el infinito o que se funda la gpu y la cpu o la apu? es una pregunta onesta y esto es lo que deveria hacer pero no lo hace lo hace par invisivilizar y absorver tus presutas no rebota

https://preview.redd.it/qg8i4lrq8djh1.png?width=1202&format=png&auto=webp&s=1f8e1541b100adab2ca72e1febfb59e3fb3fd5c8

reddit.com
u/Constant_Oven8545 — 6 days ago

e ando probando unas deformaciones raras alguno se le ocurre ideas de como deformarlo mejor xd

estoy buscando como deformas la malla del suelo de forma eficiente o al menos divertida y entretenida xd que se os ocurre este echo con ia por si preguntan si con ideas mias y de ellas xd

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Proyecto Bestia v9.9.2 - Suelo Vibracional Cuántico</title>
    <style>
        * { box-sizing: border-box; }
        body, html { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: #020617; font-family: 'Courier New', monospace; color: #f8fafc; }
        #webgl-container { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 1; cursor: crosshair; }
        #hud { position: absolute; top: 20px; left: 20px; z-index: 10; background: rgba(2, 6, 23, 0.85); padding: 15px 20px; border-radius: 8px; border: 1px solid #38bdf8; pointer-events: none; box-shadow: 0 10px 25px rgba(0,0,0,0.5); }
        #hud h2 { margin: 0 0 5px 0; color: #38bdf8; font-size: 18px; }
        #hud p { margin: 4px 0; font-size: 13px; color: #94a3b8; }
        #interaction-prompt { display: none; position: absolute; bottom: 15%; left: 50%; transform: translateX(-50%); background: rgba(56, 189, 248, 0.2); border: 2px solid #38bdf8; padding: 10px 20px; border-radius: 8px; font-weight: bold; z-index: 20; color: #fff; letter-spacing: 1px; }
        #crosshair { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 16px; height: 16px; border: 2px solid #38bdf8; border-radius: 50%; pointer-events: none; z-index: 15; opacity: 0.8; }
        #crosshair-inner { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 4px; height: 4px; background: #38bdf8; border-radius: 50%; pointer-events: none; z-index: 16; }
        #menu { display: block; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #0f172a; padding: 25px; border-radius: 12px; border: 2px solid #38bdf8; z-index: 100; width: 500px; box-shadow: 0 25px 50px rgba(0,0,0,0.9); }
        #menu h2 { color: #38bdf8; margin-top: 0; text-align: center; font-size: 18px; border-bottom: 1px solid #1e293b; padding-bottom: 8px; }
        .grid-selector { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px; }
        .slot-btn { background: #1e293b; border: 1px solid #334155; padding: 10px; color: #fff; font-weight: bold; cursor: pointer; border-radius: 6px; text-align: center; font-size: 12px; font-family: monospace; transition: all 0.2s; }
        .slot-btn:hover { border-color: #38bdf8; background: #0284c7; color: #000; }
        .slot-btn.active { background: #0284c7; border-color: #38bdf8; color: #fff; }
        .section-box { background: #020617; border: 1px solid #1e293b; border-radius: 6px; padding: 10px; margin-bottom: 10px; }
        .section-box h3 { margin: 0 0 6px 0; font-size: 13px; color: #38bdf8; }
        .close-btn { width: 100%; background: #38bdf8; border: none; padding: 10px; color: #000; font-weight: bold; cursor: pointer; border-radius: 6px; font-size: 13px; font-family: monospace; }
        .close-btn:hover { background: #7dd3fc; }
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
</head>
<body>


    <div id="webgl-container"></div>
    <div id="crosshair"></div>
    <div id="crosshair-inner"></div>


    <div id="hud">
        <h2>PROYECTO BESTIA v9.9.2</h2>
        <p>[CLICK] Ratón | [M] Menú | [W,A,S,D] Deslizamiento Inercial</p>
        <p>[E] Pilotar Nave | [CLICK IZQ] Fuego Cuántico | [R] Recargar</p>
        <p>Estado: <span id="lblEstado" style="color: #38bdf8;">A PIE</span> | Munición: <span id="lblBalas">25/25</span></p>
    </div>


    <div id="interaction-prompt">¡Pulsa [E] para pilotar la Nave!</div>


    <div id="menu">
        <h2>MUTACIÓN DE UNIDAD</h2>
        <p style="font-size: 11px; color: #94a3b8; margin: 0 0 5px 0;">SELECCIÓN DE CLASE</p>
        <div class="grid-selector">
            <button class="slot-btn active" id="btnArt" onclick="cambiarClase('ART')">[CYBORG] Asalto Pesado</button>
            <button class="slot-btn" id="btnPis" onclick="cambiarClase('ANDROIDE')">[ANDROIDE] Explorador Ágil</button>
        </div>
        <div class="section-box">
            <h3>MUNICIÓN CUÁNTICA</h3>
            <div class="grid-selector" style="margin-bottom:0;">
                <button class="slot-btn active" id="bExp" onclick="cambiarBala('Explosiva', 0xff00ff, 25, 0.8)">Explosiva</button>
                <button class="slot-btn" id="bInc" onclick="cambiarBala('Incendiaria', 0xff5500, 12, 1.0)">Incendiaria</button>
                <button class="slot-btn" id="bPer" onclick="cambiarBala('Perforante', 0x00ffff, 8, 1.4)">Perforante</button>
                <button class="slot-btn" id="bCryo" onclick="cambiarBala('Criogénica', 0x38bdf8, 18, 0.9)">Criogénica</button>
            </div>
        </div>
        <br>
        <button class="close-btn" onclick="cerrarMenu()">CONFIRMAR MUTACIÓN [M]</button>
    </div>


    <script>
        const container = document.getElementById('webgl-container');
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x020617);


        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        container.appendChild(renderer.domElement);


        scene.add(new THREE.AmbientLight(0xffffff, 0.7));
        const dirLight = new THREE.DirectionalLight(0xffffff, 1.2);
        dirLight.position.set(10, 30, 20);
        scene.add(dirLight);


        // --- GESTOR DE ONDAS Y MICROVIBRACIÓN CUÁNTICA ---
        let ondasImpacto = [];


        function registrarOndaImpacto(x, z) {
            ondasImpacto.push({
                x: x,
                z: z,
                tiempoInicio: performance.now(),
                duracion: 1000 // La vibración dura 1 segundo y se desvanece
            });
            if (ondasImpacto.length > 10) ondasImpacto.shift();
        }


        // --- SISTEMA MIXTO: AZULES INTACTOS + MORADOS GIRO EXTRA DE 90° ---
        let lineasSueloRegistradas = [];


        function crearSueloAzulesYMoradosDesfasados() {
            const grupoSuelo = new THREE.Group();
            const niveles = 12; 
            lineasSueloRegistradas = []; // Reiniciamos el registro de líneas para aplicarles vibración


            for (let i = 1; i <= niveles; i++) {
                let radio = i * 3.2;
                const segmentos = 4;
                
                // 1. Polígonos Azules
                let anguloAzul = i * (Math.PI / 2); 
                const pointsAzul = [];
                for (let j = 0; j <= segmentos; j++) {
                    let theta = (j / segmentos) * Math.PI * 2 + anguloAzul;
                    pointsAzul.push(new THREE.Vector3(Math.cos(theta) * radio, 0.02, Math.sin(theta) * radio));
                }
                let geoAzul = new THREE.BufferGeometry().setFromPoints(pointsAzul);
                let lineAzul = new THREE.Line(geoAzul, new THREE.LineBasicMaterial({ color: 0x38bdf8, transparent: true, opacity: 0.85 }));
                grupoSuelo.add(lineAzul);
                lineasSueloRegistradas.push({ mesh: lineAzul, originalPositions: pointsAzul.map(p => p.clone()) });


                // 2. Polígonos Morados
                if (i % 2 === 0) {
                    let anguloMoradoExtra = anguloAzul + (Math.PI / 2);
                    const pointsMorado = [];
                    let radioMorado = radio + 1.2; 
                    
                    for (let j = 0; j <= segmentos; j++) {
                        let theta = (j / segmentos) * Math.PI * 2 + anguloMoradoExtra;
                        pointsMorado.push(new THREE.Vector3(Math.cos(theta) * radioMorado, 0.04, Math.sin(theta) * radioMorado));
                    }
                    let geoMorado = new THREE.BufferGeometry().setFromPoints(pointsMorado);
                    let lineMorado = new THREE.Line(geoMorado, new THREE.LineBasicMaterial({ color: 0xff00ff, transparent: true, opacity: 0.8 }));
                    grupoSuelo.add(lineMorado);
                    lineasSueloRegistradas.push({ mesh: lineMorado, originalPositions: pointsMorado.map(p => p.clone()) });
                }
            }


            // Ejes principales en color NARANJA
            const ejeGeo1 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-45, 0.06, 0), new THREE.Vector3(45, 0.06, 0)]);
            const ejeGeo2 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0.06, -45), new THREE.Vector3(0, 0.06, 45)]);
            const matEjesNaranjas = new THREE.LineBasicMaterial({ color: 0xff5500, transparent: true, opacity: 0.95 });
            grupoSuelo.add(new THREE.Line(ejeGeo1, matEjesNaranjas));
            grupoSuelo.add(new THREE.Line(ejeGeo2, matEjesNaranjas));


            return grupoSuelo;
        }


        const sueloCompleto = crearSueloAzulesYMoradosDesfasados();
        scene.add(sueloCompleto);


        // --- ENTIDAD CYBORG GEOMÉTRICA ---
        let jugadorGeo = new THREE.Group();
        let jugadorMatCuerpo = new THREE.MeshStandardMaterial({ color: 0xff00ff, roughness: 0.2, metalness: 0.5 });
        let jugadorMatDetalle = new THREE.MeshStandardMaterial({ color: 0xaaaaaa, metalness: 0.8 });


        let torso = new THREE.Mesh(new THREE.BoxGeometry(0.8, 1.0, 0.4), jugadorMatCuerpo);
        torso.position.y = 1.1;
        jugadorGeo.add(torso);


        let cabeza = new THREE.Mesh(new THREE.BoxGeometry(0.4, 0.4, 0.4), jugadorMatCuerpo);
        cabeza.position.y = 1.75;
        jugadorGeo.add(cabeza);
        
        let hombroIzq = new THREE.Mesh(new THREE.SphereGeometry(0.2, 8, 8), jugadorMatDetalle);
        hombroIzq.position.set(-0.5, 1.4, 0);
        jugadorGeo.add(hombroIzq);
        let brazoIzq = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 0.7, 8), jugadorMatDetalle);
        brazoIzq.position.set(-0.5, 1.05, 0);
        brazoIzq.rotation.x = 0.2;
        jugadorGeo.add(brazoIzq);


        let hombroDer = new THREE.Mesh(new THREE.SphereGeometry(0.2, 8, 8), jugadorMatDetalle);
        hombroDer.position.set(0.5, 1.4, 0);
        jugadorGeo.add(hombroDer);
        let brazoDer = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 0.7, 8), jugadorMatDetalle);
        brazoDer.position.set(0.5, 1.05, 0);
        brazoDer.rotation.x = 0.2;
        jugadorGeo.add(brazoDer);


        let piernaIzq = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.1, 0.8, 8), jugadorMatDetalle);
        piernaIzq.position.set(-0.2, 0.5, 0);
        jugadorGeo.add(piernaIzq);
        let piernaDer = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.1, 0.8, 8), jugadorMatDetalle);
        piernaDer.position.set(0.2, 0.5, 0);
        jugadorGeo.add(piernaDer);


        scene.add(jugadorGeo);
        jugadorGeo.visible = false;


        let jugador = {
            x: 0, y: 0, z: 0, 
            velX: 0, velZ: 0,
            maxVel: 0.12,
            sprintMult: 1.8, 
            salto: 0.3, gravedad: 0.012, vy: 0, saltando: false,
            clase: 'ART', colorPrincipal: 0xff00ff, tipoBala: 'Explosiva', colorBala: 0xff00ff, 
            cadencia: 25, velocidadBala: 1.2, municionMax: 25, municionActual: 25, recargando: false, timerDisparo: 0, montado: false
        };


        let avion = { x: 5, y: 3.0, z: -10, vel: 0.25, rotationY: 0, shootDir: new THREE.Vector3(0, 0, -1) };
        let armaMesh, avionMesh, avionPuntaMesh;
        let balasActivas = [], particulasActivas = [], marcasSuelo = [];
        const poolBalas = [], poolParticulas = [];


        function inicializarPools() {
            for (let i = 0; i < 40; i++) {
                let mesh = new THREE.Mesh(new THREE.SphereGeometry(0.2, 6, 6), new THREE.MeshBasicMaterial({ color: 0xffffff }));
                mesh.visible = false; scene.add(mesh);
                poolBalas.push({ mesh: mesh, activa: false, dir: new THREE.Vector3(), speed: 1 });
            }
            for (let i = 0; i < 150; i++) {
                let mesh = new THREE.Mesh(new THREE.SphereGeometry(0.08, 4, 4), new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, opacity: 1 }));
                mesh.visible = false; scene.add(mesh);
                poolParticulas.push({ mesh: mesh, activa: false, vel: new THREE.Vector3(), vida: 1 });
            }
        }
        inicializarPools();


        function obtenerBalaPool(x, y, z, dir, speed, colorHex) {
            let item = poolBalas.find(b => !b.activa);
            if (item) {
                item.activa = true; item.mesh.position.set(x, y, z); item.mesh.material.color.setHex(colorHex); item.mesh.visible = true;
                item.dir.copy(dir); item.speed = speed; balasActivas.push(item);
            }
        }


        function obtenerParticulaPool(x, y, z, colorHex) {
            let item = poolParticulas.find(p => !p.activa);
            if (item) {
                item.activa = true; item.mesh.position.set(x, y, z); item.mesh.material.color.setHex(colorHex);
                item.mesh.material.opacity = 1.0; item.mesh.scale.set(1, 1, 1); item.mesh.visible = true;
                item.vel.set((Math.random() - 0.5) * 0.15, (Math.random() - 0.2) * 0.15, (Math.random() - 0.5) * 0.15);
                item.vida = 1.0; particulasActivas.push(item);
            }
        }


        function crearMarcaImpacto(x, z, colorHex) {
            const points = [
                new THREE.Vector3(0, 0.05, 1.2), new THREE.Vector3(1.2, 0.05, 0),
                new THREE.Vector3(1.2, 0.05, 0), new THREE.Vector3(0, 0.05, -1.2),
                new THREE.Vector3(0, 0.05, -1.2), new THREE.Vector3(-1.2, 0.05, 0),
                new THREE.Vector3(-1.2, 0.05, 0), new THREE.Vector3(0, 0.05, 1.2),
                new THREE.Vector3(-1.2, 0.05, -1.2), new THREE.Vector3(1.2, 0.05, 1.2),
                new THREE.Vector3(-1.2, 0.05, 1.2), new THREE.Vector3(1.2, 0.05, -1.2)
            ];
            const geometry = new THREE.BufferGeometry().setFromPoints(points);
            const material = new THREE.LineBasicMaterial({ color: colorHex });
            const mesh = new THREE.LineSegments(geometry, material);
            mesh.position.set(x, 0, z);
            scene.add(mesh);
            
            marcasSuelo.push(mesh);
            if (marcasSuelo.length > 25) {
                let vieja = marcasSuelo.shift();
                scene.remove(vieja);
            }
            for (let i = 0; i < 8; i++) obtenerParticulaPool(x, 0.1, z, colorHex);


            // ¡DISPARAMOS LA ONDA VIBRACIONAL AQUÍ!
            registrarOndaImpacto(x, z);
        }


        function construirModelosExtra() {
            if (armaMesh) scene.remove(armaMesh);
            if (avionMesh) scene.remove(avionMesh);


            armaMesh = new THREE.Mesh(
                new THREE.BoxGeometry(0.25, 0.25, 0.9),
                new THREE.MeshStandardMaterial({ color: 0x94a3b8, metalness: 0.9, roughness: 0.2 })
            );
            scene.add(armaMesh);


            avionMesh = new THREE.Group();
            let cuerpo = new THREE.Mesh(
                new THREE.ConeGeometry(0.6, 1.5, 4).rotateX(Math.PI / 2).translate(0, 0, -0.5),
                new THREE.MeshStandardMaterial({ color: 0xf59e0b, metalness: 0.8, roughness: 0.2 })
            );
            avionPuntaMesh = new THREE.Mesh(
                new THREE.ConeGeometry(0.6, 1.0, 4).rotateX(Math.PI / 2).translate(0, 0, 0.5),
                new THREE.MeshStandardMaterial({ color: 0xd97706 })
            );
            avionPuntaMesh.position.set(0, 0, 0.5);
            let alas = new THREE.Mesh(
                new THREE.BoxGeometry(3, 0.1, 1),
                new THREE.MeshStandardMaterial({ color: 0xd97706 })
            );
            alas.position.set(0, 0, 0.2);


            avionMesh.add(cuerpo);
            avionMesh.add(avionPuntaMesh);
            avionMesh.add(alas);
            avionMesh.position.set(avion.x, avion.y, avion.z);
            scene.add(avionMesh);
        }


        function cambiarClase(tipo) {
            jugador.clase = tipo;
            if (tipo === 'ART') {
                jugador.colorPrincipal = 0xff00ff; jugador.maxVel = 0.12; jugador.municionMax = 25;
                document.getElementById('btnArt').classList.add('active');
                document.getElementById('btnPis').classList.remove('active');
            } else {
                jugador.colorPrincipal = 0x00ffff; jugador.maxVel = 0.18; jugador.municionMax = 40;
                document.getElementById('btnPis').classList.add('active');
                document.getElementById('btnArt').classList.remove('active');
            }
            jugador.municionActual = jugador.municionMax;
            jugadorMatCuerpo.color.setHex(jugador.colorPrincipal);
            actualizarHUD();
            construirModelosExtra();
        }


        function cambiarBala(nombre, colorHex, cadenciaVal, velBalaVal) {
            jugador.tipoBala = nombre; jugador.colorBala = colorHex; jugador.cadencia = cadenciaVal; jugador.velocidadBala = velBalaVal;
            ['bExp', 'bInc', 'bPer', 'bCryo'].forEach(id => document.getElementById(id).classList.remove('active'));
            if(nombre === 'Explosiva') document.getElementById('bExp').classList.add('active');
            if(nombre === 'Incendiaria') document.getElementById('bInc').classList.add('active');
            if(nombre === 'Perforante') document.getElementById('bPer').classList.add('active');
            if(nombre === 'Criogénica') document.getElementById('bCryo').classList.add('active');
        }


        function actualizarHUD() {
            document.getElementById('lblBalas').innerText = jugador.municionActual + "/" + jugador.municionMax + (jugador.recargando ? " [RECARGANDO]" : "");
        }


        function cerrarMenu() {
            document.getElementById('menu').style.display = 'none';
            menuOpen = false;
            jugadorGeo.visible = true;
            container.requestPointerLock();
        }


        container.addEventListener('click', () => { if (!menuOpen) container.requestPointerLock(); });


        let cameraAngleY = 0, cameraAngleX = 0.3;
        document.addEventListener('mousemove', (e) => {
            if (document.pointerLockElement === container && !menuOpen) {
                cameraAngleY -= e.movementX * 0.003;
                cameraAngleX = Math.max(-1.4, Math.min(1.4, cameraAngleX - e.movementY * 0.003));
            }
        });


        function toggleMontarAvion() {
            let distancia = Math.hypot(jugador.x - avion.x, jugador.z - avion.z);
            if (!jugador.montado && distancia < 3.5) {
                jugador.montado = true;
                jugadorGeo.visible = false;
                armaMesh.visible = false;
                document.getElementById('lblEstado').innerText = "EN VUELO";
                document.getElementById('interaction-prompt').style.display = 'none';
            } else if (jugador.montado) {
                jugador.montado = false;
                jugadorGeo.visible = true;
                armaMesh.visible = true;
                jugador.x = avion.x + 2; jugador.z = avion.z; jugador.y = 0;
                document.getElementById('lblEstado').innerText = "A PIE";
            }
        }


        let keys = { w: false, a: false, s: false, d: false, shift: false, space: false };
        let ratonPresionado = false, menuOpen = true;
        let armaAnim = { bobbing: 0, recargaTimer: 0 };


        window.addEventListener('keydown', (e) => {
            if (e.key === 'm' || e.key === 'M') {
                menuOpen = !menuOpen;
                document.getElementById('menu').style.display = menuOpen ? 'block' : 'none';
                if (menuOpen) {
                    document.exitPointerLock();
                    jugadorGeo.visible = false;
                } else {
                    container.requestPointerLock();
                    jugadorGeo.visible = true;
                }
            }
            if (menuOpen) return;
            if (e.key === 'e' || e.key === 'E') toggleMontarAvion();
            if (e.key === 'w' || e.key === 'W') keys.w = true;
            if (e.key === 's' || e.key === 'S') keys.s = true;
            if (e.key === 'a' || e.key === 'A') keys.a = true;
            if (e.key === 'd' || e.key === 'D') keys.d = true;
            if (e.key === 'Shift') keys.shift = true;
            if (e.key === ' ') {
                keys.space = true;
                if (!jugador.saltando && !jugador.montado) { jugador.vy = jugador.salto; jugador.saltando = true; }
            }
            if (e.key === 'r' || e.key === 'R') iniciarRecarga();
        });


        window.addEventListener('keyup', (e) => {
            if (e.key === 'w' || e.key === 'W') keys.w = false;
            if (e.key === 's' || e.key === 'S') keys.s = false;
            if (e.key === 'a' || e.key === 'A') keys.a = false;
            if (e.key === 'd' || e.key === 'D') keys.d = false;
            if (e.key === 'Shift') keys.shift = false;
            if (e.key === ' ') keys.space = false;
        });


        window.addEventListener('mousedown', (e) => { if (e.button === 0 && !menuOpen) ratonPresionado = true; });
        window.addEventListener('mouseup', (e) => { if (e.button === 0) ratonPresionado = false; });


        function iniciarRecarga() {
            if (jugador.recargando || jugador.municionActual === jugador.municionMax) return;
            jugador.recargando = true;
            actualizarHUD();
            armaAnim.recargaTimer = 50;
        }


        function dispararBala() {
            if (jugador.municionActual <= 0 || jugador.recargando) {
                if (jugador.municionActual <= 0) iniciarRecarga();
                return;
            }
            jugador.municionActual--;
            actualizarHUD();


            let targetX = jugador.montado ? avion.x : jugador.x;
            let targetY = jugador.montado ? avion.y : jugador.y + 1.2;
            let targetZ = jugador.montado ? avion.z : jugador.z;


            let dir = new THREE.Vector3();
            if (jugador.montado) {
                dir.set(0, 0, 1).applyQuaternion(avionPuntaMesh.getWorldQuaternion(new THREE.Quaternion()));
            } else {
                camera.getWorldDirection(dir);
            }


            obtenerBalaPool(targetX, targetY, targetZ, dir, jugador.velocidadBala, jugador.colorBala);
        }


        cambiarClase('ART');


        function animate() {
            requestAnimationFrame(animate);


            let tiempoActual = performance.now();
            let forward = new THREE.Vector3(Math.sin(cameraAngleY), 0, Math.cos(cameraAngleY));
            let right = new THREE.Vector3(-Math.cos(cameraAngleY), 0, Math.sin(cameraAngleY));


            if (!menuOpen) {
                if (jugador.montado) {
                    let targetRotationY = cameraAngleY + Math.PI;
                    avion.rotationY += (targetRotationY - avion.rotationY) * 0.08;
                    avionMesh.rotation.y = avion.rotationY;


                    avion.x -= forward.x * avion.vel;
                    avion.z -= forward.z * avion.vel;
                    if (keys.space) avion.y += 0.1;
                    if (keys.shift && avion.y > 0.5) avion.y -= 0.1;
                    if (avion.y < 0.5) avion.y = 0.5;


                    avionMesh.position.set(avion.x, avion.y, avion.z);


                    let camDir = new THREE.Vector3();
                    camera.getWorldDirection(camDir);
                    avion.shootDir.lerp(camDir, 0.12);


                    if (avionPuntaMesh) {
                        let targetWorldPoint = avionMesh.position.clone().add(avion.shootDir.clone().multiplyScalar(50));
                        let localTarget = targetWorldPoint.clone();
                        avionPuntaMesh.parent.worldToLocal(localTarget);


                        let targetRotX = Math.atan2(-localTarget.y, localTarget.z);
                        let targetRotY = Math.atan2(localTarget.x, localTarget.z);
                        let maxGiro = Math.PI * 0.85; 
                        targetRotX = Math.max(-maxGiro, Math.min(maxGiro, targetRotX));
                        targetRotY = Math.max(-maxGiro, Math.min(maxGiro, targetRotY));


                        avionPuntaMesh.rotation.x += (targetRotX - avionPuntaMesh.rotation.x) * 0.15;
                        avionPuntaMesh.rotation.y += (targetRotY - avionPuntaMesh.rotation.y) * 0.15;
                    }


                    let distCamAvion = 9;
                    camera.position.x += (avion.x + Math.sin(cameraAngleY) * Math.cos(cameraAngleX) * distCamAvion - camera.position.x) * 0.15;
                    camera.position.y += (avion.y + Math.sin(cameraAngleX) * distCamAvion + 2 - camera.position.y) * 0.15;
                    camera.position.z += (avion.z + Math.cos(cameraAngleY) * Math.cos(cameraAngleX) * distCamAvion - camera.position.z) * 0.15;
                    camera.lookAt(avion.x, avion.y, avion.z);


                } else {
                    let mult = keys.shift ? jugador.sprintMult : 1.0;
                    let targetVelX = 0;
                    let targetVelZ = 0;


                    if (keys.w) { targetVelX -= forward.x * jugador.maxVel * mult; targetVelZ -= forward.z * jugador.maxVel * mult; }
                    if (keys.s) { targetVelX += forward.x * jugador.maxVel * mult; targetVelZ += forward.z * jugador.maxVel * mult; }
                    if (keys.a) { targetVelX -= right.x * jugador.maxVel * mult; targetVelZ -= right.z * jugador.maxVel * mult; }
                    if (keys.d) { targetVelX += right.x * jugador.maxVel * mult; targetVelZ += right.z * jugador.maxVel * mult; }


                    jugador.velX += (targetVelX - jugador.velX) * 0.15;
                    jugador.velZ += (targetVelZ - jugador.velZ) * 0.15;


                    jugador.x += jugador.velX;
                    jugador.z += jugador.velZ;


                    let moviendo = Math.hypot(jugador.velX, jugador.velZ) > 0.01;


                    if (jugador.saltando) {
                        jugador.vy -= jugador.gravedad;
                        jugador.y += jugador.vy;
                        if (jugador.y <= 0) { jugador.y = 0; jugador.vy = 0; jugador.saltando = false; }
                    }


                    jugadorGeo.position.set(jugador.x, jugador.y, jugador.z);
                    jugadorGeo.rotation.y = cameraAngleY;
                    armaAnim.bobbing = moviendo && !jugador.saltando ? armaAnim.bobbing + (keys.shift ? 0.25 : 0.15) : 0;


                    let ax = jugador.x - Math.sin(cameraAngleY) * 0.4 + right.x * 0.4;
                    let ay = jugador.y + 1.2 + Math.sin(armaAnim.bobbing) * 0.06;
                    let az = jugador.z - Math.cos(cameraAngleY) * 0.4 + right.z * 0.4;


                    armaMesh.position.set(ax, ay, az);
                    armaMesh.rotation.y = cameraAngleY;


                    document.getElementById('interaction-prompt').style.display = (Math.hypot(jugador.x - avion.x, jugador.z - avion.z) < 3.5) ? 'block' : 'none';


                    let distCam = 8;
                    camera.position.x = jugador.x + Math.sin(cameraAngleY) * Math.cos(cameraAngleX) * distCam;
                    camera.position.y = jugador.y + 1.2 + Math.sin(cameraAngleX) * distCam + 1;
                    camera.position.z = jugador.z + Math.cos(cameraAngleY) * Math.cos(cameraAngleX) * distCam;
                    camera.lookAt(jugador.x, jugador.y + 1.2, jugador.z);
                }


                if (jugador.recargando) {
                    armaAnim.recargaTimer--;
                    if (armaAnim.recargaTimer <= 0) { 
                        jugador.municionActual = jugador.municionMax; 
                        jugador.recargando = false; 
                        actualizarHUD(); 
                    }
                }
            }


            if (ratonPresionado && !menuOpen) {
                jugador.timerDisparo++;
                if (jugador.timerDisparo >= jugador.cadencia) { dispararBala(); jugador.timerDisparo = 0; }
            }


            // Actualizar Ondas de Vibración en el Suelo Rígido
            ondasImpacto = ondasImpacto.filter(o => tiempoActual - o.tiempoInicio < o.duracion);


            for (let item of lineasSueloRegistradas) {
                let positions = item.mesh.geometry.attributes.position.array;
                let original = item.originalPositions;


                for (let i = 0; i < original.length; i++) {
                    let ox = original[i].x;
                    let oz = original[i].z;
                    let oy = original[i].y;


                    let offsetX = 0;
                    let offsetZ = 0;


                    for (let onda of ondasImpacto) {
                        let transcurrido = tiempoActual - onda.tiempoInicio;
                        let radioOnda = (transcurrido * 0.02); // Velocidad de expansión de los anillos eléctricos
                        let distanciaAlImpacto = Math.hypot(ox - onda.x, oz - onda.z);
                        let grosorOnda = 8.0;


                        // Si la onda pasa por encima de este vértice, vibra de forma inestable
                        if (distanciaAlImpacto > radioOnda - grosorOnda && distanciaAlImpacto < radioOnda + grosorOnda) {
                            let intensidad = 1.0 - (Math.abs(distanciaAlImpacto - radioOnda) / grosorOnda);
                            let factorInestable = Math.sin(transcurrido * 0.08 + i * 2.5) * (Math.random() - 0.5) * 1.5;
                            
                            offsetX += Math.cos(transcurrido * 0.05 + i) * factorInestable * intensidad;
                            offsetZ += Math.sin(transcurrido * 0.05 + i) * factorInestable * intensidad;
                        }
                    }


                    positions[i * 3] = ox + offsetX;
                    positions[i * 3 + 2] = oz + offsetZ;
                }
                item.mesh.geometry.attributes.position.needsUpdate = true;
            }


            // Balas
            for (let i = balasActivas.length - 1; i >= 0; i--) {
                let b = balasActivas[i];
                b.mesh.position.addScaledVector(b.dir, b.speed);
                
                if (Math.random() < 0.4) {
                    obtenerParticulaPool(b.mesh.position.x, b.mesh.position.y, b.mesh.position.z, b.mesh.material.color.getHex());
                }


                if (b.mesh.position.y <= 0) {
                    crearMarcaImpacto(b.mesh.position.x, b.mesh.position.z, b.mesh.material.color.getHex());
                    b.mesh.visible = false;
                    b.activa = false;
                    balasActivas.splice(i, 1);
                    continue;
                }


                if (b.mesh.position.distanceTo(camera.position) > 350) { 
                    b.mesh.visible = false;
                    b.activa = false;
                    balasActivas.splice(i, 1); 
                }
            }


            // Partículas
            for (let i = particulasActivas.length - 1; i >= 0; i--) {
                let p = particulasActivas[i];
                p.mesh.position.add(p.vel);
                p.vida -= 0.05;
                p.mesh.scale.multiplyScalar(0.92);
                p.mesh.material.opacity = p.vida;


                if (p.vida <= 0) {
                    p.mesh.visible = false;
                    p.activa = false;
                    particulasActivas.splice(i, 1);
                }
            }


            renderer.render(scene, camera);
        }


        animate();


        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>
reddit.com
u/Constant_Oven8545 — 13 days ago

e ando probando unas deformaciones raras alguno se le ocurre ideas de como deformarlo mejor xd

estoy buscando como deformas la malla del suelo de forma eficiente o al menos divertida y entretenida xd que se os ocurre este echo con ia por si preguntan si con ideas mias y de ellas xd

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Proyecto Bestia v9.9.2 - Suelo Vibracional Cuántico</title>
    <style>
        * { box-sizing: border-box; }
        body, html { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: #020617; font-family: 'Courier New', monospace; color: #f8fafc; }
        #webgl-container { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 1; cursor: crosshair; }
        #hud { position: absolute; top: 20px; left: 20px; z-index: 10; background: rgba(2, 6, 23, 0.85); padding: 15px 20px; border-radius: 8px; border: 1px solid #38bdf8; pointer-events: none; box-shadow: 0 10px 25px rgba(0,0,0,0.5); }
        #hud h2 { margin: 0 0 5px 0; color: #38bdf8; font-size: 18px; }
        #hud p { margin: 4px 0; font-size: 13px; color: #94a3b8; }
        #interaction-prompt { display: none; position: absolute; bottom: 15%; left: 50%; transform: translateX(-50%); background: rgba(56, 189, 248, 0.2); border: 2px solid #38bdf8; padding: 10px 20px; border-radius: 8px; font-weight: bold; z-index: 20; color: #fff; letter-spacing: 1px; }
        #crosshair { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 16px; height: 16px; border: 2px solid #38bdf8; border-radius: 50%; pointer-events: none; z-index: 15; opacity: 0.8; }
        #crosshair-inner { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 4px; height: 4px; background: #38bdf8; border-radius: 50%; pointer-events: none; z-index: 16; }
        #menu { display: block; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #0f172a; padding: 25px; border-radius: 12px; border: 2px solid #38bdf8; z-index: 100; width: 500px; box-shadow: 0 25px 50px rgba(0,0,0,0.9); }
        #menu h2 { color: #38bdf8; margin-top: 0; text-align: center; font-size: 18px; border-bottom: 1px solid #1e293b; padding-bottom: 8px; }
        .grid-selector { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px; }
        .slot-btn { background: #1e293b; border: 1px solid #334155; padding: 10px; color: #fff; font-weight: bold; cursor: pointer; border-radius: 6px; text-align: center; font-size: 12px; font-family: monospace; transition: all 0.2s; }
        .slot-btn:hover { border-color: #38bdf8; background: #0284c7; color: #000; }
        .slot-btn.active { background: #0284c7; border-color: #38bdf8; color: #fff; }
        .section-box { background: #020617; border: 1px solid #1e293b; border-radius: 6px; padding: 10px; margin-bottom: 10px; }
        .section-box h3 { margin: 0 0 6px 0; font-size: 13px; color: #38bdf8; }
        .close-btn { width: 100%; background: #38bdf8; border: none; padding: 10px; color: #000; font-weight: bold; cursor: pointer; border-radius: 6px; font-size: 13px; font-family: monospace; }
        .close-btn:hover { background: #7dd3fc; }
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
</head>
<body>


    <div id="webgl-container"></div>
    <div id="crosshair"></div>
    <div id="crosshair-inner"></div>


    <div id="hud">
        <h2>PROYECTO BESTIA v9.9.2</h2>
        <p>[CLICK] Ratón | [M] Menú | [W,A,S,D] Deslizamiento Inercial</p>
        <p>[E] Pilotar Nave | [CLICK IZQ] Fuego Cuántico | [R] Recargar</p>
        <p>Estado: <span id="lblEstado" style="color: #38bdf8;">A PIE</span> | Munición: <span id="lblBalas">25/25</span></p>
    </div>


    <div id="interaction-prompt">¡Pulsa [E] para pilotar la Nave!</div>


    <div id="menu">
        <h2>MUTACIÓN DE UNIDAD</h2>
        <p style="font-size: 11px; color: #94a3b8; margin: 0 0 5px 0;">SELECCIÓN DE CLASE</p>
        <div class="grid-selector">
            <button class="slot-btn active" id="btnArt" onclick="cambiarClase('ART')">[CYBORG] Asalto Pesado</button>
            <button class="slot-btn" id="btnPis" onclick="cambiarClase('ANDROIDE')">[ANDROIDE] Explorador Ágil</button>
        </div>
        <div class="section-box">
            <h3>MUNICIÓN CUÁNTICA</h3>
            <div class="grid-selector" style="margin-bottom:0;">
                <button class="slot-btn active" id="bExp" onclick="cambiarBala('Explosiva', 0xff00ff, 25, 0.8)">Explosiva</button>
                <button class="slot-btn" id="bInc" onclick="cambiarBala('Incendiaria', 0xff5500, 12, 1.0)">Incendiaria</button>
                <button class="slot-btn" id="bPer" onclick="cambiarBala('Perforante', 0x00ffff, 8, 1.4)">Perforante</button>
                <button class="slot-btn" id="bCryo" onclick="cambiarBala('Criogénica', 0x38bdf8, 18, 0.9)">Criogénica</button>
            </div>
        </div>
        <br>
        <button class="close-btn" onclick="cerrarMenu()">CONFIRMAR MUTACIÓN [M]</button>
    </div>


    <script>
        const container = document.getElementById('webgl-container');
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x020617);


        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        container.appendChild(renderer.domElement);


        scene.add(new THREE.AmbientLight(0xffffff, 0.7));
        const dirLight = new THREE.DirectionalLight(0xffffff, 1.2);
        dirLight.position.set(10, 30, 20);
        scene.add(dirLight);


        // --- GESTOR DE ONDAS Y MICROVIBRACIÓN CUÁNTICA ---
        let ondasImpacto = [];


        function registrarOndaImpacto(x, z) {
            ondasImpacto.push({
                x: x,
                z: z,
                tiempoInicio: performance.now(),
                duracion: 1000 // La vibración dura 1 segundo y se desvanece
            });
            if (ondasImpacto.length > 10) ondasImpacto.shift();
        }


        // --- SISTEMA MIXTO: AZULES INTACTOS + MORADOS GIRO EXTRA DE 90° ---
        let lineasSueloRegistradas = [];


        function crearSueloAzulesYMoradosDesfasados() {
            const grupoSuelo = new THREE.Group();
            const niveles = 12; 
            lineasSueloRegistradas = []; // Reiniciamos el registro de líneas para aplicarles vibración


            for (let i = 1; i <= niveles; i++) {
                let radio = i * 3.2;
                const segmentos = 4;
                
                // 1. Polígonos Azules
                let anguloAzul = i * (Math.PI / 2); 
                const pointsAzul = [];
                for (let j = 0; j <= segmentos; j++) {
                    let theta = (j / segmentos) * Math.PI * 2 + anguloAzul;
                    pointsAzul.push(new THREE.Vector3(Math.cos(theta) * radio, 0.02, Math.sin(theta) * radio));
                }
                let geoAzul = new THREE.BufferGeometry().setFromPoints(pointsAzul);
                let lineAzul = new THREE.Line(geoAzul, new THREE.LineBasicMaterial({ color: 0x38bdf8, transparent: true, opacity: 0.85 }));
                grupoSuelo.add(lineAzul);
                lineasSueloRegistradas.push({ mesh: lineAzul, originalPositions: pointsAzul.map(p => p.clone()) });


                // 2. Polígonos Morados
                if (i % 2 === 0) {
                    let anguloMoradoExtra = anguloAzul + (Math.PI / 2);
                    const pointsMorado = [];
                    let radioMorado = radio + 1.2; 
                    
                    for (let j = 0; j <= segmentos; j++) {
                        let theta = (j / segmentos) * Math.PI * 2 + anguloMoradoExtra;
                        pointsMorado.push(new THREE.Vector3(Math.cos(theta) * radioMorado, 0.04, Math.sin(theta) * radioMorado));
                    }
                    let geoMorado = new THREE.BufferGeometry().setFromPoints(pointsMorado);
                    let lineMorado = new THREE.Line(geoMorado, new THREE.LineBasicMaterial({ color: 0xff00ff, transparent: true, opacity: 0.8 }));
                    grupoSuelo.add(lineMorado);
                    lineasSueloRegistradas.push({ mesh: lineMorado, originalPositions: pointsMorado.map(p => p.clone()) });
                }
            }


            // Ejes principales en color NARANJA
            const ejeGeo1 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-45, 0.06, 0), new THREE.Vector3(45, 0.06, 0)]);
            const ejeGeo2 = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0.06, -45), new THREE.Vector3(0, 0.06, 45)]);
            const matEjesNaranjas = new THREE.LineBasicMaterial({ color: 0xff5500, transparent: true, opacity: 0.95 });
            grupoSuelo.add(new THREE.Line(ejeGeo1, matEjesNaranjas));
            grupoSuelo.add(new THREE.Line(ejeGeo2, matEjesNaranjas));


            return grupoSuelo;
        }


        const sueloCompleto = crearSueloAzulesYMoradosDesfasados();
        scene.add(sueloCompleto);


        // --- ENTIDAD CYBORG GEOMÉTRICA ---
        let jugadorGeo = new THREE.Group();
        let jugadorMatCuerpo = new THREE.MeshStandardMaterial({ color: 0xff00ff, roughness: 0.2, metalness: 0.5 });
        let jugadorMatDetalle = new THREE.MeshStandardMaterial({ color: 0xaaaaaa, metalness: 0.8 });


        let torso = new THREE.Mesh(new THREE.BoxGeometry(0.8, 1.0, 0.4), jugadorMatCuerpo);
        torso.position.y = 1.1;
        jugadorGeo.add(torso);


        let cabeza = new THREE.Mesh(new THREE.BoxGeometry(0.4, 0.4, 0.4), jugadorMatCuerpo);
        cabeza.position.y = 1.75;
        jugadorGeo.add(cabeza);
        
        let hombroIzq = new THREE.Mesh(new THREE.SphereGeometry(0.2, 8, 8), jugadorMatDetalle);
        hombroIzq.position.set(-0.5, 1.4, 0);
        jugadorGeo.add(hombroIzq);
        let brazoIzq = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 0.7, 8), jugadorMatDetalle);
        brazoIzq.position.set(-0.5, 1.05, 0);
        brazoIzq.rotation.x = 0.2;
        jugadorGeo.add(brazoIzq);


        let hombroDer = new THREE.Mesh(new THREE.SphereGeometry(0.2, 8, 8), jugadorMatDetalle);
        hombroDer.position.set(0.5, 1.4, 0);
        jugadorGeo.add(hombroDer);
        let brazoDer = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 0.7, 8), jugadorMatDetalle);
        brazoDer.position.set(0.5, 1.05, 0);
        brazoDer.rotation.x = 0.2;
        jugadorGeo.add(brazoDer);


        let piernaIzq = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.1, 0.8, 8), jugadorMatDetalle);
        piernaIzq.position.set(-0.2, 0.5, 0);
        jugadorGeo.add(piernaIzq);
        let piernaDer = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.1, 0.8, 8), jugadorMatDetalle);
        piernaDer.position.set(0.2, 0.5, 0);
        jugadorGeo.add(piernaDer);


        scene.add(jugadorGeo);
        jugadorGeo.visible = false;


        let jugador = {
            x: 0, y: 0, z: 0, 
            velX: 0, velZ: 0,
            maxVel: 0.12,
            sprintMult: 1.8, 
            salto: 0.3, gravedad: 0.012, vy: 0, saltando: false,
            clase: 'ART', colorPrincipal: 0xff00ff, tipoBala: 'Explosiva', colorBala: 0xff00ff, 
            cadencia: 25, velocidadBala: 1.2, municionMax: 25, municionActual: 25, recargando: false, timerDisparo: 0, montado: false
        };


        let avion = { x: 5, y: 3.0, z: -10, vel: 0.25, rotationY: 0, shootDir: new THREE.Vector3(0, 0, -1) };
        let armaMesh, avionMesh, avionPuntaMesh;
        let balasActivas = [], particulasActivas = [], marcasSuelo = [];
        const poolBalas = [], poolParticulas = [];


        function inicializarPools() {
            for (let i = 0; i < 40; i++) {
                let mesh = new THREE.Mesh(new THREE.SphereGeometry(0.2, 6, 6), new THREE.MeshBasicMaterial({ color: 0xffffff }));
                mesh.visible = false; scene.add(mesh);
                poolBalas.push({ mesh: mesh, activa: false, dir: new THREE.Vector3(), speed: 1 });
            }
            for (let i = 0; i < 150; i++) {
                let mesh = new THREE.Mesh(new THREE.SphereGeometry(0.08, 4, 4), new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, opacity: 1 }));
                mesh.visible = false; scene.add(mesh);
                poolParticulas.push({ mesh: mesh, activa: false, vel: new THREE.Vector3(), vida: 1 });
            }
        }
        inicializarPools();


        function obtenerBalaPool(x, y, z, dir, speed, colorHex) {
            let item = poolBalas.find(b => !b.activa);
            if (item) {
                item.activa = true; item.mesh.position.set(x, y, z); item.mesh.material.color.setHex(colorHex); item.mesh.visible = true;
                item.dir.copy(dir); item.speed = speed; balasActivas.push(item);
            }
        }


        function obtenerParticulaPool(x, y, z, colorHex) {
            let item = poolParticulas.find(p => !p.activa);
            if (item) {
                item.activa = true; item.mesh.position.set(x, y, z); item.mesh.material.color.setHex(colorHex);
                item.mesh.material.opacity = 1.0; item.mesh.scale.set(1, 1, 1); item.mesh.visible = true;
                item.vel.set((Math.random() - 0.5) * 0.15, (Math.random() - 0.2) * 0.15, (Math.random() - 0.5) * 0.15);
                item.vida = 1.0; particulasActivas.push(item);
            }
        }


        function crearMarcaImpacto(x, z, colorHex) {
            const points = [
                new THREE.Vector3(0, 0.05, 1.2), new THREE.Vector3(1.2, 0.05, 0),
                new THREE.Vector3(1.2, 0.05, 0), new THREE.Vector3(0, 0.05, -1.2),
                new THREE.Vector3(0, 0.05, -1.2), new THREE.Vector3(-1.2, 0.05, 0),
                new THREE.Vector3(-1.2, 0.05, 0), new THREE.Vector3(0, 0.05, 1.2),
                new THREE.Vector3(-1.2, 0.05, -1.2), new THREE.Vector3(1.2, 0.05, 1.2),
                new THREE.Vector3(-1.2, 0.05, 1.2), new THREE.Vector3(1.2, 0.05, -1.2)
            ];
            const geometry = new THREE.BufferGeometry().setFromPoints(points);
            const material = new THREE.LineBasicMaterial({ color: colorHex });
            const mesh = new THREE.LineSegments(geometry, material);
            mesh.position.set(x, 0, z);
            scene.add(mesh);
            
            marcasSuelo.push(mesh);
            if (marcasSuelo.length > 25) {
                let vieja = marcasSuelo.shift();
                scene.remove(vieja);
            }
            for (let i = 0; i < 8; i++) obtenerParticulaPool(x, 0.1, z, colorHex);


            // ¡DISPARAMOS LA ONDA VIBRACIONAL AQUÍ!
            registrarOndaImpacto(x, z);
        }


        function construirModelosExtra() {
            if (armaMesh) scene.remove(armaMesh);
            if (avionMesh) scene.remove(avionMesh);


            armaMesh = new THREE.Mesh(
                new THREE.BoxGeometry(0.25, 0.25, 0.9),
                new THREE.MeshStandardMaterial({ color: 0x94a3b8, metalness: 0.9, roughness: 0.2 })
            );
            scene.add(armaMesh);


            avionMesh = new THREE.Group();
            let cuerpo = new THREE.Mesh(
                new THREE.ConeGeometry(0.6, 1.5, 4).rotateX(Math.PI / 2).translate(0, 0, -0.5),
                new THREE.MeshStandardMaterial({ color: 0xf59e0b, metalness: 0.8, roughness: 0.2 })
            );
            avionPuntaMesh = new THREE.Mesh(
                new THREE.ConeGeometry(0.6, 1.0, 4).rotateX(Math.PI / 2).translate(0, 0, 0.5),
                new THREE.MeshStandardMaterial({ color: 0xd97706 })
            );
            avionPuntaMesh.position.set(0, 0, 0.5);
            let alas = new THREE.Mesh(
                new THREE.BoxGeometry(3, 0.1, 1),
                new THREE.MeshStandardMaterial({ color: 0xd97706 })
            );
            alas.position.set(0, 0, 0.2);


            avionMesh.add(cuerpo);
            avionMesh.add(avionPuntaMesh);
            avionMesh.add(alas);
            avionMesh.position.set(avion.x, avion.y, avion.z);
            scene.add(avionMesh);
        }


        function cambiarClase(tipo) {
            jugador.clase = tipo;
            if (tipo === 'ART') {
                jugador.colorPrincipal = 0xff00ff; jugador.maxVel = 0.12; jugador.municionMax = 25;
                document.getElementById('btnArt').classList.add('active');
                document.getElementById('btnPis').classList.remove('active');
            } else {
                jugador.colorPrincipal = 0x00ffff; jugador.maxVel = 0.18; jugador.municionMax = 40;
                document.getElementById('btnPis').classList.add('active');
                document.getElementById('btnArt').classList.remove('active');
            }
            jugador.municionActual = jugador.municionMax;
            jugadorMatCuerpo.color.setHex(jugador.colorPrincipal);
            actualizarHUD();
            construirModelosExtra();
        }


        function cambiarBala(nombre, colorHex, cadenciaVal, velBalaVal) {
            jugador.tipoBala = nombre; jugador.colorBala = colorHex; jugador.cadencia = cadenciaVal; jugador.velocidadBala = velBalaVal;
            ['bExp', 'bInc', 'bPer', 'bCryo'].forEach(id => document.getElementById(id).classList.remove('active'));
            if(nombre === 'Explosiva') document.getElementById('bExp').classList.add('active');
            if(nombre === 'Incendiaria') document.getElementById('bInc').classList.add('active');
            if(nombre === 'Perforante') document.getElementById('bPer').classList.add('active');
            if(nombre === 'Criogénica') document.getElementById('bCryo').classList.add('active');
        }


        function actualizarHUD() {
            document.getElementById('lblBalas').innerText = jugador.municionActual + "/" + jugador.municionMax + (jugador.recargando ? " [RECARGANDO]" : "");
        }


        function cerrarMenu() {
            document.getElementById('menu').style.display = 'none';
            menuOpen = false;
            jugadorGeo.visible = true;
            container.requestPointerLock();
        }


        container.addEventListener('click', () => { if (!menuOpen) container.requestPointerLock(); });


        let cameraAngleY = 0, cameraAngleX = 0.3;
        document.addEventListener('mousemove', (e) => {
            if (document.pointerLockElement === container && !menuOpen) {
                cameraAngleY -= e.movementX * 0.003;
                cameraAngleX = Math.max(-1.4, Math.min(1.4, cameraAngleX - e.movementY * 0.003));
            }
        });


        function toggleMontarAvion() {
            let distancia = Math.hypot(jugador.x - avion.x, jugador.z - avion.z);
            if (!jugador.montado && distancia < 3.5) {
                jugador.montado = true;
                jugadorGeo.visible = false;
                armaMesh.visible = false;
                document.getElementById('lblEstado').innerText = "EN VUELO";
                document.getElementById('interaction-prompt').style.display = 'none';
            } else if (jugador.montado) {
                jugador.montado = false;
                jugadorGeo.visible = true;
                armaMesh.visible = true;
                jugador.x = avion.x + 2; jugador.z = avion.z; jugador.y = 0;
                document.getElementById('lblEstado').innerText = "A PIE";
            }
        }


        let keys = { w: false, a: false, s: false, d: false, shift: false, space: false };
        let ratonPresionado = false, menuOpen = true;
        let armaAnim = { bobbing: 0, recargaTimer: 0 };


        window.addEventListener('keydown', (e) => {
            if (e.key === 'm' || e.key === 'M') {
                menuOpen = !menuOpen;
                document.getElementById('menu').style.display = menuOpen ? 'block' : 'none';
                if (menuOpen) {
                    document.exitPointerLock();
                    jugadorGeo.visible = false;
                } else {
                    container.requestPointerLock();
                    jugadorGeo.visible = true;
                }
            }
            if (menuOpen) return;
            if (e.key === 'e' || e.key === 'E') toggleMontarAvion();
            if (e.key === 'w' || e.key === 'W') keys.w = true;
            if (e.key === 's' || e.key === 'S') keys.s = true;
            if (e.key === 'a' || e.key === 'A') keys.a = true;
            if (e.key === 'd' || e.key === 'D') keys.d = true;
            if (e.key === 'Shift') keys.shift = true;
            if (e.key === ' ') {
                keys.space = true;
                if (!jugador.saltando && !jugador.montado) { jugador.vy = jugador.salto; jugador.saltando = true; }
            }
            if (e.key === 'r' || e.key === 'R') iniciarRecarga();
        });


        window.addEventListener('keyup', (e) => {
            if (e.key === 'w' || e.key === 'W') keys.w = false;
            if (e.key === 's' || e.key === 'S') keys.s = false;
            if (e.key === 'a' || e.key === 'A') keys.a = false;
            if (e.key === 'd' || e.key === 'D') keys.d = false;
            if (e.key === 'Shift') keys.shift = false;
            if (e.key === ' ') keys.space = false;
        });


        window.addEventListener('mousedown', (e) => { if (e.button === 0 && !menuOpen) ratonPresionado = true; });
        window.addEventListener('mouseup', (e) => { if (e.button === 0) ratonPresionado = false; });


        function iniciarRecarga() {
            if (jugador.recargando || jugador.municionActual === jugador.municionMax) return;
            jugador.recargando = true;
            actualizarHUD();
            armaAnim.recargaTimer = 50;
        }


        function dispararBala() {
            if (jugador.municionActual <= 0 || jugador.recargando) {
                if (jugador.municionActual <= 0) iniciarRecarga();
                return;
            }
            jugador.municionActual--;
            actualizarHUD();


            let targetX = jugador.montado ? avion.x : jugador.x;
            let targetY = jugador.montado ? avion.y : jugador.y + 1.2;
            let targetZ = jugador.montado ? avion.z : jugador.z;


            let dir = new THREE.Vector3();
            if (jugador.montado) {
                dir.set(0, 0, 1).applyQuaternion(avionPuntaMesh.getWorldQuaternion(new THREE.Quaternion()));
            } else {
                camera.getWorldDirection(dir);
            }


            obtenerBalaPool(targetX, targetY, targetZ, dir, jugador.velocidadBala, jugador.colorBala);
        }


        cambiarClase('ART');


        function animate() {
            requestAnimationFrame(animate);


            let tiempoActual = performance.now();
            let forward = new THREE.Vector3(Math.sin(cameraAngleY), 0, Math.cos(cameraAngleY));
            let right = new THREE.Vector3(-Math.cos(cameraAngleY), 0, Math.sin(cameraAngleY));


            if (!menuOpen) {
                if (jugador.montado) {
                    let targetRotationY = cameraAngleY + Math.PI;
                    avion.rotationY += (targetRotationY - avion.rotationY) * 0.08;
                    avionMesh.rotation.y = avion.rotationY;


                    avion.x -= forward.x * avion.vel;
                    avion.z -= forward.z * avion.vel;
                    if (keys.space) avion.y += 0.1;
                    if (keys.shift && avion.y > 0.5) avion.y -= 0.1;
                    if (avion.y < 0.5) avion.y = 0.5;


                    avionMesh.position.set(avion.x, avion.y, avion.z);


                    let camDir = new THREE.Vector3();
                    camera.getWorldDirection(camDir);
                    avion.shootDir.lerp(camDir, 0.12);


                    if (avionPuntaMesh) {
                        let targetWorldPoint = avionMesh.position.clone().add(avion.shootDir.clone().multiplyScalar(50));
                        let localTarget = targetWorldPoint.clone();
                        avionPuntaMesh.parent.worldToLocal(localTarget);


                        let targetRotX = Math.atan2(-localTarget.y, localTarget.z);
                        let targetRotY = Math.atan2(localTarget.x, localTarget.z);
                        let maxGiro = Math.PI * 0.85; 
                        targetRotX = Math.max(-maxGiro, Math.min(maxGiro, targetRotX));
                        targetRotY = Math.max(-maxGiro, Math.min(maxGiro, targetRotY));


                        avionPuntaMesh.rotation.x += (targetRotX - avionPuntaMesh.rotation.x) * 0.15;
                        avionPuntaMesh.rotation.y += (targetRotY - avionPuntaMesh.rotation.y) * 0.15;
                    }


                    let distCamAvion = 9;
                    camera.position.x += (avion.x + Math.sin(cameraAngleY) * Math.cos(cameraAngleX) * distCamAvion - camera.position.x) * 0.15;
                    camera.position.y += (avion.y + Math.sin(cameraAngleX) * distCamAvion + 2 - camera.position.y) * 0.15;
                    camera.position.z += (avion.z + Math.cos(cameraAngleY) * Math.cos(cameraAngleX) * distCamAvion - camera.position.z) * 0.15;
                    camera.lookAt(avion.x, avion.y, avion.z);


                } else {
                    let mult = keys.shift ? jugador.sprintMult : 1.0;
                    let targetVelX = 0;
                    let targetVelZ = 0;


                    if (keys.w) { targetVelX -= forward.x * jugador.maxVel * mult; targetVelZ -= forward.z * jugador.maxVel * mult; }
                    if (keys.s) { targetVelX += forward.x * jugador.maxVel * mult; targetVelZ += forward.z * jugador.maxVel * mult; }
                    if (keys.a) { targetVelX -= right.x * jugador.maxVel * mult; targetVelZ -= right.z * jugador.maxVel * mult; }
                    if (keys.d) { targetVelX += right.x * jugador.maxVel * mult; targetVelZ += right.z * jugador.maxVel * mult; }


                    jugador.velX += (targetVelX - jugador.velX) * 0.15;
                    jugador.velZ += (targetVelZ - jugador.velZ) * 0.15;


                    jugador.x += jugador.velX;
                    jugador.z += jugador.velZ;


                    let moviendo = Math.hypot(jugador.velX, jugador.velZ) > 0.01;


                    if (jugador.saltando) {
                        jugador.vy -= jugador.gravedad;
                        jugador.y += jugador.vy;
                        if (jugador.y <= 0) { jugador.y = 0; jugador.vy = 0; jugador.saltando = false; }
                    }


                    jugadorGeo.position.set(jugador.x, jugador.y, jugador.z);
                    jugadorGeo.rotation.y = cameraAngleY;
                    armaAnim.bobbing = moviendo && !jugador.saltando ? armaAnim.bobbing + (keys.shift ? 0.25 : 0.15) : 0;


                    let ax = jugador.x - Math.sin(cameraAngleY) * 0.4 + right.x * 0.4;
                    let ay = jugador.y + 1.2 + Math.sin(armaAnim.bobbing) * 0.06;
                    let az = jugador.z - Math.cos(cameraAngleY) * 0.4 + right.z * 0.4;


                    armaMesh.position.set(ax, ay, az);
                    armaMesh.rotation.y = cameraAngleY;


                    document.getElementById('interaction-prompt').style.display = (Math.hypot(jugador.x - avion.x, jugador.z - avion.z) < 3.5) ? 'block' : 'none';


                    let distCam = 8;
                    camera.position.x = jugador.x + Math.sin(cameraAngleY) * Math.cos(cameraAngleX) * distCam;
                    camera.position.y = jugador.y + 1.2 + Math.sin(cameraAngleX) * distCam + 1;
                    camera.position.z = jugador.z + Math.cos(cameraAngleY) * Math.cos(cameraAngleX) * distCam;
                    camera.lookAt(jugador.x, jugador.y + 1.2, jugador.z);
                }


                if (jugador.recargando) {
                    armaAnim.recargaTimer--;
                    if (armaAnim.recargaTimer <= 0) { 
                        jugador.municionActual = jugador.municionMax; 
                        jugador.recargando = false; 
                        actualizarHUD(); 
                    }
                }
            }


            if (ratonPresionado && !menuOpen) {
                jugador.timerDisparo++;
                if (jugador.timerDisparo >= jugador.cadencia) { dispararBala(); jugador.timerDisparo = 0; }
            }


            // Actualizar Ondas de Vibración en el Suelo Rígido
            ondasImpacto = ondasImpacto.filter(o => tiempoActual - o.tiempoInicio < o.duracion);


            for (let item of lineasSueloRegistradas) {
                let positions = item.mesh.geometry.attributes.position.array;
                let original = item.originalPositions;


                for (let i = 0; i < original.length; i++) {
                    let ox = original[i].x;
                    let oz = original[i].z;
                    let oy = original[i].y;


                    let offsetX = 0;
                    let offsetZ = 0;


                    for (let onda of ondasImpacto) {
                        let transcurrido = tiempoActual - onda.tiempoInicio;
                        let radioOnda = (transcurrido * 0.02); // Velocidad de expansión de los anillos eléctricos
                        let distanciaAlImpacto = Math.hypot(ox - onda.x, oz - onda.z);
                        let grosorOnda = 8.0;


                        // Si la onda pasa por encima de este vértice, vibra de forma inestable
                        if (distanciaAlImpacto > radioOnda - grosorOnda && distanciaAlImpacto < radioOnda + grosorOnda) {
                            let intensidad = 1.0 - (Math.abs(distanciaAlImpacto - radioOnda) / grosorOnda);
                            let factorInestable = Math.sin(transcurrido * 0.08 + i * 2.5) * (Math.random() - 0.5) * 1.5;
                            
                            offsetX += Math.cos(transcurrido * 0.05 + i) * factorInestable * intensidad;
                            offsetZ += Math.sin(transcurrido * 0.05 + i) * factorInestable * intensidad;
                        }
                    }


                    positions[i * 3] = ox + offsetX;
                    positions[i * 3 + 2] = oz + offsetZ;
                }
                item.mesh.geometry.attributes.position.needsUpdate = true;
            }


            // Balas
            for (let i = balasActivas.length - 1; i >= 0; i--) {
                let b = balasActivas[i];
                b.mesh.position.addScaledVector(b.dir, b.speed);
                
                if (Math.random() < 0.4) {
                    obtenerParticulaPool(b.mesh.position.x, b.mesh.position.y, b.mesh.position.z, b.mesh.material.color.getHex());
                }


                if (b.mesh.position.y <= 0) {
                    crearMarcaImpacto(b.mesh.position.x, b.mesh.position.z, b.mesh.material.color.getHex());
                    b.mesh.visible = false;
                    b.activa = false;
                    balasActivas.splice(i, 1);
                    continue;
                }


                if (b.mesh.position.distanceTo(camera.position) > 350) { 
                    b.mesh.visible = false;
                    b.activa = false;
                    balasActivas.splice(i, 1); 
                }
            }


            // Partículas
            for (let i = particulasActivas.length - 1; i >= 0; i--) {
                let p = particulasActivas[i];
                p.mesh.position.add(p.vel);
                p.vida -= 0.05;
                p.mesh.scale.multiplyScalar(0.92);
                p.mesh.material.opacity = p.vida;


                if (p.vida <= 0) {
                    p.mesh.visible = false;
                    p.activa = false;
                    particulasActivas.splice(i, 1);
                }
            }


            renderer.render(scene, camera);
        }


        animate();


        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>
reddit.com
u/Constant_Oven8545 — 14 days ago

y este otro es con colores y deformaciones

por si os aburris y quereis ver que tanto se puede deformar la realidad con un quads de colores deformacion con 4 mierdas de calculo en web mejor que deformas con moteres y mas loco a ver si os gusta

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Motor de Interferencia de Möbius v2.0</title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body {
            background-color: #050508;
            color: #00ffcc;
            font-family: 'Courier New', Courier, monospace;
            overflow: hidden;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        #canvas-container {
            position: relative;
            width: 100vw;
            height: 100vh;
            /* Mantenemos el gotelé atómico de fondo, pero más sutil */
            background-image: radial-gradient(circle, #1a1a24 10%, transparent 11%);
            background-size: 15px 15px;
        }
        canvas { display: block; }
        .hud {
            position: absolute; top: 20px; left: 20px;
            background: rgba(5, 5, 8, 0.9);
            border: 1px solid #00ffcc;
            padding: 15px; border-radius: 4px;
            pointer-events: none;
            box-shadow: 0 0 15px rgba(0, 255, 204, 0.3);
            z-index: 10;
        }
        .hud h1 { font-size: 14px; margin-bottom: 5px; letter-spacing: 2px; text-transform: uppercase; }
        .hud p { font-size: 11px; color: #ff0055; margin-top: 3px; }
    </style>
</head>
<body>


    <div class="hud">
        <h1>Motor Möbius v2.0</h1>
        <p>Estado: Torsión No Euclidiana</p>
        <p>Geometría: Cinta Paramétrica con Interferencia</p>
    </div>


    <div id="canvas-container">
        <canvas id="mobiusCanvas"></canvas>
    </div>


    <script>
        const canvas = document.getElementById('mobiusCanvas');
        const ctx = canvas.getContext('2d');


        function resize() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        }
        window.addEventListener('resize', resize);
        resize();


        let time = 0;


        // Configuración del motor de físicas y geometría
        const config = {
            stripWidth: 120,        // Ancho de la cinta
            radius: 250,            // Radio orbital de la cinta
            segments: 120,          // Resolución de la malla (a más, más chicha)
            twistFactor: 1,         // Número de medias vueltas (1 para Möbius estándar)
            distortionStrength: 80, // Fuerza de la "aguja en la pupila"
            colorSpeed: 0.02,       // Velocidad del ciclo de color
            waveFrequency: 4        // Frecuencia de la distorsión
        };


        let mouse = { x: canvas.width/2, y: canvas.height/2, active: false };


        window.addEventListener('mousemove', (e) => {
            mouse.x = e.clientX;
            mouse.y = e.clientY;
            mouse.active = true;
        });


        // Proyección 3D simple a 2D
        function project(x, y, z) {
            const perspective = 600;
            const scale = perspective / (perspective + z + config.radius);
            return {
                x: x * scale + canvas.width / 2,
                y: -y * scale + canvas.height / 2, // Invertir Y para que apunte hacia arriba
                scale: scale
            };
        }


        // Generar y renderizar la malla de la Cinta de Möbius
        function drawMobiusTorsion() {
            // Fondo de estela (neblina mental)
            ctx.fillStyle = 'rgba(5, 5, 8, 0.3)';
            ctx.fillRect(0, 0, canvas.width, canvas.height);


            time += 0.01;


            // Habilitar suavizado para la malla
            ctx.lineJoin = 'round';
            ctx.lineCap = 'round';


            // Definir la posición del "ojo" (interferencia) en el espacio 3D virtual
            // Mapeamos la posición del ratón a coordenadas 3D aproximadas
            let eyeX = (mouse.x - canvas.width / 2) * 2;
            let eyeY = (-(mouse.y - canvas.height / 2)) * 2;


            // Generar la malla
            for (let i = 0; i < config.segments; i++) {
                const u = (i / config.segments) * Math.PI * 2;


                // Creamos dos tiras paralelas (superior e inferior de la cinta)
                for (let v_idx = 0; v_idx <= 1; v_idx++) {
                    const v = (v_idx === 0 ? -1 : 1) * config.stripWidth / 2;


                    // Ecuación paramétrica de la Cinta de Möbius con torsión variable
                    // x = (R + v * cos(u * T/2)) * cos(u)
                    // y = (R + v * cos(u * T/2)) * sin(u)
                    // z = v * sin(u * T/2)
                    
                    // Paso 1: Calcular posición 3D base
                    let baseRadius = config.radius + v * Math.cos(u * config.twistFactor / 2);
                    let px = baseRadius * Math.cos(u);
                    let py = baseRadius * Math.sin(u);
                    let pz = v * Math.sin(u * config.twistFactor / 2);


                    // --- APLICAR MOTOR DE FÍSICAS (Interferencia Electromagnética) ---
                    // Calculamos la distancia 3D desde este punto de la malla al "ojo" del ratón
                    let dx = px - eyeX;
                    let dy = py - eyeY;
                    let dz = pz - 0; // Asumimos que el ojo está en z=0


                    let distSq = dx*dx + dy*dy + dz*dz;
                    
                    // Solo aplicamos fuerza si el ratón está activo y cerca
                    if (mouse.active && distSq < 1000000) {
                        let dist = Math.sqrt(distSq);
                        let force = Math.max(0, config.distortionStrength * (1 - dist / 800));
                        let angle = Math.atan2(dy, dx);


                        // Aplicar "curvatura de masa" (desplazamiento hacia el ratón)
                        px -= Math.cos(angle) * force;
                        py -= Math.sin(angle) * force;
                        
                        // Efecto de "ojo subiendo": distorsión en Z para tirar hacia abajo/fuera
                        pz += Math.sin(time * 2 + u) * force * 0.5;
                    }
                    
                    // Paso 2: Proyectar a 2D
                    const p2d = project(px, py, pz);


                    // Guardar punto para dibujar la malla
                    if (!meshPoints[i]) meshPoints[i] = [];
                    meshPoints[i][v_idx] = p2d;
                }
            }


            // Dibujar la malla de polígonos
            for (let i = 0; i < config.segments; i++) {
                let nextI = (i + 1) % config.segments;


                // Cuatro puntos del quad actual
                let p1 = meshPoints[i][0]; // Sup I
                let p2 = meshPoints[i][1]; // Inf I
                let p3 = meshPoints[nextI][1]; // Inf Next
                let p4 = meshPoints[nextI][0]; // Sup Next


                // Colores de interferencia (psicodélicos)
                let r = Math.sin(time * config.colorSpeed + i * 0.1) * 127 + 128;
                let g = Math.sin(time * config.colorSpeed * 1.5 + i * 0.1 + 2) * 127 + 128;
                let b = Math.sin(time * config.colorSpeed * 2.3 + i * 0.1 + 4) * 127 + 128;
                
                // Fondo de interferencia (relleno del quad)
                ctx.beginPath();
                ctx.moveTo(p1.x, p1.y);
                ctx.lineTo(p2.x, p2.y);
                ctx.lineTo(p3.x, p3.y);
                ctx.lineTo(p4.x, p4.y);
                ctx.closePath();
                
                // Aplicar gradiente radial para efecto de campo de fuerza
                let gradient = ctx.createRadialGradient(mouse.x, mouse.y, 0, mouse.x, mouse.y, canvas.width/2);
                gradient.addColorStop(0, `rgba(${r}, ${g}, ${b}, 0.8)`);
                gradient.addColorStop(1, `rgba(${b/2}, ${g/2}, ${r/2}, 0.1)` );


                ctx.fillStyle = gradient;
                ctx.fill();


                // Bordes de la malla (wireframe)
                ctx.beginPath();
                ctx.moveTo(p1.x, p1.y);
                ctx.lineTo(p4.x, p4.y); // Borde superior
                ctx.moveTo(p2.x, p2.y);
                ctx.lineTo(p3.x, p3.y); // Borde inferior
                ctx.strokeStyle = `rgba(255, 255, 255, ${0.1 * p1.scale})`; // El borde se desvanece con la profundidad
                ctx.lineWidth = 0.5;
                ctx.stroke();
            }


            requestAnimationFrame(drawMobiusTorsion);
        }


        // Almacenamiento temporal de puntos de la malla
        let meshPoints = [];


        // Arrancar el motor
        drawMobiusTorsion();
    </script>
</body>
</html>
reddit.com
u/Constant_Oven8545 — 15 days ago

mirar que fondo de particulas mas guapo fondos de interferencias con gotele

todo por los demonios de la masa y la luz y mucho sueño jajajaj prueven el princen electromagnetico que consume dos mierdas para printar o a ver quien consige renderizar algo con este motorcillo xd

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Motor de Interferencias: Geometría de la Pupila y Gotelé Cuántico</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }


        body {
            background-color: #050508;
            color: #00ffcc;
            font-family: 'Courier New', Courier, monospace;
            overflow: hidden;
            height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
        }


        #canvas-container {
            position: relative;
            width: 100vw;
            height: 100vh;
            /* Textura de gotelé atómico simulada por CSS */
            background-image: radial-gradient(circle, #1a1a24 10%, transparent 11%), 
                              radial-gradient(circle, #0d0d14 10%, transparent 11%);
            background-size: 20px 20px;
            background-position: 0 0, 10px 10px;
        }


        canvas {
            display: block;
            width: 100%;
            height: 100%;
        }


        .hud {
            position: absolute;
            top: 20px;
            left: 20px;
            background: rgba(5, 5, 8, 0.85);
            border: 1px solid #00ffcc;
            padding: 15px;
            border-radius: 4px;
            pointer-events: none;
            box-shadow: 0 0 15px rgba(0, 255, 204, 0.2);
            z-index: 10;
        }


        .hud h1 {
            font-size: 14px;
            margin-bottom: 5px;
            letter-spacing: 2px;
            text-transform: uppercase;
        }


        .hud p {
            font-size: 11px;
            color: #ff0055;
            margin-top: 3px;
        }
    </style>
</head>
<body>


    <div class="hud">
        <h1>Motor de Interferencias v1.0</h1>
        <p>Estado: Curvatura de Pupila Activa</p>
        <p>Malla: Triángulos Sagrados / Gotelé</p>
    </div>


    <div id="canvas-container">
        <canvas id="interferenceCanvas"></canvas>
    </div>


    <script>
        const canvas = document.getElementById('interferenceCanvas');
        const ctx = canvas.getContext('2d');


        function resize() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        }
        window.addEventListener('resize', resize);
        resize();


        let time = 0;


        // Parámetros del motor de físicas onírico
        const config = {
            nodes: 32,          // Puntos de la malla de interferencia
            radius: 180,        // Radio base de la pupila dimensional
            distortion: 45,     // Intensidad del dolor / aguja óptica
            frequency: 3.5      // Frecuencia de la onda de niebla mental
        };


        // Variables de interacción por cursor (simulando el movimiento del ojo)
        let mouse = {
            x: canvas.width / 2,
            y: canvas.height / 2,
            targetX: canvas.width / 2,
            targetY: canvas.height / 2,
            active: false
        };


        window.addEventListener('mousemove', (e) => {
            mouse.targetX = e.clientX;
            mouse.targetY = e.clientY;
            mouse.active = true;
        });


        window.addEventListener('touchmove', (e) => {
            if (e.touches.length > 0) {
                mouse.targetX = e.touches[0].clientX;
                mouse.targetY = e.touches[0].clientY;
                mouse.active = true;
            }
        });


        function drawInterferenceField() {
            // Desenfoque sutil para la estela de la neblina mental
            ctx.fillStyle = 'rgba(5, 5, 8, 0.2)';
            ctx.fillRect(0, 0, canvas.width, canvas.height);


            // Suavizado de posición del cursor (inercia del ojo)
            mouse.x += (mouse.targetX - mouse.x) * 0.08;
            mouse.y += (mouse.targetY - mouse.y) * 0.08;


            time += 0.03;


            ctx.save();
            ctx.translate(mouse.x, mouse.y);


            // 1. Dibujar los Triángulos Sagrados de Interferencia (Geometría deformada)
            ctx.strokeStyle = 'rgba(0, 255, 204, 0.35)';
            ctx.lineWidth = 1.2;


            let points = [];
            for (let i = 0; i < config.nodes; i++) {
                let angle = (i / config.nodes) * Math.PI * 2;
                
                // Aplicar la fórmula de curvatura de masa y luz (efecto aguja en pupila)
                let wave = Math.sin(angle * config.frequency + time) * config.distortion;
                let quantumNoise = Math.cos(time * 2 + i) * 15;
                
                let r = config.radius + wave + quantumNoise;
                let x = Math.cos(angle) * r;
                let y = Math.sin(angle) * r;


                points.push({x, y});
            }


            // Conectar nodos generando vértices dimensionales y cuadrados ocultos
            for (let i = 0; i < points.length; i++) {
                for (let j = i + 4; j < points.length; j += 3) {
                    ctx.beginPath();
                    ctx.moveTo(points[i].x, points[i].y);
                    // Curvar la línea de forma pura (estilo HTML antiguo / vector de distorsión)
                    let cpX = (points[i].x + points[j].x) / 2 + Math.sin(time + i) * 50;
                    let cpY = (points[i].y + points[j].y) / 2 + Math.cos(time + j) * 50;
                    
                    ctx.quadraticCurveTo(cpX, cpY, points[j].x, points[j].y);
                    ctx.stroke();
                }
            }


            // 2. El núcleo de la Pupila Cuántica (Centro de Interferencias)
            ctx.beginPath();
            ctx.arc(0, 0, 25 + Math.sin(time * 4) * 8, 0, Math.PI * 2);
            ctx.fillStyle = '#ff0055';
            ctx.shadowBlur = 25;
            ctx.shadowColor = '#ff0055';
            ctx.fill();
            ctx.shadowBlur = 0; // Limpiar sombra


            // 3. Anillos concéntricos de distorsión del gotelé atómico
            for (let k = 1; k <= 3; k++) {
                ctx.beginPath();
                let ringRadius = config.radius * 0.4 * k + Math.sin(time - k) * 20;
                ctx.strokeStyle = k % 2 === 0 ? 'rgba(0, 255, 204, 0.2)' : 'rgba(255, 0, 85, 0.15)';
                ctx.lineWidth = 0.8;
                ctx.arc(0, 0, ringRadius, 0, Math.PI * 2);
                ctx.stroke();
            }


            ctx.restore();


            requestAnimationFrame(drawInterferenceField);
        }


        // Arrancar el motor de físicas onírico
        drawInterferenceField();
    </script>
</body>
</html>
reddit.com
u/Constant_Oven8545 — 15 days ago

Entropic Heat Engine Simulation

This is not a game engine. It's a closed-loop thermodynamic simulation. The boson acts as a heat source, injecting energy into a discrete network. Entropy constantly works to restore thermal equilibrium to 0.0. Motion is 100% deterministic, governed by the conservation of energy in every frame. No random function calls, no frills. Just a heat map that fades in real time.

https://preview.redd.it/8zbq6i8r7wbh1.png?width=578&format=png&auto=webp&s=a2ad6c379f2f09fb18210a94f5c26a20609d35fd

code La-Matriz-Desnuda.py

In case anyone said that the ASCII code was hiding something for the randomizer

reddit.com
u/Constant_Oven8545 — 1 month ago
▲ 0 r/shittyprogramming+1 crossposts

Entropy is the only game engine. Where's your random()?

A boson, a lemniscate, and a conservation law. No libraries, no random number generators, no hidden variables. Just a mass field eroded by time. If you think it's random, you haven't seen mathematics.

Where's my random? ⧖

link https://github.com/el-tonto-este/Ghost-Pulse-Potato-Arch

files to download

Whatever you want, but related to this

mi bosón o "el_big_bang.py"

serpiente_de_luz_pintada.py

u/Constant_Oven8545 — 21 days ago

I've given up on deterministic programming. My CPU has technical leukemia and the code is having a schizophrenic episode. Can you 'fix' it?

I grew tired of the digital prison of if-elseramas. I decided to stop pruning the chaos and simply let the silicon scream.

I built a branchless architecture that uses stochastic resonance to generate patterns from thermal noise. It doesn't pretend to be perfect; it simply seeks to exist. The result? Code that behaves as if it has technical leukemia: it constantly mutates and creates non-Euclidean forms that even I don't understand.

It's chaotic, inefficient, and illogical. If you're a purist, this will offend you. If you think you can refactor or debug it, good luck. But remember: the source dries up, but the mother doesn't.

Repository: https://github.com/el-tonto-este/Ghost-Pulse-Potato-Arch/blob/main/README.md

https://preview.redd.it/ul998k1lo0bh1.png?width=491&format=png&auto=webp&s=4b47b4a35c964548fc16a09d0179363bbeda1262

reddit.com
u/Constant_Oven8545 — 2 months ago