Skip to content
LAM
Read Home Blog
Make Projects HTML Tools Games
Touch grass Notes Resume Links
Home Blog HTML Projects
Tools Games Notes Resume Links
Back Interactive Mathematics Visualizer Math
Download Open
Show description 2,057 chars · Math

Interactive Mathematics Visualizer

Interactive Mathematics Visualizer





























Welcome

Calculus

Multivariable

Diff Equations

Linear Algebra

Discrete Math

Probability

Numerical

Complex

Graph Theory

Number Theory

Algorithms

Cryptography

Optimization









Interactive Mathematics Visualizer

Explore mathematical concepts through interactive 2D and 3D visualizations




📈

Dynamic Graphs

Visualize functions, derivatives, and integrals in real-time




🎯

3D Surfaces

Explore multivariable functions and vector fields in 3D space




🔐

Interactive Algorithms

Watch sorting algorithms, graph traversals, and encryption in action




🎲

Probability Simulations

Run Monte Carlo simulations and visualize distributions




🌀

Complex Analysis

Navigate the complex plane with conformal mappings




🔢

Number Patterns

Discover prime spirals and modular arithmetic patterns














Function Explorer




sin(x)
cos(x)
e^x
x³ - 3x
Show Derivative
Show Integral
Animate Tangent







f(x) = sin(x)

Explore functions, their derivatives, and integrals. Watch how the tangent line changes as it moves along the curve.








Riemann Sums





Rectangles:

10


Toggle Type















3D Surface Explorer




Saddle Point
Paraboloid
Wave Function
Show Gradient
Show Contours








z = x² - y²

Rotate with mouse, scroll to zoom. Visualize gradients and level curves on 3D surfaces.








Vector Field Visualization




Rotation Field
Radial Field
Spiral Field
Animate Particles















Phase Portrait




Pendulum
Predator-Prey
Van der Pol
Add Trajectory
Clear







Click on the phase plane to start trajectories. Watch how different initial conditions evolve over time.












Matrix Transformations




Rotation
Scale
Shear
Reflection
Show Eigenvectors
Reset







A = [1 0; 0 1]

Watch how matrices transform the plane.…

Interactive Mathematics Visualizer

