NGVT / vortex_torus_diagram.html
EvanPi's picture
Add NGVT model card, visualizations, and interactive diagram - 98.33%
467e458
.control-group input[type="checkbox"] {
width: auto;
margin-right: 5px;
}<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NGVT: Vortex Torus - Compatible Version</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<style>
body {
margin: 0;
background: linear-gradient(135deg, #0a0a0a 0%, #1a1a2e 50%, #16213e 100%);
font-family: 'Arial', sans-serif;
overflow: hidden;
color: white;
}
#container {
position: relative;
width: 100vw;
height: 100vh;
}
#info {
position: absolute;
top: 20px;
left: 20px;
z-index: 100;
background: rgba(0, 0, 0, 0.9);
padding: 20px;
border-radius: 10px;
border: 1px solid #00ffff;
box-shadow: 0 0 20px rgba(0, 255, 255, 0.3);
max-width: 280px;
}
#info h1 {
margin: 0 0 10px 0;
color: #00ffff;
font-size: 20px;
text-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
}
#info h2 {
margin: 15px 0 5px 0;
color: #ff6b6b;
font-size: 14px;
}
#info p {
margin: 3px 0;
font-size: 12px;
color: #cccccc;
}
#controls {
position: absolute;
bottom: 20px;
left: 20px;
z-index: 100;
background: rgba(0, 0, 0, 0.9);
padding: 15px;
border-radius: 10px;
border: 1px solid #ff6b6b;
}
.control-group {
margin: 10px 0;
}
.control-group label {
display: block;
color: #ff6b6b;
font-size: 11px;
margin-bottom: 5px;
}
.control-group input {
width: 120px;
}
#legend {
position: absolute;
bottom: 20px;
right: 20px;
z-index: 100;
background: rgba(0, 0, 0, 0.9);
padding: 15px;
border-radius: 10px;
border: 1px solid #4ecdc4;
}
.legend-item {
display: flex;
align-items: center;
margin: 6px 0;
}
.legend-color {
width: 16px;
height: 16px;
margin-right: 8px;
border-radius: 3px;
}
.legend-text {
font-size: 11px;
color: #cccccc;
}
#error-message {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(255, 0, 0, 0.1);
border: 1px solid #ff6b6b;
padding: 20px;
border-radius: 10px;
color: #ff6b6b;
display: none;
text-align: center;
}
#fallback-canvas {
display: none;
border: 1px solid #4ecdc4;
}
</style>
</head>
<body>
<div id="container">
<div id="error-message">
<h3>WebGL Not Available</h3>
<p>Your browser doesn't support WebGL or it's disabled.</p>
<p>Falling back to 2D visualization...</p>
</div>
<div id="info">
<h1>NGVT Vortex Torus</h1>
<p><strong>Directional Flow Visualization</strong></p>
<h2>Torus Parameters:</h2>
<p>Rings: 1-5 concentric</p>
<p>Particles: ON SAME PLANE</p>
<p>Drag to orbit manually</p>
<h2>Code Flow:</h2>
<p>6 colored spiral bands</p>
<p>Tight/loose spiral control</p>
<p>Multi-ring vortex</p>
<h2>Performance:</h2>
<p>SWE-bench: 98.33%</p>
<p>Speed: 7.4× faster</p>
</div>
<div id="controls">
<h3 style="color: #ff6b6b; margin-top: 0; font-size: 14px;">Flow Controls</h3>
<div class="control-group">
<label>Flow Speed:</label>
<input type="range" id="flowSpeed" min="0.1" max="2.0" step="0.1" value="0.8">
</div>
<div class="control-group">
<label>Number of Rings:</label>
<input type="range" id="numberOfRings" min="1" max="5" step="1" value="1">
</div>
<div class="control-group">
<label>Spiral Pitch:</label>
<input type="range" id="spiralPitch" min="0.5" max="4.0" step="0.1" value="2.0">
</div>
<div class="control-group">
<label>Spiral Tightness:</label>
<input type="range" id="spiralTightness" min="2" max="20" step="1" value="8">
</div>
<div class="control-group">
<label>Ring Size:</label>
<input type="range" id="ringSize" min="2.0" max="8.0" step="0.2" value="4.0">
</div>
<div class="control-group">
<label>Zoom Level:</label>
<input type="range" id="zoomLevel" min="5.0" max="30.0" step="1.0" value="15.0">
</div>
<div class="control-group">
<label>Rotation:</label>
<input type="checkbox" id="rotationToggle" checked>
<span style="color: #ff6b6b; font-size: 11px; margin-left: 5px;">Auto Orbit</span>
</div>
<div class="control-group">
<label>Vortex Intensity:</label>
<input type="range" id="vortexIntensity" min="0.1" max="1.5" step="0.1" value="0.8">
</div>
</div>
<div id="legend">
<h3 style="color: #4ecdc4; margin-top: 0; font-size: 14px;">Flow Elements</h3>
<div class="legend-item">
<div class="legend-color" style="background: #00ffff; box-shadow: 0 0 8px #00ffff;"></div>
<div class="legend-text">Functions</div>
</div>
<div class="legend-item">
<div class="legend-color" style="background: #ff6b6b; box-shadow: 0 0 8px #ff6b6b;"></div>
<div class="legend-text">Variables</div>
</div>
<div class="legend-item">
<div class="legend-color" style="background: #4ecdc4; box-shadow: 0 0 8px #4ecdc4;"></div>
<div class="legend-text">Keywords</div>
</div>
<div class="legend-item">
<div class="legend-color" style="background: #ffd93d; box-shadow: 0 0 8px #ffd93d;"></div>
<div class="legend-text">Operators</div>
</div>
<div class="legend-item">
<div class="legend-color" style="background: #a8e6cf; box-shadow: 0 0 8px #a8e6cf;"></div>
<div class="legend-text">Comments</div>
</div>
<div class="legend-item">
<div class="legend-color" style="background: #dda0dd; box-shadow: 0 0 8px #dda0dd;"></div>
<div class="legend-text">Strings</div>
</div>
</div>
<canvas id="fallback-canvas" width="800" height="600"></canvas>
</div>
<script>
// Global variables
let scene, camera, renderer;
let torus, codeSegments = [];
let animationId;
// Control variables
let flowSpeed = 0.8;
let spiralPitch = 2.0;
let ringSize = 4.0;
let vortexIntensity = 0.8;
let zoomLevel = 15.0;
let rotationEnabled = true;
let numberOfRings = 1; // New: multiple rings control
let spiralTightness = 8; // New: corkscrew tightness control
// Mouse drag controls
let isDragging = false;
let previousMousePosition = { x: 0, y: 0 };
let cameraAngleX = 0;
let cameraAngleY = 0;
// Check WebGL support
function isWebGLAvailable() {
try {
const canvas = document.createElement('canvas');
return !!(window.WebGLRenderingContext && (
canvas.getContext('webgl') ||
canvas.getContext('experimental-webgl') ||
canvas.getContext('webgl2')
));
} catch (e) {
return false;
}
}
// Initialize Three.js with error handling
function initThreeJS() {
try {
// Scene setup
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// Renderer with fallback options
const rendererOptions = {
antialias: false, // Disable for compatibility
alpha: true,
powerPreference: "default" // Don't force high-performance
};
renderer = new THREE.WebGLRenderer(rendererOptions);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000, 0);
// Test if renderer actually works
const testGeometry = new THREE.BoxGeometry(1, 1, 1);
const testMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const testMesh = new THREE.Mesh(testGeometry, testMaterial);
scene.add(testMesh);
renderer.render(scene, camera);
scene.remove(testMesh);
document.getElementById('container').appendChild(renderer.domElement);
return true;
} catch (error) {
console.error('Three.js initialization failed:', error);
return false;
}
}
// 2D Canvas fallback
function initFallbackCanvas() {
const canvas = document.getElementById('fallback-canvas');
canvas.style.display = 'block';
canvas.style.position = 'absolute';
canvas.style.top = '50%';
canvas.style.left = '50%';
canvas.style.transform = 'translate(-50%, -50%)';
const ctx = canvas.getContext('2d');
let time = 0;
function drawFallback() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw torus outline
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const outerRadius = ringSize * 30;
const innerRadius = outerRadius * 0.4;
// Outer circle
ctx.strokeStyle = '#4ecdc4';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(centerX, centerY, outerRadius, 0, Math.PI * 2);
ctx.stroke();
// Inner circle (hole)
ctx.beginPath();
ctx.arc(centerX, centerY, innerRadius, 0, Math.PI * 2);
ctx.stroke();
// Draw flowing particles
const colors = ['#00ffff', '#ff6b6b', '#4ecdc4', '#ffd93d', '#a8e6cf', '#dda0dd'];
for (let i = 0; i < 60; i++) {
const angle = (i / 60) * Math.PI * 2 + time * flowSpeed * 0.02;
const spiralAngle = angle * spiralPitch + time * flowSpeed * 0.05;
const radius = innerRadius + (outerRadius - innerRadius) *
(0.5 + 0.4 * Math.sin(spiralAngle));
const x = centerX + radius * Math.cos(angle);
const y = centerY + radius * Math.sin(angle);
const colorIndex = Math.floor(i / 10) % colors.length;
const intensity = 0.5 + 0.5 * Math.sin(spiralAngle + time * 0.01);
ctx.fillStyle = colors[colorIndex];
ctx.globalAlpha = intensity;
ctx.beginPath();
ctx.arc(x, y, 3, 0, Math.PI * 2);
ctx.fill();
}
ctx.globalAlpha = 1;
// Text overlay
ctx.fillStyle = '#00ffff';
ctx.font = '16px Arial';
ctx.fillText('NGVT Vortex Torus (2D Fallback)', 20, 30);
ctx.fillStyle = '#ff6b6b';
ctx.font = '12px Arial';
ctx.fillText('Spiral flow visualization', 20, 50);
time++;
requestAnimationFrame(drawFallback);
}
drawFallback();
}
// Create multiple concentric torus rings and particles
function createSimplifiedVisualization() {
// Clear existing elements
codeSegments.forEach(segment => scene.remove(segment));
codeSegments.length = 0;
// Remove existing torus rings
const torusesToRemove = [];
scene.traverse((child) => {
if (child.userData && child.userData.isTorusRing) {
torusesToRemove.push(child);
}
});
torusesToRemove.forEach(torus => scene.remove(torus));
// Simple lighting
const ambientLight = new THREE.AmbientLight(0x404040, 0.8);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0x00ffff, 0.5);
directionalLight.position.set(0, 5, 5);
scene.add(directionalLight);
// Create multiple concentric torus rings
for (let ringIndex = 0; ringIndex < numberOfRings; ringIndex++) {
const currentRingSize = ringSize - (ringIndex * 1.2); // Smaller rings toward center
if (currentRingSize <= 1.0) break; // Don't create rings that are too small
const torusGeometry = new THREE.TorusGeometry(currentRingSize, 0.6, 8, 32);
const ringHue = (ringIndex * 60) % 360; // Different colors for each ring
const torusMaterial = new THREE.MeshBasicMaterial({
color: new THREE.Color().setHSL(ringHue/360, 0.7, 0.5),
transparent: true,
opacity: 0.2 + (ringIndex * 0.1),
wireframe: true
});
const torusMesh = new THREE.Mesh(torusGeometry, torusMaterial);
torusMesh.userData.isTorusRing = true;
torusMesh.userData.ringIndex = ringIndex;
scene.add(torusMesh);
if (ringIndex === 0) torus = torusMesh; // Keep reference to main torus
}
// Particles for multiple rings
const colors = [0x00ffff, 0xff6b6b, 0x4ecdc4, 0xffd93d, 0xa8e6cf, 0xdda0dd];
const particlesPerRing = 200;
for (let ringIndex = 0; ringIndex < numberOfRings; ringIndex++) {
const currentRingSize = ringSize - (ringIndex * 1.2);
if (currentRingSize <= 1.0) break;
for (let i = 0; i < particlesPerRing; i++) {
const particleGeometry = new THREE.SphereGeometry(0.03 + (ringIndex * 0.01), 6, 6);
const particleMaterial = new THREE.MeshBasicMaterial({
color: colors[(i + ringIndex) % colors.length],
transparent: true,
opacity: 0.8
});
const particle = new THREE.Mesh(particleGeometry, particleMaterial);
// Position particles on ring surface
const spiralIndex = i % 6;
const t = (i / particlesPerRing); // Progress along spiral
const u = t * Math.PI * 2 * spiralTightness + (spiralIndex * Math.PI * 2 / 6);
const v = (spiralIndex * Math.PI * 2 / 6) + (t * Math.PI * 2 * spiralPitch);
const x = (currentRingSize + 0.6 * Math.cos(v)) * Math.cos(u);
const y = (currentRingSize + 0.6 * Math.cos(v)) * Math.sin(u);
const z = 0.6 * Math.sin(v);
particle.position.set(x, y, z);
particle.userData = {
u, v,
originalU: u, originalV: v,
spiralIndex, t,
ringIndex: ringIndex,
ringSize: currentRingSize
};
codeSegments.push(particle);
scene.add(particle);
}
}
// Initial camera position
camera.position.set(0, 8, zoomLevel);
camera.lookAt(0, 0, 0);
}
// Animation loop with multiple rings support
function animate() {
if (!renderer) return;
animationId = requestAnimationFrame(animate);
// Update particles for all rings
const time = Date.now() * 0.001;
codeSegments.forEach((particle, index) => {
const data = particle.userData;
// Move along spiral path with ring-specific speeds
const ringSpeedMultiplier = 1.0 + (data.ringIndex * 0.3);
data.t += flowSpeed * 0.008 * ringSpeedMultiplier;
if (data.t > 1) data.t = 0;
// Calculate spiral position with tightness control
const u = (data.t * spiralTightness * Math.PI * 2) + (data.spiralIndex * Math.PI * 2 / 6);
const baseV = (data.spiralIndex * Math.PI * 2 / 6);
const vVariation = Math.sin(data.t * Math.PI * 2 * spiralPitch) * 0.3;
const v = baseV + vVariation;
// Position on respective ring surface
const x = (data.ringSize + 0.6 * Math.cos(v)) * Math.cos(u);
const y = (data.ringSize + 0.6 * Math.cos(v)) * Math.sin(u);
const z = 0.6 * Math.sin(v);
particle.position.set(x, y, z);
// Visual effects
const flowPosition = Math.abs(Math.cos(v));
particle.material.opacity = 0.6 + 0.4 * flowPosition;
const distanceFromCenter = Math.sqrt(x*x + y*y);
const scaleByDistance = 0.7 + 0.5 * (distanceFromCenter / data.ringSize);
particle.scale.setScalar(scaleByDistance);
});
// Rotate torus rings
scene.traverse((child) => {
if (child.userData && child.userData.isTorusRing) {
child.rotation.z += 0.001 * (child.userData.ringIndex + 1);
}
});
// Camera control - auto orbit or mouse drag
if (rotationEnabled) {
const autoAngle = time * 0.05;
cameraAngleY = autoAngle;
cameraAngleX = 0.3; // Slight downward angle
}
// Apply camera position based on angles
const x = Math.cos(cameraAngleY) * Math.cos(cameraAngleX) * zoomLevel;
const y = Math.sin(cameraAngleX) * zoomLevel + 8;
const z = Math.sin(cameraAngleY) * Math.cos(cameraAngleX) * zoomLevel;
camera.position.set(x, y, z);
camera.lookAt(0, 0, 0);
try {
renderer.render(scene, camera);
} catch (error) {
console.error('Render error:', error);
showError();
}
}
// Show error message and fallback
function showError() {
document.getElementById('error-message').style.display = 'block';
if (animationId) {
cancelAnimationFrame(animationId);
}
setTimeout(() => {
document.getElementById('error-message').style.display = 'none';
initFallbackCanvas();
}, 3000);
}
// Control event listeners
function setupControls() {
document.getElementById('flowSpeed').addEventListener('input', (e) => {
flowSpeed = parseFloat(e.target.value);
});
document.getElementById('numberOfRings').addEventListener('input', (e) => {
numberOfRings = parseInt(e.target.value);
createSimplifiedVisualization();
});
document.getElementById('spiralTightness').addEventListener('input', (e) => {
spiralTightness = parseInt(e.target.value);
});
document.getElementById('spiralPitch').addEventListener('input', (e) => {
spiralPitch = parseFloat(e.target.value);
});
document.getElementById('ringSize').addEventListener('input', (e) => {
ringSize = parseFloat(e.target.value);
createSimplifiedVisualization(); // Recreate all rings with new size
});
document.getElementById('zoomLevel').addEventListener('input', (e) => {
zoomLevel = parseFloat(e.target.value);
});
document.getElementById('rotationToggle').addEventListener('change', (e) => {
rotationEnabled = e.target.checked;
});
document.getElementById('vortexIntensity').addEventListener('input', (e) => {
vortexIntensity = parseFloat(e.target.value);
});
}
// Mouse drag controls for camera
function onMouseDown(event) {
if (event.button === 0) { // Left mouse button
isDragging = true;
previousMousePosition.x = event.clientX;
previousMousePosition.y = event.clientY;
rotationEnabled = false; // Disable auto rotation when dragging
document.getElementById('rotationToggle').checked = false;
}
}
function onMouseMove(event) {
if (isDragging) {
const deltaX = event.clientX - previousMousePosition.x;
const deltaY = event.clientY - previousMousePosition.y;
// Update camera angles based on mouse movement
cameraAngleY += deltaX * 0.01;
cameraAngleX += deltaY * 0.01;
// Clamp vertical angle to prevent flipping
cameraAngleX = Math.max(-Math.PI/2, Math.min(Math.PI/2, cameraAngleX));
previousMousePosition.x = event.clientX;
previousMousePosition.y = event.clientY;
}
}
function onMouseUp(event) {
isDragging = false;
}
// Touch controls for mobile
function onTouchStart(event) {
if (event.touches.length === 1) {
isDragging = true;
previousMousePosition.x = event.touches[0].clientX;
previousMousePosition.y = event.touches[0].clientY;
rotationEnabled = false;
document.getElementById('rotationToggle').checked = false;
event.preventDefault();
}
}
function onTouchMove(event) {
if (isDragging && event.touches.length === 1) {
const deltaX = event.touches[0].clientX - previousMousePosition.x;
const deltaY = event.touches[0].clientY - previousMousePosition.y;
cameraAngleY += deltaX * 0.01;
cameraAngleX += deltaY * 0.01;
cameraAngleX = Math.max(-Math.PI/2, Math.min(Math.PI/2, cameraAngleX));
previousMousePosition.x = event.touches[0].clientX;
previousMousePosition.y = event.touches[0].clientY;
event.preventDefault();
}
}
function onTouchEnd(event) {
isDragging = false;
}
// Handle mouse wheel zoom
function onMouseWheel(event) {
event.preventDefault();
const zoomDelta = event.deltaY > 0 ? 1 : -1;
zoomLevel = Math.max(5, Math.min(30, zoomLevel + zoomDelta));
// Update the slider to reflect the change
const zoomSlider = document.getElementById('zoomLevel');
if (zoomSlider) {
zoomSlider.value = zoomLevel;
}
}
// Window resize handler
function onWindowResize() {
if (camera && renderer) {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
}
// Initialize everything
function init() {
setupControls();
if (!isWebGLAvailable()) {
showError();
return;
}
if (initThreeJS()) {
createSimplifiedVisualization();
animate();
window.addEventListener('resize', onWindowResize);
window.addEventListener('wheel', onMouseWheel, { passive: false });
// Mouse drag controls
renderer.domElement.addEventListener('mousedown', onMouseDown);
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
// Touch controls
renderer.domElement.addEventListener('touchstart', onTouchStart);
window.addEventListener('touchmove', onTouchMove);
window.addEventListener('touchend', onTouchEnd);
} else {
showError();
}
}
// Start when page loads
window.addEventListener('load', init);
// Error handling
window.addEventListener('error', (event) => {
console.error('Global error:', event.error);
showError();
});
</script>
</body>
</html>