UNPKG

@sschepis/resolang

Version:

ResoLang - Core quantum resonance computation library for browser and Node.js

602 lines (520 loc) 16.1 kB
// visualization/memory-fragments.ts // Implements memory fragment visualization and management import { Complex, Prime } from "../types"; import { Quaternion } from "../quaternion"; import { Coordinate2D, Coordinate3D, MemoryFragmentVisualization, AnimationState, RenderContext } from "./types"; import { NetworkNodeVisual } from "./network-node"; import { TeleportationOperation } from "./quantum-operations"; /** * Memory fragment states */ export enum FragmentState { IDLE = "idle", ACTIVE = "active", TELEPORTING = "teleporting", ENTANGLED = "entangled", COLLAPSED = "collapsed" } /** * Extended memory fragment with full visualization capabilities */ export class MemoryFragment extends MemoryFragmentVisualization { state: FragmentState; attachedNodeId: string | null; velocity: Coordinate3D; rotationQuaternion: Quaternion; rotationSpeed: f64; glowIntensity: f64; trailPositions: Array<Coordinate3D>; maxTrailLength: i32; constructor( id: string, content: string, position: Coordinate3D, holographicData: Map<Prime, Complex> ) { super(id, content, position, holographicData); this.state = FragmentState.IDLE; this.attachedNodeId = null; this.velocity = new Coordinate3D(0, 0, 0); this.rotationQuaternion = new Quaternion(1, 0, 0, 0); this.rotationSpeed = 0.5; this.glowIntensity = 0.5; this.trailPositions = []; this.maxTrailLength = 20; } /** * Attach fragment to a node */ attachToNode(nodeId: string, node: NetworkNodeVisual): void { this.attachedNodeId = nodeId; this.state = FragmentState.ACTIVE; // Orbit around node const orbitRadius = node.state.size * 2; const angle = Math.random() * 2 * Math.PI; const offsetX = Math.cos(angle) * orbitRadius; const offsetY = Math.sin(angle) * orbitRadius; this.position = new Coordinate3D( node.state.position.x + offsetX, node.state.position.y + offsetY, node.state.position.z ); } /** * Detach from node */ detach(): void { this.attachedNodeId = null; this.state = FragmentState.IDLE; // Add some random velocity when detached this.velocity = new Coordinate3D( (Math.random() - 0.5) * 10, (Math.random() - 0.5) * 10, (Math.random() - 0.5) * 5 ); } /** * Update fragment physics and animation */ update(deltaTime: f64, nodes: Map<string, NetworkNodeVisual>): void { // Store previous position for trail if (this.trailPositions.length >= this.maxTrailLength) { this.trailPositions.shift(); } this.trailPositions.push(new Coordinate3D( this.position.x, this.position.y, this.position.z )); // Update based on state switch (this.state) { case FragmentState.IDLE: this.updateIdle(deltaTime); break; case FragmentState.ACTIVE: this.updateActive(deltaTime, nodes); break; case FragmentState.TELEPORTING: this.updateTeleporting(deltaTime); break; case FragmentState.ENTANGLED: this.updateEntangled(deltaTime); break; case FragmentState.COLLAPSED: this.updateCollapsed(deltaTime); break; } // Update rotation const angle = this.rotationSpeed * deltaTime * 0.001; const rotationDelta = new Quaternion( Math.cos(angle / 2), 0, Math.sin(angle / 2), 0 ); this.rotationQuaternion = this.rotationQuaternion.multiply(rotationDelta).normalize(); // Update glow based on state const targetGlow = this.state === FragmentState.ACTIVE ? 1.0 : 0.5; this.glowIntensity += (targetGlow - this.glowIntensity) * 0.1; } /** * Update idle state */ private updateIdle(deltaTime: f64): void { // Apply velocity with damping this.position.x += this.velocity.x * deltaTime * 0.001; this.position.y += this.velocity.y * deltaTime * 0.001; this.position.z += this.velocity.z * deltaTime * 0.001; // Damping this.velocity.x *= 0.98; this.velocity.y *= 0.98; this.velocity.z *= 0.98; // Gentle floating motion const time = deltaTime * 0.001; this.position.y += Math.sin(time) * 0.1; } /** * Update active state (attached to node) */ private updateActive(deltaTime: f64, nodes: Map<string, NetworkNodeVisual>): void { if (!this.attachedNodeId) { this.state = FragmentState.IDLE; return; } const node = nodes.get(this.attachedNodeId); if (!node) { this.detach(); return; } // Orbit around node const time = Date.now() * 0.001; const orbitRadius = node.state.size * 2; const orbitSpeed = 0.5 + this.glowIntensity * 0.5; const angle = time * orbitSpeed; const targetX = node.state.position.x + Math.cos(angle) * orbitRadius; const targetY = node.state.position.y + Math.sin(angle) * orbitRadius; const targetZ = node.state.position.z + Math.sin(angle * 0.5) * 10; // Smooth movement to target this.position.x += (targetX - this.position.x) * 0.1; this.position.y += (targetY - this.position.y) * 0.1; this.position.z += (targetZ - this.position.z) * 0.1; // Increase rotation speed when active this.rotationSpeed = 1.0 + node.state.entanglementStrength; } /** * Update teleporting state */ private updateTeleporting(deltaTime: f64): void { // Handled by TeleportationOperation this.opacity = 0.5 + Math.sin(Date.now() * 0.01) * 0.3; this.scale = 0.8 + Math.sin(Date.now() * 0.02) * 0.2; } /** * Update entangled state */ private updateEntangled(deltaTime: f64): void { // Quantum fluctuations this.position.x += (Math.random() - 0.5) * 0.5; this.position.y += (Math.random() - 0.5) * 0.5; this.position.z += (Math.random() - 0.5) * 0.5; // Pulsing glow this.glowIntensity = 0.7 + Math.sin(Date.now() * 0.005) * 0.3; } /** * Update collapsed state */ private updateCollapsed(deltaTime: f64): void { this.opacity *= 0.95; this.scale *= 0.98; if (this.opacity < 0.01) { this.state = FragmentState.IDLE; this.opacity = 1.0; this.scale = 1.0; } } /** * Start teleportation */ startTeleportation(): void { this.state = FragmentState.TELEPORTING; this.isTeleported = true; } /** * Complete teleportation */ completeTeleportation(newPosition: Coordinate3D): void { this.position = newPosition; this.state = FragmentState.IDLE; this.isTeleported = false; // Flash effect this.glowIntensity = 2.0; } /** * Apply entanglement */ applyEntanglement(partner: MemoryFragment): void { this.state = FragmentState.ENTANGLED; this.isNonLocal = true; // Synchronize some properties const avgGlow = (this.glowIntensity + partner.glowIntensity) / 2; this.glowIntensity = avgGlow; partner.glowIntensity = avgGlow; } /** * Collapse wave function */ collapse(): void { this.state = FragmentState.COLLAPSED; this.applyQuantumEffect("collapse", 1000); } /** * Get render data */ getRenderData(context: RenderContext): FragmentRenderData { const screenPos = context.worldToScreen(this.position); // Apply rotation to get oriented bounding box const size = 20 * this.scale; const corners = [ new Coordinate3D(-size/2, -size/2, 0), new Coordinate3D(size/2, -size/2, 0), new Coordinate3D(size/2, size/2, 0), new Coordinate3D(-size/2, size/2, 0) ]; const rotatedCorners: Array<Coordinate2D> = []; for (let i = 0; i < corners.length; i++) { const rotated = corners[i].rotate(this.rotationQuaternion); const projected = new Coordinate3D( this.position.x + rotated.x, this.position.y + rotated.y, this.position.z + rotated.z ).projectTo2D(context.perspective); rotatedCorners.push(projected); } // Trail data const trail: Array<Coordinate2D> = []; for (let i = 0; i < this.trailPositions.length; i++) { trail.push(context.worldToScreen(this.trailPositions[i])); } return new FragmentRenderData( this.id, screenPos, rotatedCorners, this.opacity, this.glowIntensity, this.state, trail, this.calculateHolographicPattern() ); } /** * Calculate holographic interference pattern */ private calculateHolographicPattern(): Array<HolographicPatternPoint> { const pattern: Array<HolographicPatternPoint> = []; const center = this.calculateCenterOfMass(); // Sample points around the fragment const samples = 8; for (let i = 0; i < samples; i++) { const angle = (i / samples as f64) * 2 * Math.PI; const radius = 30; const x = center.x + Math.cos(angle) * radius; const y = center.y + Math.sin(angle) * radius; // Calculate interference at this point let totalAmplitude = new Complex(0, 0); const keys = this.holographicData.keys(); for (let j = 0; j < keys.length; j++) { const prime = keys[j]; const amplitude = this.holographicData.get(prime)!; const phase = (prime as f64) * 0.1 + angle; totalAmplitude = totalAmplitude.add( amplitude.multiply(Complex.fromPolar(1.0, phase)) ); } pattern.push(new HolographicPatternPoint( new Coordinate2D(x, y), totalAmplitude.magnitude(), Math.atan2(totalAmplitude.imag, totalAmplitude.real) )); } return pattern; } } /** * Memory fragment manager */ export class MemoryFragmentManager { fragments: Map<string, MemoryFragment>; nextFragmentId: i32; maxFragments: i32; constructor(maxFragments: i32 = 100) { this.fragments = new Map<string, MemoryFragment>(); this.nextFragmentId = 1; this.maxFragments = maxFragments; } /** * Create a new memory fragment */ createFragment( content: string, position: Coordinate3D, primes: Array<Prime> ): MemoryFragment { const id = `fragment_${this.nextFragmentId++}`; // Generate holographic data from primes const holographicData = new Map<Prime, Complex>(); for (let i = 0; i < primes.length; i++) { const prime = primes[i]; const amplitude = 1.0 / (1.0 + i); const phase = (prime as f64) * 0.1; holographicData.set(prime, Complex.fromPolar(amplitude, phase)); } const fragment = new MemoryFragment(id, content, position, holographicData); this.fragments.set(id, fragment); // Remove oldest if over limit if (this.fragments.size > this.maxFragments) { const keys = this.fragments.keys(); this.fragments.delete(keys[0]); } return fragment; } /** * Remove a fragment */ removeFragment(id: string): void { this.fragments.delete(id); } /** * Get fragment by ID */ getFragment(id: string): MemoryFragment | null { return this.fragments.get(id) || null; } /** * Find fragments near a position */ findFragmentsNear(position: Coordinate3D, radius: f64): Array<MemoryFragment> { const nearby: Array<MemoryFragment> = []; const fragmentIds = this.fragments.keys(); for (let i = 0; i < fragmentIds.length; i++) { const fragment = this.fragments.get(fragmentIds[i])!; if (fragment.position.distanceTo3D(position) <= radius) { nearby.push(fragment); } } return nearby; } /** * Update all fragments */ update(deltaTime: f64, nodes: Map<string, NetworkNodeVisual>): void { const fragmentIds = this.fragments.keys(); for (let i = 0; i < fragmentIds.length; i++) { const fragment = this.fragments.get(fragmentIds[i])!; fragment.update(deltaTime, nodes); } } /** * Get render data for all fragments */ getRenderData(context: RenderContext): Array<FragmentRenderData> { const renderData: Array<FragmentRenderData> = []; const fragmentIds = this.fragments.keys(); // Sort by z-depth for proper rendering const sortedFragments: Array<MemoryFragment> = []; for (let i = 0; i < fragmentIds.length; i++) { sortedFragments.push(this.fragments.get(fragmentIds[i])!); } sortedFragments.sort((a: MemoryFragment, b: MemoryFragment): i32 => { return (b.position.z - a.position.z) > 0 ? 1 : -1; }); for (let i = 0; i < sortedFragments.length; i++) { renderData.push(sortedFragments[i].getRenderData(context)); } return renderData; } /** * Clear all fragments */ clear(): void { this.fragments.clear(); } } /** * Fragment render data */ export class FragmentRenderData { id: string; position: Coordinate2D; corners: Array<Coordinate2D>; opacity: f64; glowIntensity: f64; state: FragmentState; trail: Array<Coordinate2D>; holographicPattern: Array<HolographicPatternPoint>; constructor( id: string, position: Coordinate2D, corners: Array<Coordinate2D>, opacity: f64, glowIntensity: f64, state: FragmentState, trail: Array<Coordinate2D>, holographicPattern: Array<HolographicPatternPoint> ) { this.id = id; this.position = position; this.corners = corners; this.opacity = opacity; this.glowIntensity = glowIntensity; this.state = state; this.trail = trail; this.holographicPattern = holographicPattern; } } /** * Holographic pattern point */ export class HolographicPatternPoint { position: Coordinate2D; intensity: f64; phase: f64; constructor(position: Coordinate2D, intensity: f64, phase: f64) { this.position = position; this.intensity = intensity; this.phase = phase; } } /** * Memory fragment interactions */ export class FragmentInteractionHandler { manager: MemoryFragmentManager; selectedFragment: string | null; dragOffset: Coordinate2D | null; constructor(manager: MemoryFragmentManager) { this.manager = manager; this.selectedFragment = null; this.dragOffset = null; } /** * Handle mouse down */ handleMouseDown(screenPos: Coordinate2D, context: RenderContext): boolean { const fragment = this.findFragmentAt(screenPos, context); if (fragment) { this.selectedFragment = fragment.id; const fragmentScreen = context.worldToScreen(fragment.position); this.dragOffset = new Coordinate2D( screenPos.x - fragmentScreen.x, screenPos.y - fragmentScreen.y ); return true; } return false; } /** * Handle mouse move */ handleMouseMove(screenPos: Coordinate2D, context: RenderContext): void { if (this.selectedFragment && this.dragOffset) { const fragment = this.manager.getFragment(this.selectedFragment); if (fragment) { // Convert screen position to world position const worldPos = context.screenToWorld2D(new Coordinate2D( screenPos.x - this.dragOffset.x, screenPos.y - this.dragOffset.y )); fragment.position.x = worldPos.x; fragment.position.y = worldPos.y; } } } /** * Handle mouse up */ handleMouseUp(): void { this.selectedFragment = null; this.dragOffset = null; } /** * Find fragment at screen position */ private findFragmentAt(screenPos: Coordinate2D, context: RenderContext): MemoryFragment | null { const fragmentIds = this.manager.fragments.keys(); for (let i = 0; i < fragmentIds.length; i++) { const fragment = this.manager.fragments.get(fragmentIds[i])!; const fragmentScreen = context.worldToScreen(fragment.position); const distance = screenPos.distanceTo(fragmentScreen); if (distance < 20 * fragment.scale) { return fragment; } } return null; } }