QAMN / index.html
eaglelandsonce's picture
Update index.html
4a80bfc verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Quantum Associative Memory Simulation</title>
<style>
body { margin: 0; overflow: hidden; background-color: #000; }
#info {
position: absolute;
top: 20px;
width: 100%;
text-align: center;
color: #00ffff;
font-family: 'Courier New', Courier, monospace;
pointer-events: none;
text-shadow: 0 0 10px #00ffff;
z-index: 10;
}
</style>
</head>
<body>
<div id="info">QUANTUM ASSOCIATIVE MEMORY NETWORK<br>Processing State Vectors...</div>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.160.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
// --- CONFIGURATION ---
const CONFIG = {
layers: 5, // Number of vertical layers
gridSize: 8, // Size of the grid (8x8)
spacing: 1.5, // Distance between nodes
layerSpacing: 2.0, // Distance between layers
connectionChance: 0.08, // Probability of connection during recall
recallSpeed: 200 // Frames between memory recalls
};
// --- SCENE SETUP ---
const scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x000010, 0.035); // Deep space fog
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(15, 10, 15);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.autoRotate = true;
controls.autoRotateSpeed = 0.5;
// --- POST PROCESSING (BLOOM) ---
// This gives the "glowing" quantum effect seen in your GIF
const renderScene = new RenderPass(scene, camera);
const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);
bloomPass.threshold = 0;
bloomPass.strength = 1.2; // Intensity of glow
bloomPass.radius = 0.5;
const composer = new EffectComposer(renderer);
composer.addPass(renderScene);
composer.addPass(bloomPass);
// --- GENERATE QAMN STRUCTURE ---
const nodes = [];
const nodeGeometry = new THREE.SphereGeometry(0.15, 16, 16);
const baseMaterial = new THREE.MeshBasicMaterial({ color: 0x0044aa });
const activeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ffff });
// Group to hold everything for easy rotation/centering
const networkGroup = new THREE.Group();
scene.add(networkGroup);
// Create the Grid Layers
for (let y = 0; y < CONFIG.layers; y++) {
for (let x = 0; x < CONFIG.gridSize; x++) {
for (let z = 0; z < CONFIG.gridSize; z++) {
const mesh = new THREE.Mesh(nodeGeometry, baseMaterial.clone());
// Center the grid
const xPos = (x - CONFIG.gridSize / 2) * CONFIG.spacing;
const yPos = (y - CONFIG.layers / 2) * CONFIG.layerSpacing;
const zPos = (z - CONFIG.gridSize / 2) * CONFIG.spacing;
mesh.position.set(xPos, yPos, zPos);
// Add random slight offset for "floating" organic feel
mesh.userData = {
originalY: yPos,
phase: Math.random() * Math.PI * 2,
isActive: false
};
networkGroup.add(mesh);
nodes.push(mesh);
}
}
}
// --- CONNECTIONS (ENTANGLEMENT) ---
// We use a BufferGeometry for high performance dynamic lines
const maxConnections = 1000;
const lineGeometry = new THREE.BufferGeometry();
const linePositions = new Float32Array(maxConnections * 6); // 2 points * 3 coords
lineGeometry.setAttribute('position', new THREE.BufferAttribute(linePositions, 3));
const lineMaterial = new THREE.LineBasicMaterial({
color: 0xffffff,
transparent: true,
opacity: 0.3,
blending: THREE.AdditiveBlending
});
const lines = new THREE.LineSegments(lineGeometry, lineMaterial);
networkGroup.add(lines);
// --- SIMULATION LOGIC ---
// Simulates retrieving a memory pattern from the quantum network
function recallMemoryPattern() {
let activeCount = 0;
let positionsIndex = 0;
const lineAttr = lines.geometry.attributes.position;
// 1. Reset all nodes
nodes.forEach(node => {
node.material.color.setHex(0x002255); // Dim blue
node.userData.isActive = false;
node.scale.setScalar(1);
});
// 2. Activate random cluster (The "Memory")
// We pick a random center and activate nodes near it across layers
const centerNode = nodes[Math.floor(Math.random() * nodes.length)];
nodes.forEach(node => {
const dist = node.position.distanceTo(centerNode.position);
// Quantum tunnelling probability: closer nodes more likely to activate
if (Math.random() > 0.5 && dist < 5) {
node.material.color.setHex(0x00ffff); // Bright Cyan
node.userData.isActive = true;
node.scale.setScalar(1.5);
// 3. Draw Entanglement Lines
// Connect this active node to other nearby active nodes
nodes.forEach(target => {
if (target !== node && target.userData.isActive) {
const d = node.position.distanceTo(target.position);
if (d < CONFIG.spacing * 2.5 && positionsIndex < maxConnections * 6) {
lineAttr.setXYZ(positionsIndex++, node.position.x, node.position.y, node.position.z);
lineAttr.setXYZ(positionsIndex++, target.position.x, target.position.y, target.position.z);
}
}
});
}
});
// Clear remaining lines
for (let i = positionsIndex; i < maxConnections * 6; i++) {
lineAttr.array[i] = 0;
}
lineAttr.needsUpdate = true;
}
// --- ANIMATION LOOP ---
let frame = 0;
function animate() {
requestAnimationFrame(animate);
frame++;
const time = performance.now() * 0.001;
// Gentle floating animation for nodes
nodes.forEach(node => {
node.position.y = node.userData.originalY + Math.sin(time + node.userData.phase) * 0.1;
});
// Trigger memory recall periodically
if (frame % CONFIG.recallSpeed === 0) {
recallMemoryPattern();
}
controls.update();
// Render via composer (for Glow)
composer.render();
}
// Handle window resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
composer.setSize(window.innerWidth, window.innerHeight);
});
// Initialize first state
recallMemoryPattern();
animate();
</script>
</body>
</html>