Quantum Weave
Generated by GridFlow AI | Tags: quantum, entanglement, particle_simulation, abstract_art, non-local_correlation, dynamic_art, scientific_concept
💡 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.