Quantum Weave

📅 April 16, 2026 🏷️ art
quantum entanglement particle_simulation abstract_art non-local_correlation dynamic_art scientific_concept
Generated by GridFlow AI | Tags: quantum, entanglement, particle_simulation, abstract_art, non-local_correlation, dynamic_art, scientific_concept

📊 视觉感受量化评分

0
0
0
0

💡 AI 提示词

Quantum Entanglement Simulation

🧠 核心算法要点

  • Two `QuantumParticle` objects represent the entangled pair, positioned equidistant from the canvas center.
  • A shared `quantumState` object holds current 'collapsed' properties (hue and angular 'spin').
  • Periodically, a 'measurement' event occurs, randomizing the shared `quantumState` and visually indicated by a brief screen flash.
  • One `QuantumParticle` displays its state directly from `quantumState`, while the other displays a perfectly anti-correlated state (e.g., opposite hue and angle), demonstrating instantaneous non-local correlation.
  • A dynamically wavy, gradient line connects the two main particles, visually emphasizing their inexplicable quantum link.
  • Smaller, ephemeral `GhostParticle` objects orbit each main particle, representing their uncertain, probabilistic 'wave function' before measurement, fading and respawning to suggest constant flux.

💻 原始 p5.js 代码

var sketch = function(p) {
    let entangledParticles = [];
    let ghostParticles = [];
    let quantumState = {
        hue: 0,
        angle: 0
    };
    let lastMeasurementTime = 0;
    let measurementInterval = 2000; // milliseconds between measurements

    class QuantumParticle {
        constructor(id, x, y, size, isPrimary) {
            this.id = id;
            this.x = x;
            this.y = y;
            this.size = size;
            this.isPrimary = isPrimary; // true for particle A, false for particle B (correlated)
            this.currentHue = 0;
            this.currentAngle = 0;
            this.rotationSpeed = p.random(0.005, 0.02);
            this.noiseOffset = p.random(1000); // For subtle movement
        }

        updateState(hue, angle) {
            if (this.isPrimary) {
                this.currentHue = hue;
                this.currentAngle = angle;
            } else {
                // Correlated state: opposite hue and angle
                this.currentHue = (hue + 180) % 360;
                this.currentAngle = (angle + p.PI) % (2 * p.PI);
            }
        }

        display() {
            p.push();
            p.translate(this.x, this.y);

            // Subtle movement based on noise
            let offsetX = p.map(p.noise(this.noiseOffset + p.frameCount * 0.005), 0, 1, -this.size * 0.1, this.size * 0.1);
            let offsetY = p.map(p.noise(this.noiseOffset + 1000 + p.frameCount * 0.005), 0, 1, -this.size * 0.1, this.size * 0.1);
            p.translate(offsetX, offsetY);

            // Particle core
            p.noStroke();
            p.fill(this.currentHue, 80, 100, 0.8);
            p.ellipse(0, 0, this.size);

            // Inner glow
            p.fill(this.currentHue, 50, 100, 0.3);
            p.ellipse(0, 0, this.size * 0.8);

            // "Spin" indicator
            p.stroke(255, 0.7);
            p.strokeWeight(this.size * 0.02);
            p.rotate(this.currentAngle + p.frameCount * this.rotationSpeed);
            p.line(0, 0, this.size * 0.4, 0);

            p.pop();
        }
    }

    class GhostParticle {
        constructor(parentX, parentY, parentSize) {
            this.parentX = parentX;
            this.parentY = parentY;
            this.parentSize = parentSize;
            this.reset();
            this.alpha = p.random(50, 150);
            this.hueOffset = p.random(-30, 30);
        }

        reset() {
            this.angle = p.random(p.TWO_PI);
            this.radius = p.random(this.parentSize * 0.4, this.parentSize * 0.8);
            this.speed = p.random(0.005, 0.02);
            this.size = p.random(this.parentSize * 0.05, this.parentSize * 0.15);
            this.maxLifetime = p.random(100, 300);
            this.lifetime = this.maxLifetime; // Reset lifetime
        }

        update(parentX, parentY, parentHue) {
            this.parentX = parentX;
            this.parentY = parentY;
            this.angle += this.speed;
            this.lifetime -= 2; // Fade out
            if (this.lifetime <= 0) {
                this.reset(); // Reborn
            }
        }

        display(parentHue) {
            p.push();
            let x = this.parentX + p.cos(this.angle) * this.radius;
            let y = this.parentY + p.sin(this.angle) * this.radius;
            p.noStroke();
            p.fill((parentHue + this.hueOffset) % 360, 50, 100, p.map(this.lifetime, 0, this.maxLifetime, 0, this.alpha));
            p.ellipse(x, y, this.size * p.map(this.lifetime, 0, this.maxLifetime, 0.5, 1)); // Scale with lifetime
            p.pop();
        }
    }

    p.setup = function() {
        let container = document.getElementById('p5-wrapper'); p.createCanvas(container.offsetWidth, container.offsetHeight).parent('p5-wrapper');
        p.colorMode(p.HSB, 360, 100, 100, 1);
        p.ellipseMode(p.CENTER);

        let particleSize = p.min(p.width, p.height) * 0.15;
        entangledParticles.push(new QuantumParticle(0, p.width * 0.25, p.height * 0.5, particleSize, true));
        entangledParticles.push(new QuantumParticle(1, p.width * 0.75, p.height * 0.5, particleSize, false));

        // Create ghost particles for each main particle
        for (let i = 0; i < 2; i++) {
            let parent = entangledParticles[i];
            for (let j = 0; j < 20; j++) {
                ghostParticles.push(new GhostParticle(parent.x, parent.y, parent.size));
            }
        }

        // Initial measurement
        measureEntanglement();
        lastMeasurementTime = p.millis();
    };

    p.draw = function() {
        p.background(0, 0, 10, 1); // Dark background

        // Periodically trigger a measurement
        if (p.millis() - lastMeasurementTime > measurementInterval) {
            measureEntanglement();
            lastMeasurementTime = p.millis();
        }

        // Update and display main particles
        let p1 = entangledParticles[0];
        let p2 = entangledParticles[1];

        // Update states based on the shared quantumState
        p1.updateState(quantumState.hue, quantumState.angle);
        p2.updateState(quantumState.hue, quantumState.angle); // EntangledParticle handles the correlation logic

        p1.display();
        p2.display();

        // Draw the entanglement link
        drawEntanglementLink(p1, p2);

        // Update and display ghost particles
        for (let i = 0; i < ghostParticles.length; i++) {
            let parentIndex = p.floor(i / 20); // Each 20 ghost particles belong to one main particle
            let parent = entangledParticles[parentIndex];
            ghostParticles[i].update(parent.x, parent.y, parent.currentHue);
            ghostParticles[i].display(parent.currentHue);
        }
    };

    function measureEntanglement() {
        // A "measurement" collapses the superposition, defining a state for the pair
        quantumState.hue = p.random(360);
        quantumState.angle = p.random(p.TWO_PI);

        // Flash effect for measurement
        p.fill(quantumState.hue, 50, 100, 0.5);
        p.rect(0, 0, p.width, p.height);
    }

    function drawEntanglementLink(particleA, particleB) {
        let numSegments = 50;

        p.push();
        p.strokeWeight(p.min(p.width, p.height) * 0.003); // Responsive line thickness

        for (let i = 0; i < numSegments; i++) {
            let t1 = i / numSegments;
            let t2 = (i + 1) / numSegments;

            let x1 = p.lerp(particleA.x, particleB.x, t1);
            let y1 = p.lerp(particleA.y, particleB.y, t1);
            let x2 = p.lerp(particleA.x, particleB.x, t2);
            let y2 = p.lerp(particleA.y, particleB.y, t2);

            // Make the line slightly wavy
            let waveOffset = p.sin(p.frameCount * 0.05 + t1 * p.TWO_PI * 5) * p.min(p.width, p.height) * 0.005;
            let midX = (x1 + x2) / 2;
            let midY = (y1 + y2) / 2;
            let angle = p.atan2(y2 - y1, x2 - x1);

            // Apply wave perpendicular to the line segment
            x1 += p.cos(angle + p.HALF_PI) * waveOffset;
            y1 += p.sin(angle + p.HALF_PI) * waveOffset;
            x2 += p.cos(angle + p.HALF_PI) * waveOffset;
            y2 += p.sin(angle + p.HALF_PI) * waveOffset;

            // Gradient color based on shared state
            let segmentHue = p.lerp(particleA.currentHue, particleB.currentHue, t1);
            p.stroke(segmentHue, 70, 90, 0.8 - t1 * 0.3); // Fade out slightly towards ends

            // Draw line segment
            p.line(x1, y1, x2, y2);
        }
        p.pop();
    }


    p.windowResized = function() {
        let container = document.getElementById('p5-wrapper'); p.resizeCanvas(container.offsetWidth, container.offsetHeight);
        let particleSize = p.min(p.width, p.height) * 0.15;
        entangledParticles[0].x = p.width * 0.25;
        entangledParticles[0].y = p.height * 0.5;
        entangledParticles[0].size = particleSize;
        entangledParticles[1].x = p.width * 0.75;
        entangledParticles[1].y = p.height * 0.5;
        entangledParticles[1].size = particleSize;

        ghostParticles = [];
        for (let i = 0; i < 2; i++) {
            let parent = entangledParticles[i];
            for (let j = 0; j < 20; j++) {
                ghostParticles.push(new GhostParticle(parent.x, parent.y, parent.size));
            }
        }
    };
};
new p5(sketch);