77,295 bytes · HTML source
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Interactive Mathematics Visualizer</title>
    
    <!-- Three.js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    
    <!-- Chart.js for some visualizations -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    
    <!-- Math.js for calculations -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/11.11.0/math.min.js"></script>
    
    <!-- D3.js for graph visualizations -->
    <script src="https://d3js.org/d3.v7.min.js"></script>
    
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: #0a0a0a;
            color: #ffffff;
            overflow-x: hidden;
            position: relative;
        }
        
        /* Animated background */
        #particles-bg {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
        }
        
        /* Navigation */
        .nav-container {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            background: rgba(0, 0, 0, 0.9);
            backdrop-filter: blur(10px);
            z-index: 1000;
            padding: 10px 0;
            border-bottom: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .nav-scroll {
            display: flex;
            gap: 15px;
            padding: 0 20px;
            overflow-x: auto;
            scrollbar-width: thin;
            scrollbar-color: #444 transparent;
        }
        
        .nav-item {
            flex-shrink: 0;
            padding: 10px 20px;
            background: rgba(255, 255, 255, 0.1);
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 25px;
            cursor: pointer;
            transition: all 0.3s ease;
            font-size: 14px;
            position: relative;
            overflow: hidden;
        }
        
        .nav-item:before {
            content: '';
            position: absolute;
            top: 50%;
            left: 50%;
            width: 0;
            height: 0;
            background: radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%);
            transform: translate(-50%, -50%);
            transition: width 0.3s, height 0.3s;
        }
        
        .nav-item:hover:before {
            width: 100%;
            height: 100%;
        }
        
        .nav-item:hover {
            background: rgba(255, 255, 255, 0.2);
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(255, 255, 255, 0.1);
        }
        
        .nav-item.active {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-color: transparent;
        }
        
        /* Main container */
        .main-container {
            margin-top: 80px;
            min-height: calc(100vh - 80px);
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 20px;
        }
        
        /* Section containers */
        .section {
            display: none;
            width: 100%;
            max-width: 1400px;
            animation: fadeIn 0.5s ease;
        }
        
        .section.active {
            display: block;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(20px); }
            to { opacity: 1; transform: translateY(0); }
        }
        
        /* Visualization containers */
        .viz-container {
            background: rgba(255, 255, 255, 0.05);
            border: 1px solid rgba(255, 255, 255, 0.1);
            border-radius: 20px;
            padding: 30px;
            margin-bottom: 20px;
            position: relative;
            overflow: hidden;
        }
        
        .viz-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        
        .viz-title {
            font-size: 24px;
            font-weight: 600;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        
        .controls {
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
            margin: 20px 0;
        }
        
        .control-btn {
            padding: 8px 16px;
            background: rgba(255, 255, 255, 0.1);
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 20px;
            color: white;
            cursor: pointer;
            transition: all 0.3s ease;
            font-size: 14px;
        }
        
        .control-btn:hover {
            background: rgba(255, 255, 255, 0.2);
            transform: translateY(-2px);
        }
        
        .control-slider {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 8px 16px;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 20px;
        }
        
        .control-slider input[type="range"] {
            width: 150px;
            height: 4px;
            background: rgba(255, 255, 255, 0.2);
            border-radius: 2px;
            outline: none;
            -webkit-appearance: none;
        }
        
        .control-slider input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 16px;
            height: 16px;
            background: #667eea;
            border-radius: 50%;
            cursor: pointer;
        }
        
        /* Canvas styles */
        .canvas-container {
            width: 100%;
            height: 500px;
            border-radius: 10px;
            overflow: hidden;
            position: relative;
            background: rgba(0, 0, 0, 0.3);
        }
        
        canvas {
            display: block;
            width: 100% !important;
            height: 100% !important;
        }
        
        /* Info panels */
        .info-panel {
            background: rgba(0, 0, 0, 0.5);
            border: 1px solid rgba(255, 255, 255, 0.1);
            border-radius: 10px;
            padding: 20px;
            margin-top: 20px;
            font-size: 14px;
            line-height: 1.6;
        }
        
        .formula-display {
            background: rgba(255, 255, 255, 0.05);
            border: 1px solid rgba(255, 255, 255, 0.1);
            border-radius: 8px;
            padding: 15px;
            margin: 10px 0;
            font-family: 'Courier New', monospace;
            text-align: center;
            font-size: 18px;
        }
        
        /* Welcome screen */
        .welcome-section {
            text-align: center;
            padding: 60px 20px;
        }
        
        .welcome-title {
            font-size: 48px;
            font-weight: 700;
            margin-bottom: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        
        .welcome-subtitle {
            font-size: 20px;
            color: rgba(255, 255, 255, 0.7);
            margin-bottom: 40px;
        }
        
        .feature-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 20px;
            margin-top: 40px;
        }
        
        .feature-card {
            background: rgba(255, 255, 255, 0.05);
            border: 1px solid rgba(255, 255, 255, 0.1);
            border-radius: 15px;
            padding: 30px;
            transition: all 0.3s ease;
        }
        
        .feature-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3);
            border-color: rgba(102, 126, 234, 0.5);
        }
        
        .feature-icon {
            font-size: 48px;
            margin-bottom: 15px;
        }
        
        .feature-title {
            font-size: 20px;
            font-weight: 600;
            margin-bottom: 10px;
        }
        
        .feature-desc {
            color: rgba(255, 255, 255, 0.7);
            font-size: 14px;
        }
        
        /* Responsive */
        @media (max-width: 768px) {
            .canvas-container {
                height: 400px;
            }
            
            .welcome-title {
                font-size: 36px;
            }
            
            .feature-grid {
                grid-template-columns: 1fr;
            }
        }
        
        /* Loading animation */
        .loader {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            display: none;
        }
        
        .loader.active {
            display: block;
        }
        
        .loader-circle {
            width: 60px;
            height: 60px;
            border: 3px solid rgba(255, 255, 255, 0.1);
            border-top-color: #667eea;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }
        
        @keyframes spin {
            to { transform: rotate(360deg); }
        }
        
        /* Tooltip styles */
        .tooltip {
            position: absolute;
            background: rgba(0, 0, 0, 0.9);
            color: white;
            padding: 10px 15px;
            border-radius: 8px;
            font-size: 14px;
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.3s;
            z-index: 1000;
            border: 1px solid rgba(255, 255, 255, 0.2);
        }
        
        .tooltip.show {
            opacity: 1;
        }
    </style>
</head>
<body>
    <canvas id="particles-bg"></canvas>
    
    <div class="loader" id="loader">
        <div class="loader-circle"></div>
    </div>
    
    <div class="tooltip" id="tooltip"></div>
    
    <nav class="nav-container">
        <div class="nav-scroll">
            <div class="nav-item active" data-section="welcome">Welcome</div>
            <div class="nav-item" data-section="calculus">Calculus</div>
            <div class="nav-item" data-section="calc3">Multivariable</div>
            <div class="nav-item" data-section="diffeq">Diff Equations</div>
            <div class="nav-item" data-section="linear">Linear Algebra</div>
            <div class="nav-item" data-section="discrete">Discrete Math</div>
            <div class="nav-item" data-section="probability">Probability</div>
            <div class="nav-item" data-section="numerical">Numerical</div>
            <div class="nav-item" data-section="complex">Complex</div>
            <div class="nav-item" data-section="graph">Graph Theory</div>
            <div class="nav-item" data-section="number">Number Theory</div>
            <div class="nav-item" data-section="algorithms">Algorithms</div>
            <div class="nav-item" data-section="crypto">Cryptography</div>
            <div class="nav-item" data-section="optimization">Optimization</div>
        </div>
    </nav>
    
    <div class="main-container">
        <!-- Welcome Section -->
        <section id="welcome" class="section active">
            <div class="welcome-section">
                <h1 class="welcome-title">Interactive Mathematics Visualizer</h1>
                <p class="welcome-subtitle">Explore mathematical concepts through interactive 2D and 3D visualizations</p>
                
                <div class="feature-grid">
                    <div class="feature-card">
                        <div class="feature-icon">📈</div>
                        <h3 class="feature-title">Dynamic Graphs</h3>
                        <p class="feature-desc">Visualize functions, derivatives, and integrals in real-time</p>
                    </div>
                    <div class="feature-card">
                        <div class="feature-icon">🎯</div>
                        <h3 class="feature-title">3D Surfaces</h3>
                        <p class="feature-desc">Explore multivariable functions and vector fields in 3D space</p>
                    </div>
                    <div class="feature-card">
                        <div class="feature-icon">🔐</div>
                        <h3 class="feature-title">Interactive Algorithms</h3>
                        <p class="feature-desc">Watch sorting algorithms, graph traversals, and encryption in action</p>
                    </div>
                    <div class="feature-card">
                        <div class="feature-icon">🎲</div>
                        <h3 class="feature-title">Probability Simulations</h3>
                        <p class="feature-desc">Run Monte Carlo simulations and visualize distributions</p>
                    </div>
                    <div class="feature-card">
                        <div class="feature-icon">🌀</div>
                        <h3 class="feature-title">Complex Analysis</h3>
                        <p class="feature-desc">Navigate the complex plane with conformal mappings</p>
                    </div>
                    <div class="feature-card">
                        <div class="feature-icon">🔢</div>
                        <h3 class="feature-title">Number Patterns</h3>
                        <p class="feature-desc">Discover prime spirals and modular arithmetic patterns</p>
                    </div>
                </div>
            </div>
        </section>
        
        <!-- Calculus Section -->
        <section id="calculus" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Function Explorer</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="calcViz.changeFunction('sin')">sin(x)</button>
                    <button class="control-btn" onclick="calcViz.changeFunction('cos')">cos(x)</button>
                    <button class="control-btn" onclick="calcViz.changeFunction('exp')">e^x</button>
                    <button class="control-btn" onclick="calcViz.changeFunction('poly')">x³ - 3x</button>
                    <button class="control-btn" onclick="calcViz.toggleDerivative()">Show Derivative</button>
                    <button class="control-btn" onclick="calcViz.toggleIntegral()">Show Integral</button>
                    <button class="control-btn" onclick="calcViz.animateTangent()">Animate Tangent</button>
                </div>
                <div class="canvas-container">
                    <canvas id="calcCanvas"></canvas>
                </div>
                <div class="info-panel">
                    <div class="formula-display" id="calcFormula">f(x) = sin(x)</div>
                    <p>Explore functions, their derivatives, and integrals. Watch how the tangent line changes as it moves along the curve.</p>
                </div>
            </div>
            
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Riemann Sums</h2>
                </div>
                <div class="controls">
                    <div class="control-slider">
                        <label>Rectangles:</label>
                        <input type="range" id="riemannSlider" min="1" max="50" value="10">
                        <span id="riemannCount">10</span>
                    </div>
                    <button class="control-btn" onclick="calcViz.toggleRiemannType()">Toggle Type</button>
                </div>
                <div class="canvas-container">
                    <canvas id="riemannCanvas"></canvas>
                </div>
            </div>
        </section>
        
        <!-- Multivariable Calculus Section -->
        <section id="calc3" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">3D Surface Explorer</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="calc3Viz.changeSurface('saddle')">Saddle Point</button>
                    <button class="control-btn" onclick="calc3Viz.changeSurface('paraboloid')">Paraboloid</button>
                    <button class="control-btn" onclick="calc3Viz.changeSurface('waves')">Wave Function</button>
                    <button class="control-btn" onclick="calc3Viz.toggleGradient()">Show Gradient</button>
                    <button class="control-btn" onclick="calc3Viz.toggleContours()">Show Contours</button>
                </div>
                <div class="canvas-container">
                    <div id="surface3D"></div>
                </div>
                <div class="info-panel">
                    <div class="formula-display" id="surfaceFormula">z = x² - y²</div>
                    <p>Rotate with mouse, scroll to zoom. Visualize gradients and level curves on 3D surfaces.</p>
                </div>
            </div>
            
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Vector Field Visualization</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="calc3Viz.changeField('rotation')">Rotation Field</button>
                    <button class="control-btn" onclick="calc3Viz.changeField('radial')">Radial Field</button>
                    <button class="control-btn" onclick="calc3Viz.changeField('spiral')">Spiral Field</button>
                    <button class="control-btn" onclick="calc3Viz.animateParticles()">Animate Particles</button>
                </div>
                <div class="canvas-container">
                    <canvas id="vectorFieldCanvas"></canvas>
                </div>
            </div>
        </section>
        
        <!-- Differential Equations Section -->
        <section id="diffeq" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Phase Portrait</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="diffeqViz.changeSystem('pendulum')">Pendulum</button>
                    <button class="control-btn" onclick="diffeqViz.changeSystem('predatorPrey')">Predator-Prey</button>
                    <button class="control-btn" onclick="diffeqViz.changeSystem('vanDerPol')">Van der Pol</button>
                    <button class="control-btn" onclick="diffeqViz.addTrajectory()">Add Trajectory</button>
                    <button class="control-btn" onclick="diffeqViz.clear()">Clear</button>
                </div>
                <div class="canvas-container">
                    <canvas id="phaseCanvas"></canvas>
                </div>
                <div class="info-panel">
                    <p>Click on the phase plane to start trajectories. Watch how different initial conditions evolve over time.</p>
                </div>
            </div>
        </section>
        
        <!-- Linear Algebra Section -->
        <section id="linear" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Matrix Transformations</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="linearViz.applyRotation()">Rotation</button>
                    <button class="control-btn" onclick="linearViz.applyScale()">Scale</button>
                    <button class="control-btn" onclick="linearViz.applyShear()">Shear</button>
                    <button class="control-btn" onclick="linearViz.applyReflection()">Reflection</button>
                    <button class="control-btn" onclick="linearViz.showEigenvectors()">Show Eigenvectors</button>
                    <button class="control-btn" onclick="linearViz.reset()">Reset</button>
                </div>
                <div class="canvas-container">
                    <canvas id="matrixCanvas"></canvas>
                </div>
                <div class="info-panel">
                    <div class="formula-display" id="matrixDisplay">A = [1 0; 0 1]</div>
                    <p>Watch how matrices transform the plane. Eigenvectors remain in the same direction after transformation.</p>
                </div>
            </div>
            
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">3D Vector Operations</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="linearViz.showCrossProduct()">Cross Product</button>
                    <button class="control-btn" onclick="linearViz.showProjection()">Projection</button>
                    <button class="control-btn" onclick="linearViz.showSpan()">Linear Span</button>
                </div>
                <div class="canvas-container">
                    <div id="vector3D"></div>
                </div>
            </div>
        </section>
        
        <!-- Discrete Mathematics Section -->
        <section id="discrete" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Set Operations Visualizer</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="discreteViz.showUnion()">Union</button>
                    <button class="control-btn" onclick="discreteViz.showIntersection()">Intersection</button>
                    <button class="control-btn" onclick="discreteViz.showComplement()">Complement</button>
                    <button class="control-btn" onclick="discreteViz.showDifference()">Difference</button>
                    <button class="control-btn" onclick="discreteViz.showPowerSet()">Power Set</button>
                </div>
                <div class="canvas-container">
                    <canvas id="setCanvas"></canvas>
                </div>
            </div>
            
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Combinatorics Explorer</h2>
                </div>
                <div class="controls">
                    <div class="control-slider">
                        <label>n:</label>
                        <input type="range" id="nSlider" min="1" max="10" value="5">
                        <span id="nValue">5</span>
                    </div>
                    <div class="control-slider">
                        <label>r:</label>
                        <input type="range" id="rSlider" min="1" max="10" value="3">
                        <span id="rValue">3</span>
                    </div>
                    <button class="control-btn" onclick="discreteViz.showPermutations()">Permutations</button>
                    <button class="control-btn" onclick="discreteViz.showCombinations()">Combinations</button>
                </div>
                <div class="canvas-container">
                    <div id="combinatoricsDisplay"></div>
                </div>
            </div>
        </section>
        
        <!-- Probability Section -->
        <section id="probability" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Distribution Explorer</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="probViz.showNormal()">Normal</button>
                    <button class="control-btn" onclick="probViz.showBinomial()">Binomial</button>
                    <button class="control-btn" onclick="probViz.showPoisson()">Poisson</button>
                    <button class="control-btn" onclick="probViz.showExponential()">Exponential</button>
                    <button class="control-btn" onclick="probViz.generateSamples()">Generate Samples</button>
                </div>
                <div class="canvas-container">
                    <canvas id="distCanvas"></canvas>
                </div>
                <div class="info-panel">
                    <div class="formula-display" id="distFormula">Normal Distribution: μ = 0, σ = 1</div>
                </div>
            </div>
            
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Central Limit Theorem</h2>
                </div>
                <div class="controls">
                    <div class="control-slider">
                        <label>Sample Size:</label>
                        <input type="range" id="sampleSize" min="1" max="100" value="30">
                        <span id="sampleSizeValue">30</span>
                    </div>
                    <button class="control-btn" onclick="probViz.runCLT()">Run Simulation</button>
                    <button class="control-btn" onclick="probViz.resetCLT()">Reset</button>
                </div>
                <div class="canvas-container">
                    <canvas id="cltCanvas"></canvas>
                </div>
            </div>
        </section>
        
        <!-- Numerical Analysis Section -->
        <section id="numerical" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Root Finding Methods</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="numericalViz.runBisection()">Bisection</button>
                    <button class="control-btn" onclick="numericalViz.runNewton()">Newton's Method</button>
                    <button class="control-btn" onclick="numericalViz.runSecant()">Secant Method</button>
                    <button class="control-btn" onclick="numericalViz.reset()">Reset</button>
                </div>
                <div class="canvas-container">
                    <canvas id="rootCanvas"></canvas>
                </div>
                <div class="info-panel">
                    <p>Watch different root-finding algorithms converge to the solution. Compare their convergence rates.</p>
                </div>
            </div>
        </section>
        
        <!-- Complex Analysis Section -->
        <section id="complex" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Complex Function Visualizer</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="complexViz.showFunction('z2')">z²</button>
                    <button class="control-btn" onclick="complexViz.showFunction('exp')">e^z</button>
                    <button class="control-btn" onclick="complexViz.showFunction('log')">log(z)</button>
                    <button class="control-btn" onclick="complexViz.showFunction('sin')">sin(z)</button>
                    <button class="control-btn" onclick="complexViz.toggleGrid()">Toggle Grid</button>
                </div>
                <div class="canvas-container">
                    <canvas id="complexCanvas"></canvas>
                </div>
                <div class="info-panel">
                    <p>Visualize complex functions using domain coloring. See how they transform the complex plane.</p>
                </div>
            </div>
        </section>
        
        <!-- Graph Theory Section -->
        <section id="graph" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Interactive Graph Editor</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="graphViz.addVertex()">Add Vertex</button>
                    <button class="control-btn" onclick="graphViz.addEdgeMode()">Add Edge</button>
                    <button class="control-btn" onclick="graphViz.runDijkstra()">Dijkstra's</button>
                    <button class="control-btn" onclick="graphViz.runDFS()">DFS</button>
                    <button class="control-btn" onclick="graphViz.runBFS()">BFS</button>
                    <button class="control-btn" onclick="graphViz.findMST()">MST</button>
                    <button class="control-btn" onclick="graphViz.clear()">Clear</button>
                </div>
                <div class="canvas-container">
                    <div id="graphCanvas"></div>
                </div>
                <div class="info-panel">
                    <p>Build graphs interactively and run various algorithms. Click to add vertices, drag to move them.</p>
                </div>
            </div>
        </section>
        
        <!-- Number Theory Section -->
        <section id="number" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Prime Spiral (Ulam Spiral)</h2>
                </div>
                <div class="controls">
                    <div class="control-slider">
                        <label>Size:</label>
                        <input type="range" id="spiralSize" min="50" max="500" value="200">
                        <span id="spiralSizeValue">200</span>
                    </div>
                    <button class="control-btn" onclick="numberViz.highlightTwins()">Twin Primes</button>
                    <button class="control-btn" onclick="numberViz.highlightMersenne()">Mersenne</button>
                </div>
                <div class="canvas-container">
                    <canvas id="primeCanvas"></canvas>
                </div>
            </div>
            
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Modular Arithmetic Clock</h2>
                </div>
                <div class="controls">
                    <div class="control-slider">
                        <label>Modulus:</label>
                        <input type="range" id="modulus" min="2" max="24" value="12">
                        <span id="modulusValue">12</span>
                    </div>
                    <button class="control-btn" onclick="numberViz.showMultiplication()">Multiplication</button>
                    <button class="control-btn" onclick="numberViz.showPowers()">Powers</button>
                </div>
                <div class="canvas-container">
                    <canvas id="modularCanvas"></canvas>
                </div>
            </div>
        </section>
        
        <!-- Algorithms Section -->
        <section id="algorithms" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Sorting Algorithm Visualizer</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="algoViz.runBubbleSort()">Bubble Sort</button>
                    <button class="control-btn" onclick="algoViz.runQuickSort()">Quick Sort</button>
                    <button class="control-btn" onclick="algoViz.runMergeSort()">Merge Sort</button>
                    <button class="control-btn" onclick="algoViz.runHeapSort()">Heap Sort</button>
                    <button class="control-btn" onclick="algoViz.shuffle()">Shuffle</button>
                    <div class="control-slider">
                        <label>Speed:</label>
                        <input type="range" id="sortSpeed" min="1" max="100" value="50">
                    </div>
                </div>
                <div class="canvas-container">
                    <canvas id="sortCanvas"></canvas>
                </div>
                <div class="info-panel">
                    <p id="sortInfo">Comparisons: 0 | Swaps: 0 | Time: O(n²)</p>
                </div>
            </div>
        </section>
        
        <!-- Cryptography Section -->
        <section id="crypto" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">RSA Encryption Demo</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="cryptoViz.generateKeys()">Generate Keys</button>
                    <button class="control-btn" onclick="cryptoViz.encrypt()">Encrypt</button>
                    <button class="control-btn" onclick="cryptoViz.decrypt()">Decrypt</button>
                </div>
                <div class="canvas-container" style="height: auto; padding: 20px;">
                    <div id="cryptoDisplay">
                        <input type="text" id="messageInput" placeholder="Enter message" style="width: 100%; padding: 10px; margin: 10px 0; background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2); color: white; border-radius: 5px;">
                        <div class="formula-display" id="publicKey">Public Key: (n, e)</div>
                        <div class="formula-display" id="privateKey">Private Key: (n, d)</div>
                        <div class="formula-display" id="encryptedMsg">Encrypted: </div>
                        <div class="formula-display" id="decryptedMsg">Decrypted: </div>
                    </div>
                </div>
            </div>
            
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Diffie-Hellman Key Exchange</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="cryptoViz.runDiffieHellman()">Run Exchange</button>
                </div>
                <div class="canvas-container">
                    <canvas id="dhCanvas"></canvas>
                </div>
            </div>
        </section>
        
        <!-- Optimization Section -->
        <section id="optimization" class="section">
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Gradient Descent Visualization</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="optViz.runGradientDescent()">Run Gradient Descent</button>
                    <button class="control-btn" onclick="optViz.runNewton()">Newton's Method</button>
                    <button class="control-btn" onclick="optViz.changeFunction()">Change Function</button>
                    <div class="control-slider">
                        <label>Learning Rate:</label>
                        <input type="range" id="learningRate" min="0.01" max="1" step="0.01" value="0.1">
                        <span id="lrValue">0.1</span>
                    </div>
                </div>
                <div class="canvas-container">
                    <div id="optCanvas"></div>
                </div>
            </div>
            
            <div class="viz-container">
                <div class="viz-header">
                    <h2 class="viz-title">Linear Programming</h2>
                </div>
                <div class="controls">
                    <button class="control-btn" onclick="optViz.addConstraint()">Add Constraint</button>
                    <button class="control-btn" onclick="optViz.solveSimplex()">Solve (Simplex)</button>
                    <button class="control-btn" onclick="optViz.clear()">Clear</button>
                </div>
                <div class="canvas-container">
                    <canvas id="lpCanvas"></canvas>
                </div>
            </div>
        </section>
    </div>
    
    <script>
        // Particle background
        const particlesCanvas = document.getElementById('particles-bg');
        const particlesCtx = particlesCanvas.getContext('2d');
        let particles = [];
        
        function resizeCanvas() {
            particlesCanvas.width = window.innerWidth;
            particlesCanvas.height = window.innerHeight;
        }
        
        class Particle {
            constructor() {
                this.x = Math.random() * particlesCanvas.width;
                this.y = Math.random() * particlesCanvas.height;
                this.vx = (Math.random() - 0.5) * 0.5;
                this.vy = (Math.random() - 0.5) * 0.5;
                this.radius = Math.random() * 2 + 1;
                this.opacity = Math.random() * 0.5 + 0.2;
            }
            
            update() {
                this.x += this.vx;
                this.y += this.vy;
                
                if (this.x < 0 || this.x > particlesCanvas.width) this.vx *= -1;
                if (this.y < 0 || this.y > particlesCanvas.height) this.vy *= -1;
            }
            
            draw() {
                particlesCtx.fillStyle = `rgba(102, 126, 234, ${this.opacity})`;
                particlesCtx.beginPath();
                particlesCtx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
                particlesCtx.fill();
            }
        }
        
        function initParticles() {
            particles = [];
            for (let i = 0; i < 100; i++) {
                particles.push(new Particle());
            }
        }
        
        function animateParticles() {
            particlesCtx.clearRect(0, 0, particlesCanvas.width, particlesCanvas.height);
            
            particles.forEach(particle => {
                particle.update();
                particle.draw();
            });
            
            // Draw connections
            for (let i = 0; i < particles.length; i++) {
                for (let j = i + 1; j < particles.length; j++) {
                    const dx = particles[i].x - particles[j].x;
                    const dy = particles[i].y - particles[j].y;
                    const distance = Math.sqrt(dx * dx + dy * dy);
                    
                    if (distance < 100) {
                        particlesCtx.strokeStyle = `rgba(102, 126, 234, ${0.2 * (1 - distance / 100)})`;
                        particlesCtx.lineWidth = 1;
                        particlesCtx.beginPath();
                        particlesCtx.moveTo(particles[i].x, particles[i].y);
                        particlesCtx.lineTo(particles[j].x, particles[j].y);
                        particlesCtx.stroke();
                    }
                }
            }
            
            requestAnimationFrame(animateParticles);
        }
        
        // Navigation
        const navItems = document.querySelectorAll('.nav-item');
        const sections = document.querySelectorAll('.section');
        
        navItems.forEach(item => {
            item.addEventListener('click', () => {
                const targetSection = item.dataset.section;
                
                navItems.forEach(nav => nav.classList.remove('active'));
                sections.forEach(section => section.classList.remove('active'));
                
                item.classList.add('active');
                document.getElementById(targetSection).classList.add('active');
                
                // Initialize section-specific visualizations
                initializeSection(targetSection);
            });
        });
        
        // Initialize visualizations for each section
        let calcViz, calc3Viz, diffeqViz, linearViz, discreteViz, probViz, 
            numericalViz, complexViz, graphViz, numberViz, algoViz, cryptoViz, optViz;
        
        function initializeSection(section) {
            switch(section) {
                case 'calculus':
                    if (!calcViz) initCalculusViz();
                    break;
                case 'calc3':
                    if (!calc3Viz) initCalc3Viz();
                    break;
                case 'diffeq':
                    if (!diffeqViz) initDiffeqViz();
                    break;
                case 'linear':
                    if (!linearViz) initLinearViz();
                    break;
                case 'discrete':
                    if (!discreteViz) initDiscreteViz();
                    break;
                case 'probability':
                    if (!probViz) initProbViz();
                    break;
                case 'numerical':
                    if (!numericalViz) initNumericalViz();
                    break;
                case 'complex':
                    if (!complexViz) initComplexViz();
                    break;
                case 'graph':
                    if (!graphViz) initGraphViz();
                    break;
                case 'number':
                    if (!numberViz) initNumberViz();
                    break;
                case 'algorithms':
                    if (!algoViz) initAlgoViz();
                    break;
                case 'crypto':
                    if (!cryptoViz) initCryptoViz();
                    break;
                case 'optimization':
                    if (!optViz) initOptViz();
                    break;
            }
        }
        
        // Calculus Visualizations
        function initCalculusViz() {
            const canvas = document.getElementById('calcCanvas');
            const ctx = canvas.getContext('2d');
            const riemannCanvas = document.getElementById('riemannCanvas');
            const riemannCtx = riemannCanvas.getContext('2d');
            
            function resizeCalcCanvas() {
                canvas.width = canvas.offsetWidth;
                canvas.height = canvas.offsetHeight;
                riemannCanvas.width = riemannCanvas.offsetWidth;
                riemannCanvas.height = riemannCanvas.offsetHeight;
            }
            resizeCalcCanvas();
            
            calcViz = {
                currentFunction: 'sin',
                showDerivative: false,
                showIntegral: false,
                animatingTangent: false,
                tangentX: -Math.PI,
                
                functions: {
                    sin: {
                        f: x => Math.sin(x),
                        df: x => Math.cos(x),
                        F: x => -Math.cos(x),
                        name: 'f(x) = sin(x)',
                        dname: "f'(x) = cos(x)",
                        Fname: 'F(x) = -cos(x) + C'
                    },
                    cos: {
                        f: x => Math.cos(x),
                        df: x => -Math.sin(x),
                        F: x => Math.sin(x),
                        name: 'f(x) = cos(x)',
                        dname: "f'(x) = -sin(x)",
                        Fname: 'F(x) = sin(x) + C'
                    },
                    exp: {
                        f: x => Math.exp(x/2),
                        df: x => 0.5 * Math.exp(x/2),
                        F: x => 2 * Math.exp(x/2),
                        name: 'f(x) = e^(x/2)',
                        dname: "f'(x) = 0.5e^(x/2)",
                        Fname: 'F(x) = 2e^(x/2) + C'
                    },
                    poly: {
                        f: x => x*x*x/3 - x,
                        df: x => x*x - 1,
                        F: x => x*x*x*x/12 - x*x/2,
                        name: 'f(x) = x³/3 - x',
                        dname: "f'(x) = x² - 1",
                        Fname: 'F(x) = x⁴/12 - x²/2 + C'
                    }
                },
                
                changeFunction(func) {
                    this.currentFunction = func;
                    this.draw();
                    document.getElementById('calcFormula').textContent = this.functions[func].name;
                },
                
                toggleDerivative() {
                    this.showDerivative = !this.showDerivative;
                    this.draw();
                },
                
                toggleIntegral() {
                    this.showIntegral = !this.showIntegral;
                    this.draw();
                },
                
                animateTangent() {
                    this.animatingTangent = !this.animatingTangent;
                    if (this.animatingTangent) {
                        this.tangentAnimation();
                    }
                },
                
                tangentAnimation() {
                    if (!this.animatingTangent) return;
                    
                    this.tangentX += 0.05;
                    if (this.tangentX > Math.PI) this.tangentX = -Math.PI;
                    
                    this.draw();
                    requestAnimationFrame(() => this.tangentAnimation());
                },
                
                draw() {
                    const width = canvas.width;
                    const height = canvas.height;
                    const centerX = width / 2;
                    const centerY = height / 2;
                    const scale = 50;
                    
                    ctx.clearRect(0, 0, width, height);
                    
                    // Grid
                    ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
                    ctx.lineWidth = 1;
                    for (let x = 0; x < width; x += scale) {
                        ctx.beginPath();
                        ctx.moveTo(x, 0);
                        ctx.lineTo(x, height);
                        ctx.stroke();
                    }
                    for (let y = 0; y < height; y += scale) {
                        ctx.beginPath();
                        ctx.moveTo(0, y);
                        ctx.lineTo(width, y);
                        ctx.stroke();
                    }
                    
                    // Axes
                    ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
                    ctx.lineWidth = 2;
                    ctx.beginPath();
                    ctx.moveTo(0, centerY);
                    ctx.lineTo(width, centerY);
                    ctx.moveTo(centerX, 0);
                    ctx.lineTo(centerX, height);
                    ctx.stroke();
                    
                    const func = this.functions[this.currentFunction];
                    
                    // Function
                    ctx.strokeStyle = '#667eea';
                    ctx.lineWidth = 3;
                    ctx.beginPath();
                    for (let px = 0; px < width; px++) {
                        const x = (px - centerX) / scale;
                        const y = func.f(x);
                        const py = centerY - y * scale;
                        
                        if (px === 0) ctx.moveTo(px, py);
                        else ctx.lineTo(px, py);
                    }
                    ctx.stroke();
                    
                    // Derivative
                    if (this.showDerivative) {
                        ctx.strokeStyle = '#ff6b6b';
                        ctx.lineWidth = 2;
                        ctx.beginPath();
                        for (let px = 0; px < width; px++) {
                            const x = (px - centerX) / scale;
                            const y = func.df(x);
                            const py = centerY - y * scale;
                            
                            if (px === 0) ctx.moveTo(px, py);
                            else ctx.lineTo(px, py);
                        }
                        ctx.stroke();
                    }
                    
                    // Integral
                    if (this.showIntegral) {
                        ctx.strokeStyle = '#4ecdc4';
                        ctx.lineWidth = 2;
                        ctx.beginPath();
                        for (let px = 0; px < width; px++) {
                            const x = (px - centerX) / scale;
                            const y = func.F(x);
                            const py = centerY - y * scale;
                            
                            if (px === 0) ctx.moveTo(px, py);
                            else ctx.lineTo(px, py);
                        }
                        ctx.stroke();
                    }
                    
                    // Tangent line
                    if (this.animatingTangent) {
                        const x0 = this.tangentX;
                        const y0 = func.f(x0);
                        const slope = func.df(x0);
                        
                        // Point
                        ctx.fillStyle = '#ffd93d';
                        ctx.beginPath();
                        ctx.arc(centerX + x0 * scale, centerY - y0 * scale, 5, 0, Math.PI * 2);
                        ctx.fill();
                        
                        // Tangent line
                        ctx.strokeStyle = '#ffd93d';
                        ctx.lineWidth = 2;
                        ctx.beginPath();
                        const dx = 2;
                        ctx.moveTo(centerX + (x0 - dx) * scale, centerY - (y0 + slope * (-dx)) * scale);
                        ctx.lineTo(centerX + (x0 + dx) * scale, centerY - (y0 + slope * dx) * scale);
                        ctx.stroke();
                    }
                },
                
                // Riemann sums
                riemannType: 'left',
                rectangles: 10,
                
                toggleRiemannType() {
                    const types = ['left', 'right', 'midpoint'];
                    const currentIndex = types.indexOf(this.riemannType);
                    this.riemannType = types[(currentIndex + 1) % types.length];
                    this.drawRiemann();
                },
                
                drawRiemann() {
                    const width = riemannCanvas.width;
                    const height = riemannCanvas.height;
                    const centerX = width / 2;
                    const centerY = height / 2;
                    const scale = 50;
                    
                    riemannCtx.clearRect(0, 0, width, height);
                    
                    // Grid and axes
                    riemannCtx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
                    riemannCtx.lineWidth = 1;
                    for (let x = 0; x < width; x += scale) {
                        riemannCtx.beginPath();
                        riemannCtx.moveTo(x, 0);
                        riemannCtx.lineTo(x, height);
                        riemannCtx.stroke();
                    }
                    for (let y = 0; y < height; y += scale) {
                        riemannCtx.beginPath();
                        riemannCtx.moveTo(0, y);
                        riemannCtx.lineTo(width, y);
                        riemannCtx.stroke();
                    }
                    
                    riemannCtx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
                    riemannCtx.lineWidth = 2;
                    riemannCtx.beginPath();
                    riemannCtx.moveTo(0, centerY);
                    riemannCtx.lineTo(width, centerY);
                    riemannCtx.moveTo(centerX, 0);
                    riemannCtx.lineTo(centerX, height);
                    riemannCtx.stroke();
                    
                    const func = this.functions[this.currentFunction];
                    const a = -2;
                    const b = 2;
                    const n = this.rectangles;
                    const dx = (b - a) / n;
                    
                    // Draw rectangles
                    let sum = 0;
                    for (let i = 0; i < n; i++) {
                        const x = a + i * dx;
                        let rectX, rectHeight;
                        
                        if (this.riemannType === 'left') {
                            rectX = x;
                            rectHeight = func.f(x);
                        } else if (this.riemannType === 'right') {
                            rectX = x;
                            rectHeight = func.f(x + dx);
                        } else {
                            rectX = x;
                            rectHeight = func.f(x + dx/2);
                        }
                        
                        sum += rectHeight * dx;
                        
                        const px = centerX + rectX * scale;
                        const py = centerY - rectHeight * scale;
                        const pwidth = dx * scale;
                        const pheight = Math.abs(rectHeight * scale);
                        
                        riemannCtx.fillStyle = 'rgba(102, 126, 234, 0.3)';
                        riemannCtx.strokeStyle = 'rgba(102, 126, 234, 0.8)';
                        riemannCtx.lineWidth = 1;
                        
                        if (rectHeight >= 0) {
                            riemannCtx.fillRect(px, py, pwidth, pheight);
                            riemannCtx.strokeRect(px, py, pwidth, pheight);
                        } else {
                            riemannCtx.fillRect(px, centerY, pwidth, pheight);
                            riemannCtx.strokeRect(px, centerY, pwidth, pheight);
                        }
                    }
                    
                    // Draw function
                    riemannCtx.strokeStyle = '#667eea';
                    riemannCtx.lineWidth = 3;
                    riemannCtx.beginPath();
                    for (let px = 0; px < width; px++) {
                        const x = (px - centerX) / scale;
                        const y = func.f(x);
                        const py = centerY - y * scale;
                        
                        if (px === 0) riemannCtx.moveTo(px, py);
                        else riemannCtx.lineTo(px, py);
                    }
                    riemannCtx.stroke();
                    
                    // Display sum
                    riemannCtx.fillStyle = 'white';
                    riemannCtx.font = '16px monospace';
                    riemannCtx.fillText(`Approximate area: ${sum.toFixed(4)}`, 10, 30);
                    riemannCtx.fillText(`Type: ${this.riemannType}`, 10, 50);
                }
            };
            
            // Initialize sliders
            const riemannSlider = document.getElementById('riemannSlider');
            const riemannCount = document.getElementById('riemannCount');
            
            riemannSlider.addEventListener('input', (e) => {
                calcViz.rectangles = parseInt(e.target.value);
                riemannCount.textContent = e.target.value;
                calcViz.drawRiemann();
            });
            
            // Initial draw
            calcViz.draw();
            calcViz.drawRiemann();
        }
        
        // Multivariable Calculus Visualizations
        function initCalc3Viz() {
            const container = document.getElementById('surface3D');
            const vectorCanvas = document.getElementById('vectorFieldCanvas');
            const vectorCtx = vectorCanvas.getContext('2d');
            
            // Three.js setup for 3D surface
            const scene = new THREE.Scene();
            const camera = new THREE.PerspectiveCamera(75, container.offsetWidth / container.offsetHeight, 0.1, 1000);
            const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
            renderer.setSize(container.offsetWidth, container.offsetHeight);
            container.appendChild(renderer.domElement);
            
            camera.position.set(3, 3, 3);
            camera.lookAt(0, 0, 0);
            
            // Controls
            let mouseX = 0, mouseY = 0;
            let isMouseDown = false;
            
            container.addEventListener('mousedown', () => isMouseDown = true);
            container.addEventListener('mouseup', () => isMouseDown = false);
            container.addEventListener('mousemove', (e) => {
                if (isMouseDown) {
                    mouseX = (e.clientX / window.innerWidth) * 2 - 1;
                    mouseY = -(e.clientY / window.innerHeight) * 2 + 1;
                }
            });
            
            calc3Viz = {
                currentSurface: 'saddle',
                showGradient: false,
                showContours: false,
                
                surfaces: {
                    saddle: {
                        f: (x, y) => x * x - y * y,
                        name: 'z = x² - y²'
                    },
                    paraboloid: {
                        f: (x, y) => x * x + y * y,
                        name: 'z = x² + y²'
                    },
                    waves: {
                        f: (x, y) => Math.sin(x * 2) * Math.cos(y * 2) * 0.5,
                        name: 'z = 0.5 sin(2x) cos(2y)'
                    }
                },
                
                changeSurface(surf) {
                    this.currentSurface = surf;
                    this.updateSurface();
                    document.getElementById('surfaceFormula').textContent = this.surfaces[surf].name;
                },
                
                updateSurface() {
                    // Clear scene
                    while(scene.children.length > 0) {
                        scene.remove(scene.children[0]);
                    }
                    
                    // Add lights
                    const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
                    scene.add(ambientLight);
                    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.4);
                    directionalLight.position.set(5, 5, 5);
                    scene.add(directionalLight);
                    
                    // Create surface
                    const geometry = new THREE.ParametricGeometry((u, v, target) => {
                        const x = (u - 0.5) * 4;
                        const y = (v - 0.5) * 4;
                        const z = this.surfaces[this.currentSurface].f(x, y);
                        target.set(x, z, y);
                    }, 50, 50);
                    
                    const material = new THREE.MeshPhongMaterial({
                        color: 0x667eea,
                        side: THREE.DoubleSide,
                        wireframe: false,
                        transparent: true,
                        opacity: 0.8
                    });
                    
                    const mesh = new THREE.Mesh(geometry, material);
                    scene.add(mesh);
                    
                    // Add axes
                    const axesHelper = new THREE.AxesHelper(3);
                    scene.add(axesHelper);
                    
                    // Add grid
                    const gridHelper = new THREE.GridHelper(4, 10, 0x444444, 0x222222);
                    gridHelper.rotation.x = Math.PI / 2;
                    scene.add(gridHelper);
                },
                
                toggleGradient() {
                    this.showGradient = !this.showGradient;
                    // Implementation for gradient vectors
                },
                
                toggleContours() {
                    this.showContours = !this.showContours;
                    // Implementation for contour lines
                },
                
                // Vector field
                currentField: 'rotation',
                particles: [],
                
                fields: {
                    rotation: {
                        vx: (x, y) => -y,
                        vy: (x, y) => x
                    },
                    radial: {
                        vx: (x, y) => x,
                        vy: (x, y) => y
                    },
                    spiral: {
                        vx: (x, y) => -y + x * 0.1,
                        vy: (x, y) => x + y * 0.1
                    }
                },
                
                changeField(field) {
                    this.currentField = field;
                    this.drawVectorField();
                },
                
                drawVectorField() {
                    const width = vectorCanvas.width = vectorCanvas.offsetWidth;
                    const height = vectorCanvas.height = vectorCanvas.offsetHeight;
                    const centerX = width / 2;
                    const centerY = height / 2;
                    const scale = 30;
                    
                    vectorCtx.clearRect(0, 0, width, height);
                    
                    // Grid
                    vectorCtx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
                    vectorCtx.lineWidth = 1;
                    for (let x = 0; x < width; x += scale) {
                        vectorCtx.beginPath();
                        vectorCtx.moveTo(x, 0);
                        vectorCtx.lineTo(x, height);
                        vectorCtx.stroke();
                    }
                    for (let y = 0; y < height; y += scale) {
                        vectorCtx.beginPath();
                        vectorCtx.moveTo(0, y);
                        vectorCtx.lineTo(width, y);
                        vectorCtx.stroke();
                    }
                    
                    // Draw vectors
                    const field = this.fields[this.currentField];
                    const spacing = 30;
                    
                    for (let px = spacing/2; px < width; px += spacing) {
                        for (let py = spacing/2; py < height; py += spacing) {
                            const x = (px - centerX) / scale;
                            const y = -(py - centerY) / scale;
                            
                            const vx = field.vx(x, y);
                            const vy = field.vy(x, y);
                            const mag = Math.sqrt(vx * vx + vy * vy);
                            
                            if (mag > 0) {
                                const nvx = vx / mag * 15;
                                const nvy = vy / mag * 15;
                                
                                vectorCtx.strokeStyle = `hsl(${mag * 60 + 200}, 70%, 60%)`;
                                vectorCtx.lineWidth = 2;
                                vectorCtx.beginPath();
                                vectorCtx.moveTo(px, py);
                                vectorCtx.lineTo(px + nvx, py - nvy);
                                vectorCtx.stroke();
                                
                                // Arrowhead
                                const angle = Math.atan2(-nvy, nvx);
                                vectorCtx.save();
                                vectorCtx.translate(px + nvx, py - nvy);
                                vectorCtx.rotate(angle);
                                vectorCtx.beginPath();
                                vectorCtx.moveTo(0, 0);
                                vectorCtx.lineTo(-5, -3);
                                vectorCtx.lineTo(-5, 3);
                                vectorCtx.closePath();
                                vectorCtx.fillStyle = vectorCtx.strokeStyle;
                                vectorCtx.fill();
                                vectorCtx.restore();
                            }
                        }
                    }
                    
                    // Draw particles
                    this.particles.forEach(particle => {
                        vectorCtx.fillStyle = '#ffd93d';
                        vectorCtx.beginPath();
                        vectorCtx.arc(particle.px, particle.py, 3, 0, Math.PI * 2);
                        vectorCtx.fill();
                    });
                },
                
                animateParticles() {
                    // Add random particles
                    for (let i = 0; i < 20; i++) {
                        this.particles.push({
                            px: Math.random() * vectorCanvas.width,
                            py: Math.random() * vectorCanvas.height,
                            trail: []
                        });
                    }
                    
                    this.particleAnimation();
                },
                
                particleAnimation() {
                    const width = vectorCanvas.width;
                    const height = vectorCanvas.height;
                    const centerX = width / 2;
                    const centerY = height / 2;
                    const scale = 30;
                    const field = this.fields[this.currentField];
                    
                    // Update particles
                    this.particles = this.particles.filter(particle => {
                        const x = (particle.px - centerX) / scale;
                        const y = -(particle.py - centerY) / scale;
                        
                        const vx = field.vx(x, y);
                        const vy = field.vy(x, y);
                        
                        particle.px += vx * 2;
                        particle.py -= vy * 2;
                        
                        particle.trail.push({ x: particle.px, y: particle.py });
                        if (particle.trail.length > 20) particle.trail.shift();
                        
                        return particle.px >= 0 && particle.px <= width && 
                               particle.py >= 0 && particle.py <= height;
                    });
                    
                    this.drawVectorField();
                    
                    // Draw trails
                    this.particles.forEach(particle => {
                        vectorCtx.strokeStyle = 'rgba(255, 217, 61, 0.5)';
                        vectorCtx.lineWidth = 2;
                        vectorCtx.beginPath();
                        particle.trail.forEach((point, i) => {
                            if (i === 0) vectorCtx.moveTo(point.x, point.y);
                            else vectorCtx.lineTo(point.x, point.y);
                        });
                        vectorCtx.stroke();
                    });
                    
                    if (this.particles.length > 0) {
                        requestAnimationFrame(() => this.particleAnimation());
                    }
                }
            };
            
            // Animation loop for 3D
            function animate3D() {
                requestAnimationFrame(animate3D);
                
                // Rotate camera
                if (isMouseDown) {
                    camera.position.x = Math.cos(mouseX * Math.PI) * 5;
                    camera.position.z = Math.sin(mouseX * Math.PI) * 5;
                    camera.position.y = 3 + mouseY * 2;
                    camera.lookAt(0, 0, 0);
                }
                
                renderer.render(scene, camera);
            }
            
            calc3Viz.updateSurface();
            calc3Viz.drawVectorField();
            animate3D();
        }
        
        // Initialize remaining visualizations with placeholder implementations
        function initDiffeqViz() {
            const canvas = document.getElementById('phaseCanvas');
            const ctx = canvas.getContext('2d');
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
            
            diffeqViz = {
                changeSystem() { console.log('Changing system'); },
                addTrajectory() { console.log('Adding trajectory'); },
                clear() { ctx.clearRect(0, 0, canvas.width, canvas.height); }
            };
        }
        
        function initLinearViz() {
            const canvas = document.getElementById('matrixCanvas');
            const ctx = canvas.getContext('2d');
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
            
            linearViz = {
                applyRotation() { console.log('Applying rotation'); },
                applyScale() { console.log('Applying scale'); },
                applyShear() { console.log('Applying shear'); },
                applyReflection() { console.log('Applying reflection'); },
                showEigenvectors() { console.log('Showing eigenvectors'); },
                reset() { ctx.clearRect(0, 0, canvas.width, canvas.height); }
            };
        }
        
        function initDiscreteViz() {
            const canvas = document.getElementById('setCanvas');
            const ctx = canvas.getContext('2d');
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
            
            discreteViz = {
                showUnion() { console.log('Showing union'); },
                showIntersection() { console.log('Showing intersection'); },
                showComplement() { console.log('Showing complement'); },
                showDifference() { console.log('Showing difference'); },
                showPowerSet() { console.log('Showing power set'); },
                showPermutations() { console.log('Showing permutations'); },
                showCombinations() { console.log('Showing combinations'); }
            };
        }
        
        function initProbViz() {
            const canvas = document.getElementById('distCanvas');
            const ctx = canvas.getContext('2d');
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
            
            probViz = {
                showNormal() { console.log('Showing normal distribution'); },
                showBinomial() { console.log('Showing binomial distribution'); },
                showPoisson() { console.log('Showing Poisson distribution'); },
                showExponential() { console.log('Showing exponential distribution'); },
                generateSamples() { console.log('Generating samples'); },
                runCLT() { console.log('Running CLT simulation'); },
                resetCLT() { console.log('Resetting CLT'); }
            };
        }
        
        function initNumericalViz() {
            const canvas = document.getElementById('rootCanvas');
            const ctx = canvas.getContext('2d');
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
            
            numericalViz = {
                runBisection() { console.log('Running bisection'); },
                runNewton() { console.log('Running Newton method'); },
                runSecant() { console.log('Running secant method'); },
                reset() { ctx.clearRect(0, 0, canvas.width, canvas.height); }
            };
        }
        
        function initComplexViz() {
            const canvas = document.getElementById('complexCanvas');
            const ctx = canvas.getContext('2d');
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
            
            complexViz = {
                showFunction() { console.log('Showing complex function'); },
                toggleGrid() { console.log('Toggling grid'); }
            };
        }
        
        function initGraphViz() {
            const container = document.getElementById('graphCanvas');
            container.innerHTML = '<svg width="100%" height="100%"></svg>';
            
            graphViz = {
                addVertex() { console.log('Adding vertex'); },
                addEdgeMode() { console.log('Edge mode'); },
                runDijkstra() { console.log('Running Dijkstra'); },
                runDFS() { console.log('Running DFS'); },
                runBFS() { console.log('Running BFS'); },
                findMST() { console.log('Finding MST'); },
                clear() { console.log('Clearing graph'); }
            };
        }
        
        function initNumberViz() {
            const canvas = document.getElementById('primeCanvas');
            const ctx = canvas.getContext('2d');
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
            
            numberViz = {
                highlightTwins() { console.log('Highlighting twin primes'); },
                highlightMersenne() { console.log('Highlighting Mersenne primes'); },
                showMultiplication() { console.log('Showing multiplication'); },
                showPowers() { console.log('Showing powers'); }
            };
        }
        
        function initAlgoViz() {
            const canvas = document.getElementById('sortCanvas');
            const ctx = canvas.getContext('2d');
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
            
            algoViz = {
                runBubbleSort() { console.log('Running bubble sort'); },
                runQuickSort() { console.log('Running quick sort'); },
                runMergeSort() { console.log('Running merge sort'); },
                runHeapSort() { console.log('Running heap sort'); },
                shuffle() { console.log('Shuffling array'); }
            };
        }
        
        function initCryptoViz() {
            cryptoViz = {
                generateKeys() { console.log('Generating RSA keys'); },
                encrypt() { console.log('Encrypting message'); },
                decrypt() { console.log('Decrypting message'); },
                runDiffieHellman() { console.log('Running Diffie-Hellman'); }
            };
        }
        
        function initOptViz() {
            const container = document.getElementById('optCanvas');
            container.innerHTML = '<canvas width="100%" height="100%"></canvas>';
            
            optViz = {
                runGradientDescent() { console.log('Running gradient descent'); },
                runNewton() { console.log('Running Newton optimization'); },
                changeFunction() { console.log('Changing function'); },
                addConstraint() { console.log('Adding constraint'); },
                solveSimplex() { console.log('Solving with simplex'); },
                clear() { console.log('Clearing optimization'); }
            };
        }
        
        // Initialize on load
        window.addEventListener('load', () => {
            resizeCanvas();
            initParticles();
            animateParticles();
        });
        
        window.addEventListener('resize', () => {
            resizeCanvas();
        });
    </script>
</body>
</html>