// visualization/holographic-field.ts // Implements the holographic memory field visualization import { Complex, Prime } from "../types"; import { Quaternion } from "../quaternion"; import { Coordinate2D, Coordinate3D, HolographicPoint, RenderContext, AnimationState } from "./types"; /** * Represents a holographic memory field that visualizes * quantum information distribution in 3D space */ export class HolographicField { points: Array; resolution: i32; bounds: Coordinate3D; interferencePattern: Map; animationStates: Map; constructor(resolution: i32 = 20, bounds: Coordinate3D = new Coordinate3D(100, 100, 100)) { this.points = new Array(); this.resolution = resolution; this.bounds = bounds; this.interferencePattern = new Map(); this.animationStates = new Map(); this.initializeField(); } /** * Initialize the holographic field with a grid of points */ private initializeField(): void { const stepX = this.bounds.x / this.resolution; const stepY = this.bounds.y / this.resolution; const stepZ = this.bounds.z / this.resolution; for (let i = 0; i < this.resolution; i++) { for (let j = 0; j < this.resolution; j++) { for (let k = 0; k < this.resolution; k++) { const x = (i - this.resolution / 2) * stepX; const y = (j - this.resolution / 2) * stepY; const z = (k - this.resolution / 2) * stepZ; const position = new Coordinate3D(x, y, z); const amplitude = new Complex(0, 0); const phase = 0; const frequency = 1.0; this.points.push( new HolographicPoint(position, amplitude, phase, frequency) ); } } } } /** * Add a quantum source to the field */ addSource(position: Coordinate3D, amplitude: Complex, frequency: f64 = 1.0): void { // Find nearest grid point let nearestPoint: HolographicPoint | null = null; let minDistance = f64.MAX_VALUE; for (let i = 0; i < this.points.length; i++) { const point = this.points[i]; const distance = point.position.distanceTo3D(position); if (distance < minDistance) { minDistance = distance; nearestPoint = point; } } if (nearestPoint) { nearestPoint.amplitude = amplitude; nearestPoint.frequency = frequency; this.propagateWave(nearestPoint); } } /** * Propagate wave from a source point through the field */ private propagateWave(source: HolographicPoint): void { const waveSpeed = 1.0; const damping = 0.95; for (let i = 0; i < this.points.length; i++) { const point = this.points[i]; if (point === source) continue; const distance = source.position.distanceTo3D(point.position); const phase = 2 * Math.PI * distance * source.frequency / waveSpeed; const amplitude = source.amplitude.multiply( Complex.fromPolar(damping ** distance, -phase) ); // Superposition principle point.amplitude = point.amplitude.add(amplitude); point.phase = Math.atan2(point.amplitude.imag, point.amplitude.real); } } /** * Calculate interference pattern between multiple sources */ calculateInterference(): void { this.interferencePattern.clear(); // Sample interference at key points const sampleResolution = 10; const stepX = this.bounds.x / sampleResolution; const stepY = this.bounds.y / sampleResolution; for (let i = 0; i < sampleResolution; i++) { for (let j = 0; j < sampleResolution; j++) { const x = (i - sampleResolution / 2) * stepX; const y = (j - sampleResolution / 2) * stepY; const z = 0; // Sample at z=0 plane const samplePoint = new Coordinate3D(x, y, z); let totalAmplitude = new Complex(0, 0); // Sum contributions from all points for (let k = 0; k < this.points.length; k++) { const point = this.points[k]; const distance = point.position.distanceTo3D(samplePoint); const phase = 2 * Math.PI * distance * point.frequency; const contribution = point.amplitude.multiply( Complex.fromPolar(1.0 / (1.0 + distance), -phase) ); totalAmplitude = totalAmplitude.add(contribution); } const key = `${i},${j}`; this.interferencePattern.set(key, totalAmplitude); } } } /** * Apply quantum operation to the field */ applyQuantumOperation(operation: string, params: Map): void { switch (operation) { case "collapse": this.collapseWaveFunction(params.get("position_x")!, params.get("position_y")!, params.get("position_z")!); break; case "entangle": this.createEntanglement(params.get("source_x")!, params.get("source_y")!, params.get("source_z")!, params.get("target_x")!, params.get("target_y")!, params.get("target_z")!); break; case "rotate": this.rotateField(params.get("angle")!, params.get("axis_x")!, params.get("axis_y")!, params.get("axis_z")!); break; } } /** * Collapse wave function at a specific position */ private collapseWaveFunction(x: f64, y: f64, z: f64): void { const collapsePoint = new Coordinate3D(x, y, z); const collapseRadius = 20.0; for (let i = 0; i < this.points.length; i++) { const point = this.points[i]; const distance = point.position.distanceTo3D(collapsePoint); if (distance < collapseRadius) { // Gaussian collapse const factor = Math.exp(-(distance * distance) / (2 * collapseRadius * collapseRadius)); point.amplitude = point.amplitude.multiply(new Complex(factor, 0)); // Add animation const animKey = `collapse_${i}`; this.animationStates.set(animKey, new AnimationState( point.amplitude.magnitude(), point.amplitude.magnitude() * factor, 1000, // 1 second duration AnimationState.easeOutElastic )); } } } /** * Create quantum entanglement between two regions */ private createEntanglement(x1: f64, y1: f64, z1: f64, x2: f64, y2: f64, z2: f64): void { const source = new Coordinate3D(x1, y1, z1); const target = new Coordinate3D(x2, y2, z2); const entangleRadius = 15.0; let sourcePoints: Array = []; let targetPoints: Array = []; // Find points in source and target regions for (let i = 0; i < this.points.length; i++) { const point = this.points[i]; if (point.position.distanceTo3D(source) < entangleRadius) { sourcePoints.push(point); } if (point.position.distanceTo3D(target) < entangleRadius) { targetPoints.push(point); } } // Create entanglement by correlating phases for (let i = 0; i < sourcePoints.length && i < targetPoints.length; i++) { const sourcePoint = sourcePoints[i]; const targetPoint = targetPoints[i]; // Entangle phases const avgPhase = (sourcePoint.phase + targetPoint.phase) / 2; sourcePoint.phase = avgPhase; targetPoint.phase = avgPhase; // Create visual connection const midpoint = sourcePoint.position.lerp(targetPoint.position, 0.5); const entangleAmplitude = sourcePoint.amplitude.add(targetPoint.amplitude).multiply( new Complex(0.5, 0) ); this.addSource(midpoint, entangleAmplitude, 2.0); // Higher frequency for entanglement } } /** * Rotate the entire field using quaternion rotation */ private rotateField(angle: f64, axisX: f64, axisY: f64, axisZ: f64): void { const axis = new Quaternion(0, axisX, axisY, axisZ).normalize(); const halfAngle = angle / 2.0; const rotation = new Quaternion( Math.cos(halfAngle), Math.sin(halfAngle) * axis.x, Math.sin(halfAngle) * axis.y, Math.sin(halfAngle) * axis.z ); for (let i = 0; i < this.points.length; i++) { const point = this.points[i]; const rotated = point.position.rotate(rotation); point.position = rotated; // Also rotate the quaternion if present if (point.quaternion) { point.quaternion = rotation.multiply(point.quaternion); } } } /** * Update animations */ updateAnimations(deltaTime: f64): void { const keys = this.animationStates.keys(); const toRemove: Array = []; for (let i = 0; i < keys.length; i++) { const key = keys[i]; const animation = this.animationStates.get(key); if (animation) { animation.update(deltaTime); if (animation.isComplete) { toRemove.push(key); } } } // Remove completed animations for (let i = 0; i < toRemove.length; i++) { this.animationStates.delete(toRemove[i]); } } /** * Get visible points for rendering (with frustum culling) */ getVisiblePoints(context: RenderContext): Array { const visible: Array = []; const threshold = 0.01; // Minimum amplitude to render for (let i = 0; i < this.points.length; i++) { const point = this.points[i]; // Skip points with negligible amplitude if (point.intensity() < threshold) continue; // Simple frustum culling const screenPos = context.worldToScreen(point.position); if (screenPos.x >= -50 && screenPos.x <= context.width + 50 && screenPos.y >= -50 && screenPos.y <= context.height + 50) { visible.push(point); } } return visible; } /** * Clear the field */ clear(): void { for (let i = 0; i < this.points.length; i++) { const point = this.points[i]; point.amplitude = new Complex(0, 0); point.phase = 0; } this.interferencePattern.clear(); this.animationStates.clear(); } } /** * Holographic field renderer for visualization */ export class HolographicFieldRenderer { field: HolographicField; colorMap: (intensity: f64, phase: f64) => string; constructor(field: HolographicField) { this.field = field; this.colorMap = HolographicFieldRenderer.defaultColorMap; } /** * Default color mapping function */ static defaultColorMap(intensity: f64, phase: f64): string { // Map phase to hue (0-360) const hue = (phase / (2 * Math.PI)) * 360; // Map intensity to lightness (20-80%) const lightness = 20 + intensity * 60; // Full saturation for vivid colors const saturation = 100; return `hsl(${hue}, ${saturation}%, ${lightness}%)`; } /** * Render the field to a 2D context (returns render data) */ render(context: RenderContext): Array { const renderData: Array = []; const visiblePoints = this.field.getVisiblePoints(context); // Sort by z-depth for proper rendering order visiblePoints.sort((a: HolographicPoint, b: HolographicPoint): i32 => { return (b.position.z - a.position.z) > 0 ? 1 : -1; }); for (let i = 0; i < visiblePoints.length; i++) { const point = visiblePoints[i]; const screenPos = context.worldToScreen(point.position); const intensity = point.intensity(); const color = this.colorMap(intensity, point.phase); // Size based on intensity and perspective const baseSize = 5.0; const perspectiveFactor = context.perspective / (context.perspective + point.position.z); const size = baseSize * intensity * perspectiveFactor; renderData.push(new RenderData( screenPos, size, color, intensity, point.phase )); } return renderData; } /** * Render interference pattern overlay */ renderInterferencePattern(context: RenderContext): Array { const renderData: Array = []; const pattern = this.field.interferencePattern; const keys = pattern.keys(); for (let i = 0; i < keys.length; i++) { const key = keys[i]; const parts = key.split(','); const gridX = parseInt(parts[0]); const gridY = parseInt(parts[1]); const amplitude = pattern.get(key)!; const intensity = amplitude.magnitude(); const phase = Math.atan2(amplitude.imag, amplitude.real); // Convert grid position to world coordinates const worldX = (gridX - 5) * this.field.bounds.x / 10; const worldY = (gridY - 5) * this.field.bounds.y / 10; const worldPos = new Coordinate3D(worldX, worldY, 0); const screenPos = context.worldToScreen(worldPos); const color = this.colorMap(intensity, phase); renderData.push(new RenderData( screenPos, 10.0, // Fixed size for pattern color, intensity, phase )); } return renderData; } } /** * Render data structure for visualization */ export class RenderData { position: Coordinate2D; size: f64; color: string; intensity: f64; phase: f64; constructor( position: Coordinate2D, size: f64, color: string, intensity: f64, phase: f64 ) { this.position = position; this.size = size; this.color = color; this.intensity = intensity; this.phase = phase; } }