🎨 AI 艺术解读

This artwork visually abstracts the profound and perplexing concept of quantum entanglement. The two primary orbs, though spatially separated, are inextricably linked, instantly mirroring each other's 'spin' and 'color' when their shared quantum state is measured. The surrounding 'ghost' particles evoke the probabilistic nature of their unmeasured state, collapsing into definition with each periodic observation. It's a poetic abstraction of how observation collapses possibilities into a singular, correlated reality across vast distances, highlighting the mysterious interconnectedness of the quantum realm.

📝 补充说明

  • The artwork is implemented in instance mode (`var sketch = function(p) { ... }; new p5(sketch);`) for better organization and to avoid global namespace conflicts.
  • Using `p.colorMode(p.HSB)` simplifies color manipulation, allowing direct use of hue for representing quantum states and generating complementary colors for entanglement.
  • The `p.windowResized()` function dynamically adjusts particle positions and sizes, along with re-initializing ghost particles, ensuring the artwork scales gracefully across various screen dimensions.
  • `p.push()` and `p.pop()` are used extensively within the `display` methods of particle classes to isolate transformations (translate, rotate) for individual objects, preventing unintended global effects.
  • The 'measurement' event is simulated with a timed random state change and a subtle screen-wide color flash, providing a clear visual cue for the 'collapse' of the quantum wave function.