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 Calculus Visualizations Math
Download Open
Show description 1,732 chars · Math

Interactive Calculus Visualizations

Interactive Calculus Visualizations













Calculus Concepts Visualized

An interactive exploration of parametric and polar formulas.






Parametric Derivative (Slope)

Finds the slope of the tangent line for a parametric curve. Remember this as the change in y over the change in x, both with respect to the parameter t.

$$ \frac{dy}{dx} = \frac{dy/dt}{dx/dt} $$



Parameter 't': 1




Curve: \( x(t) = t^2 - 2, y(t) = t^3 - 3t \)

Slope at t=1 is -








Parametric Arc Length

Calculates the length of a curve defined parametrically from t=a to t=b.

$$ L = \int_{a}^{b} \sqrt{(\frac{dx}{dt})^2 + (\frac{dy}{dt})^2} \,dt $$




Start 'a': -1.5




End 'b': 1.5






Arc Length: -








Polar Area

Finds the area of a region bounded by a polar curve. Remember the \( \frac{1}{2} \) and that the radius is squared.

$$ A = \int_{\alpha}^{\beta} \frac{1}{2} r^2 \,d\theta $$




Start Angle α: 0°




End Angle β: 90°






Curve: \( r(\theta) = 3 \cos(4\theta) \)

Area: -








Polar Arc Length

Calculates the length of a curve defined in polar coordinates from θ=a to θ=b.

$$ L = \int_{a}^{b} \sqrt{r^2 + (\frac{dr}{d\theta})^2} \,d\theta $$




Start Angle a: 0°




End Angle b: 180°






Polar Arc Length: -








Coordinate Conversion

Convert coordinates between Polar and Cartesian systems.



Polar to Cartesian

$$ x = r \cos(\theta), \quad y = r \sin(\theta) $$



Radius (r): 2




Angle (θ): 45°






Cartesian: (x, y)






Cartesian to Polar

$$ r^2 = x^2 + y^2, \quad \tan(\theta) = \frac{y}{x} $$



X-coordinate: 1




Y-coordinate: 1






Polar: (r, θ)

Interactive Calculus Visualizations

31,531 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 Calculus Visualizations</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Inter', sans-serif;
        }
        .formula-card {
            background-color: #111827; /* A very dark gray, almost black */
            color: #e2e8f0;
            border: 1px solid #4b5563;
        }
        .formula {
            font-family: 'Times New Roman', Times, serif;
            font-size: 1.25rem;
            color: #f97316; /* Matte Orange */
            text-align: center;
            margin: 1rem 0;
        }
        .katex-display {
            display: block;
            margin: 1em 0;
            text-align: center;
        }
    </style>
    <!-- KaTeX for rendering math -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css" xintegrity="sha384-Xi8rHCmBmhbuyyhbI88391ZKP2dmfnOl4rT9ZfRI7zTDRGto2iA60PJpreK1NsBp" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.js" xintegrity="sha384-X/XCfMm41YSAbCIZ24GGMxxguZ1hI2lNQAIeEaQUtLjIvE/MxdX+n2s5v/Kk5M0i" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/contrib/auto-render.min.js" xintegrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7eEbyTRldC3vqFe7QLA4HJJIK" crossorigin="anonymous"></script>
</head>
<body class="bg-black text-white p-4 sm:p-8">

    <div class="max-w-7xl mx-auto">
        <h1 class="text-4xl font-bold text-center mb-4 text-orange-500">Calculus Concepts Visualized</h1>
        <p class="text-center text-gray-400 mb-12">An interactive exploration of parametric and polar formulas.</p>

        <div class="grid grid-cols-1 md:grid-cols-2 gap-8">

            <!-- Parametric Derivative (Slope) -->
            <div class="formula-card rounded-lg p-6">
                <h2 class="text-2xl font-semibold mb-2 text-orange-600">Parametric Derivative (Slope)</h2>
                <p class="text-gray-400 mb-4">Finds the slope of the tangent line for a parametric curve. Remember this as the change in y over the change in x, both with respect to the parameter t.</p>
                <div class="formula">$$ \frac{dy}{dx} = \frac{dy/dt}{dx/dt} $$</div>
                <canvas id="parametricSlopeChart"></canvas>
                <div class="mt-4">
                    <label for="tSlider" class="block text-sm font-medium text-gray-300">Parameter 't': <span id="tValue">1</span></label>
                    <input id="tSlider" type="range" min="-2" max="2" value="1" step="0.01" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                </div>
                <div class="mt-2 text-sm text-gray-400">
                    <p>Curve: \( x(t) = t^2 - 2, y(t) = t^3 - 3t \)</p>
                    <p>Slope at t=<span id="tDisplay">1</span> is <span id="slopeValue">-</span></p>
                </div>
            </div>

            <!-- Parametric Arc Length -->
            <div class="formula-card rounded-lg p-6">
                <h2 class="text-2xl font-semibold mb-2 text-orange-600">Parametric Arc Length</h2>
                <p class="text-gray-400 mb-4">Calculates the length of a curve defined parametrically from t=a to t=b.</p>
                <div class="formula">$$ L = \int_{a}^{b} \sqrt{(\frac{dx}{dt})^2 + (\frac{dy}{dt})^2} \,dt $$</div>
                <canvas id="parametricArcChart"></canvas>
                <div class="mt-4 grid grid-cols-2 gap-4">
                    <div>
                        <label for="arcStartSlider" class="block text-sm font-medium text-gray-300">Start 'a': <span id="arcStartValue">-1.5</span></label>
                        <input id="arcStartSlider" type="range" min="-2" max="2" value="-1.5" step="0.01" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                    </div>
                    <div>
                        <label for="arcEndSlider" class="block text-sm font-medium text-gray-300">End 'b': <span id="arcEndValue">1.5</span></label>
                        <input id="arcEndSlider" type="range" min="-2" max="2" value="1.5" step="0.01" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                    </div>
                </div>
                 <div class="mt-2 text-sm text-gray-400">
                    <p>Arc Length: <span id="arcLengthValue">-</span></p>
                </div>
            </div>

            <!-- Polar Area -->
            <div class="formula-card rounded-lg p-6">
                <h2 class="text-2xl font-semibold mb-2 text-orange-600">Polar Area</h2>
                <p class="text-gray-400 mb-4">Finds the area of a region bounded by a polar curve. Remember the \( \frac{1}{2} \) and that the radius is squared.</p>
                <div class="formula">$$ A = \int_{\alpha}^{\beta} \frac{1}{2} r^2 \,d\theta $$</div>
                <canvas id="polarAreaChart"></canvas>
                 <div class="mt-4 grid grid-cols-2 gap-4">
                    <div>
                        <label for="angleStartSlider" class="block text-sm font-medium text-gray-300">Start Angle α: <span id="angleStartValue">0</span>°</label>
                        <input id="angleStartSlider" type="range" min="0" max="360" value="0" step="1" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                    </div>
                    <div>
                        <label for="angleEndSlider" class="block text-sm font-medium text-gray-300">End Angle β: <span id="angleEndValue">90</span>°</label>
                        <input id="angleEndSlider" type="range" min="0" max="360" value="90" step="1" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                    </div>
                </div>
                <div class="mt-2 text-sm text-gray-400">
                    <p>Curve: \( r(\theta) = 3 \cos(4\theta) \)</p>
                    <p>Area: <span id="polarAreaValue">-</span></p>
                </div>
            </div>

            <!-- Polar Arc Length -->
            <div class="formula-card rounded-lg p-6">
                <h2 class="text-2xl font-semibold mb-2 text-orange-600">Polar Arc Length</h2>
                 <p class="text-gray-400 mb-4">Calculates the length of a curve defined in polar coordinates from θ=a to θ=b.</p>
                <div class="formula">$$ L = \int_{a}^{b} \sqrt{r^2 + (\frac{dr}{d\theta})^2} \,d\theta $$</div>
                <canvas id="polarArcChart"></canvas>
                 <div class="mt-4 grid grid-cols-2 gap-4">
                    <div>
                        <label for="polarArcStartSlider" class="block text-sm font-medium text-gray-300">Start Angle a: <span id="polarArcStartValue">0</span>°</label>
                        <input id="polarArcStartSlider" type="range" min="0" max="360" value="0" step="1" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                    </div>
                    <div>
                        <label for="polarArcEndSlider" class="block text-sm font-medium text-gray-300">End Angle b: <span id="polarArcEndValue">180</span>°</label>
                        <input id="polarArcEndSlider" type="range" min="0" max="360" value="180" step="1" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                    </div>
                </div>
                 <div class="mt-2 text-sm text-gray-400">
                    <p>Polar Arc Length: <span id="polarArcLengthValue">-</span></p>
                </div>
            </div>

             <!-- Coordinate Conversion -->
            <div class="formula-card rounded-lg p-6 md:col-span-2">
                <h2 class="text-2xl font-semibold mb-2 text-orange-600">Coordinate Conversion</h2>
                <p class="text-gray-400 mb-4">Convert coordinates between Polar and Cartesian systems.</p>
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
                    <div>
                        <h3 class="text-xl font-medium text-orange-500">Polar to Cartesian</h3>
                        <div class="formula">$$ x = r \cos(\theta), \quad y = r \sin(\theta) $$</div>
                        <div class="mt-4 space-y-4">
                            <div>
                                <label for="rInput" class="block text-sm font-medium text-gray-300">Radius (r): <span id="rValueDisplay">2</span></label>
                                <input id="rInput" type="range" min="0" max="5" value="2" step="0.1" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                            </div>
                            <div>
                                <label for="thetaInput" class="block text-sm font-medium text-gray-300">Angle (θ): <span id="thetaValueDisplay">45</span>°</label>
                                <input id="thetaInput" type="range" min="0" max="360" value="45" step="1" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                            </div>
                        </div>
                        <div class="mt-4 text-center bg-gray-800 p-3 rounded-md">
                            <p class="text-lg">Cartesian: <span id="cartesianResult" class="font-mono text-orange-400">(x, y)</span></p>
                        </div>
                    </div>
                     <div>
                        <h3 class="text-xl font-medium text-orange-500">Cartesian to Polar</h3>
                        <div class="formula">$$ r^2 = x^2 + y^2, \quad \tan(\theta) = \frac{y}{x} $$</div>
                         <div class="mt-4 space-y-4">
                            <div>
                                <label for="xInput" class="block text-sm font-medium text-gray-300">X-coordinate: <span id="xValueDisplay">1</span></label>
                                <input id="xInput" type="range" min="-5" max="5" value="1" step="0.1" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                            </div>
                            <div>
                                <label for="yInput" class="block text-sm font-medium text-gray-300">Y-coordinate: <span id="yValueDisplay">1</span></label>
                                <input id="yInput" type="range" min="-5" max="5" value="1" step="0.1" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
                            </div>
                        </div>
                         <div class="mt-4 text-center bg-gray-800 p-3 rounded-md">
                            <p class="text-lg">Polar: <span id="polarResult" class="font-mono text-orange-400">(r, θ)</span></p>
                        </div>
                    </div>
                </div>
                 <canvas id="conversionChart" class="mt-6"></canvas>
            </div>

        </div>
    </div>

    <script>
        // --- UTILITY FUNCTIONS ---
        const xParam = t => t * t - 2;
        const yParam = t => t * t * t - 3 * t;
        const dx_dt = t => 2 * t;
        const dy_dt = t => 3 * t * t - 3;

        const rPolar = theta => 3 * Math.cos(4 * theta);
        const dr_dtheta = theta => -12 * Math.sin(4 * theta);

        // --- 1. PARAMETRIC SLOPE VISUALIZATION ---
        const tSlider = document.getElementById('tSlider');
        const tValueSpan = document.getElementById('tValue');
        const tDisplaySpan = document.getElementById('tDisplay');
        const slopeValueSpan = document.getElementById('slopeValue');
        const parametricSlopeCtx = document.getElementById('parametricSlopeChart').getContext('2d');
        let parametricSlopeChart;

        function updateParametricSlope() {
            const t = parseFloat(tSlider.value);
            tValueSpan.textContent = t.toFixed(2);
            tDisplaySpan.textContent = t.toFixed(2);

            const x = xParam(t);
            const y = yParam(t);
            const slope = dx_dt(t) !== 0 ? dy_dt(t) / dx_dt(t) : Infinity;
            slopeValueSpan.textContent = isFinite(slope) ? slope.toFixed(3) : 'Vertical';

            // Tangent line points
            const t_range = 2;
            const tangent_x1 = x - t_range;
            const tangent_y1 = y - slope * t_range;
            const tangent_x2 = x + t_range;
            const tangent_y2 = y + slope * t_range;
            
            parametricSlopeChart.data.datasets[1].data = [{x, y}];
            parametricSlopeChart.data.datasets[2].data = isFinite(slope) ? [{x: tangent_x1, y: tangent_y1}, {x: tangent_x2, y: tangent_y2}] : [{x, y: -5}, {x, y: 5}];
            parametricSlopeChart.update();
        }

        function createParametricSlopeChart() {
            const data = [];
            for (let t = -2; t <= 2; t += 0.05) {
                data.push({ x: xParam(t), y: yParam(t) });
            }

            parametricSlopeChart = new Chart(parametricSlopeCtx, {
                type: 'scatter',
                data: {
                    datasets: [{
                        label: 'Parametric Curve',
                        data: data,
                        borderColor: '#ea580c', // Dark Orange
                        backgroundColor: '#ea580c',
                        showLine: true,
                        pointRadius: 0,
                        tension: 0.1,
                    }, {
                        label: 'Point (t)',
                        data: [],
                        backgroundColor: '#f97316', // Bright Orange
                        pointRadius: 6,
                        pointHoverRadius: 8,
                    }, {
                        label: 'Tangent Line',
                        data: [],
                        borderColor: '#c2410c', // Darker Orange
                        backgroundColor: '#c2410c',
                        showLine: true,
                        pointRadius: 0,
                        borderDash: [5, 5],
                        fill: false
                    }]
                },
                options: {
                    responsive: true,
                    plugins: { legend: { labels: { color: '#e2e8f0' } } },
                    scales: {
                        x: { title: { display: true, text: 'x', color: '#9ca3af' }, ticks: { color: '#9ca3af' }, grid: { color: '#4b5563' } },
                        y: { title: { display: true, text: 'y', color: '#9ca3af' }, ticks: { color: '#9ca3af' }, grid: { color: '#4b5563' } }
                    }
                }
            });
            updateParametricSlope();
        }

        tSlider.addEventListener('input', updateParametricSlope);

        // --- 2. PARAMETRIC ARC LENGTH VISUALIZATION ---
        const arcStartSlider = document.getElementById('arcStartSlider');
        const arcEndSlider = document.getElementById('arcEndSlider');
        const arcStartValueSpan = document.getElementById('arcStartValue');
        const arcEndValueSpan = document.getElementById('arcEndValue');
        const arcLengthValueSpan = document.getElementById('arcLengthValue');
        const parametricArcCtx = document.getElementById('parametricArcChart').getContext('2d');
        let parametricArcChart;

        function updateParametricArc() {
            let a = parseFloat(arcStartSlider.value);
            let b = parseFloat(arcEndSlider.value);
            if (a > b) [a, b] = [b, a]; // Swap if a > b

            arcStartValueSpan.textContent = a.toFixed(2);
            arcEndValueSpan.textContent = b.toFixed(2);

            const arcData = [];
            for (let t = a; t <= b; t += 0.05) {
                arcData.push({ x: xParam(t), y: yParam(t) });
            }
            parametricArcChart.data.datasets[1].data = arcData;
            
            // Numerical Integration for Arc Length
            let length = 0;
            const n = 1000;
            const dt = (b - a) / n;
            for (let i = 0; i < n; i++) {
                const t = a + i * dt;
                const dxdt = dx_dt(t);
                const dydt = dy_dt(t);
                length += Math.sqrt(dxdt * dxdt + dydt * dydt) * dt;
            }
            arcLengthValueSpan.textContent = length.toFixed(4);

            parametricArcChart.update();
        }

        function createParametricArcChart() {
            const fullCurveData = [];
            for (let t = -2; t <= 2; t += 0.05) {
                fullCurveData.push({ x: xParam(t), y: yParam(t) });
            }

            parametricArcChart = new Chart(parametricArcCtx, {
                type: 'scatter',
                data: {
                    datasets: [{
                        label: 'Full Curve',
                        data: fullCurveData,
                        borderColor: '#4b5563',
                        showLine: true,
                        pointRadius: 0
                    }, {
                        label: 'Arc Segment',
                        data: [],
                        borderColor: '#f97316', // Bright Orange
                        backgroundColor: '#f97316',
                        showLine: true,
                        pointRadius: 0,
                        borderWidth: 3
                    }]
                },
                options: {
                    responsive: true,
                    plugins: { legend: { labels: { color: '#e2e8f0' } } },
                    scales: {
                        x: { title: { display: true, text: 'x', color: '#9ca3af' }, ticks: { color: '#9ca3af' }, grid: { color: '#4b5563' } },
                        y: { title: { display: true, text: 'y', color: '#9ca3af' }, ticks: { color: '#9ca3af' }, grid: { color: '#4b5563' } }
                    }
                }
            });
            updateParametricArc();
        }

        arcStartSlider.addEventListener('input', updateParametricArc);
        arcEndSlider.addEventListener('input', updateParametricArc);

        // --- 3. POLAR AREA VISUALIZATION ---
        const angleStartSlider = document.getElementById('angleStartSlider');
        const angleEndSlider = document.getElementById('angleEndSlider');
        const angleStartValueSpan = document.getElementById('angleStartValue');
        const angleEndValueSpan = document.getElementById('angleEndValue');
        const polarAreaValueSpan = document.getElementById('polarAreaValue');
        const polarAreaCtx = document.getElementById('polarAreaChart').getContext('2d');
        let polarAreaChart;

        function updatePolarArea() {
            let alphaDeg = parseFloat(angleStartSlider.value);
            let betaDeg = parseFloat(angleEndSlider.value);
            if (alphaDeg > betaDeg) [alphaDeg, betaDeg] = [betaDeg, alphaDeg];

            angleStartValueSpan.textContent = `${alphaDeg}°`;
            angleEndValueSpan.textContent = `${betaDeg}°`;

            const alphaRad = alphaDeg * Math.PI / 180;
            const betaRad = betaDeg * Math.PI / 180;

            const areaData = [{x: 0, y: 0}];
            for (let theta = alphaRad; theta <= betaRad; theta += 0.01) {
                const r = rPolar(theta);
                areaData.push({ x: r * Math.cos(theta), y: r * Math.sin(theta) });
            }
            areaData.push({x: 0, y: 0});
            polarAreaChart.data.datasets[1].data = areaData;

            // Numerical Integration for Area
            let area = 0;
            const n = 1000;
            const dtheta = (betaRad - alphaRad) / n;
            for (let i = 0; i < n; i++) {
                const theta = alphaRad + i * dtheta;
                const r = rPolar(theta);
                area += 0.5 * r * r * dtheta;
            }
            polarAreaValueSpan.textContent = area.toFixed(4);

            polarAreaChart.update();
        }

        function createPolarAreaChart() {
            const fullCurveData = [];
            for (let theta = 0; theta <= 2 * Math.PI; theta += 0.01) {
                const r = rPolar(theta);
                fullCurveData.push({ x: r * Math.cos(theta), y: r * Math.sin(theta) });
            }

            polarAreaChart = new Chart(polarAreaCtx, {
                type: 'scatter',
                data: {
                    datasets: [{
                        label: 'Polar Curve',
                        data: fullCurveData,
                        borderColor: '#ea580c', // Dark Orange
                        showLine: true,
                        pointRadius: 0
                    }, {
                        label: 'Shaded Area',
                        data: [],
                        backgroundColor: 'rgba(249, 115, 22, 0.5)', // Orange with alpha
                        showLine: true,
                        pointRadius: 0,
                        fill: true
                    }]
                },
                options: {
                    responsive: true,
                    aspectRatio: 1,
                    plugins: { legend: { labels: { color: '#e2e8f0' } } },
                    scales: {
                        x: { title: { display: true, text: 'x', color: '#9ca3af' }, ticks: { color: '#9ca3af' }, grid: { color: '#4b5563' } },
                        y: { title: { display: true, text: 'y', color: '#9ca3af' }, ticks: { color: '#9ca3af' }, grid: { color: '#4b5563' } }
                    }
                }
            });
            updatePolarArea();
        }
        
        angleStartSlider.addEventListener('input', updatePolarArea);
        angleEndSlider.addEventListener('input', updatePolarArea);

        // --- 4. POLAR ARC LENGTH VISUALIZATION ---
        const polarArcStartSlider = document.getElementById('polarArcStartSlider');
        const polarArcEndSlider = document.getElementById('polarArcEndSlider');
        const polarArcStartValueSpan = document.getElementById('polarArcStartValue');
        const polarArcEndValueSpan = document.getElementById('polarArcEndValue');
        const polarArcLengthValueSpan = document.getElementById('polarArcLengthValue');
        const polarArcCtx = document.getElementById('polarArcChart').getContext('2d');
        let polarArcChart;

        function updatePolarArc() {
            let aDeg = parseFloat(polarArcStartSlider.value);
            let bDeg = parseFloat(polarArcEndSlider.value);
            if (aDeg > bDeg) [aDeg, bDeg] = [bDeg, aDeg];

            polarArcStartValueSpan.textContent = `${aDeg}°`;
            polarArcEndValueSpan.textContent = `${bDeg}°`;
            
            const aRad = aDeg * Math.PI / 180;
            const bRad = bDeg * Math.PI / 180;

            const arcData = [];
            for (let theta = aRad; theta <= bRad; theta += 0.01) {
                 const r = rPolar(theta);
                 arcData.push({ x: r * Math.cos(theta), y: r * Math.sin(theta) });
            }
            polarArcChart.data.datasets[1].data = arcData;

            // Numerical Integration for Arc Length
            let length = 0;
            const n = 1000;
            const dtheta = (bRad - aRad) / n;
            for (let i = 0; i < n; i++) {
                const theta = aRad + i * dtheta;
                const r = rPolar(theta);
                const dr = dr_dtheta(theta);
                length += Math.sqrt(r*r + dr*dr) * dtheta;
            }
            polarArcLengthValueSpan.textContent = length.toFixed(4);
            
            polarArcChart.update();
        }

        function createPolarArcChart() {
             const fullCurveData = [];
            for (let theta = 0; theta <= 2 * Math.PI; theta += 0.01) {
                const r = rPolar(theta);
                fullCurveData.push({ x: r * Math.cos(theta), y: r * Math.sin(theta) });
            }
            
            polarArcChart = new Chart(polarArcCtx, {
                type: 'scatter',
                data: {
                    datasets: [{
                        label: 'Full Curve',
                        data: fullCurveData,
                        borderColor: '#4b5563',
                        showLine: true,
                        pointRadius: 0
                    }, {
                        label: 'Arc Segment',
                        data: [],
                        borderColor: '#f97316', // Bright Orange
                        showLine: true,
                        pointRadius: 0,
                        borderWidth: 3
                    }]
                },
                 options: {
                    responsive: true,
                    aspectRatio: 1,
                    plugins: { legend: { labels: { color: '#e2e8f0' } } },
                    scales: {
                        x: { title: { display: true, text: 'x', color: '#9ca3af' }, ticks: { color: '#9ca3af' }, grid: { color: '#4b5563' } },
                        y: { title: { display: true, text: 'y', color: '#9ca3af' }, ticks: { color: '#9ca3af' }, grid: { color: '#4b5563' } }
                    }
                }
            });
            updatePolarArc();
        }

        polarArcStartSlider.addEventListener('input', updatePolarArc);
        polarArcEndSlider.addEventListener('input', updatePolarArc);
        
        // --- 5. COORDINATE CONVERSION VISUALIZATION ---
        const rInput = document.getElementById('rInput');
        const thetaInput = document.getElementById('thetaInput');
        const xInput = document.getElementById('xInput');
        const yInput = document.getElementById('yInput');
        const rValueDisplay = document.getElementById('rValueDisplay');
        const thetaValueDisplay = document.getElementById('thetaValueDisplay');
        const xValueDisplay = document.getElementById('xValueDisplay');
        const yValueDisplay = document.getElementById('yValueDisplay');
        const cartesianResult = document.getElementById('cartesianResult');
        const polarResult = document.getElementById('polarResult');
        const conversionCtx = document.getElementById('conversionChart').getContext('2d');
        let conversionChart;

        function updateConversion() {
            // Polar to Cartesian
            const r_p2c = parseFloat(rInput.value);
            const theta_deg_p2c = parseFloat(thetaInput.value);
            const theta_rad_p2c = theta_deg_p2c * Math.PI / 180;
            const x_p2c = r_p2c * Math.cos(theta_rad_p2c);
            const y_p2c = r_p2c * Math.sin(theta_rad_p2c);
            rValueDisplay.textContent = r_p2c.toFixed(1);
            thetaValueDisplay.textContent = `${theta_deg_p2c}°`;
            cartesianResult.textContent = `(${x_p2c.toFixed(2)}, ${y_p2c.toFixed(2)})`;

            // Cartesian to Polar
            const x_c2p = parseFloat(xInput.value);
            const y_c2p = parseFloat(yInput.value);
            const r_c2p = Math.sqrt(x_c2p * x_c2p + y_c2p * y_c2p);
            const theta_rad_c2p = Math.atan2(y_c2p, x_c2p);
            let theta_deg_c2p = theta_rad_c2p * 180 / Math.PI;
            if (theta_deg_c2p < 0) theta_deg_c2p += 360; // Keep angle positive
            xValueDisplay.textContent = x_c2p.toFixed(1);
            yValueDisplay.textContent = y_c2p.toFixed(1);
            polarResult.textContent = `(${r_c2p.toFixed(2)}, ${theta_deg_c2p.toFixed(1)}°)`;
            
            // Update chart
            conversionChart.data.datasets[0].data = [{x: x_p2c, y: y_p2c}];
            conversionChart.data.datasets[1].data = [{x: x_c2p, y: y_c2p}];
            conversionChart.update();
        }

        function createConversionChart() {
            conversionChart = new Chart(conversionCtx, {
                type: 'scatter',
                data: {
                    datasets: [{
                        label: 'Point from Polar',
                        data: [],
                        backgroundColor: '#ea580c', // Dark Orange
                        pointRadius: 8,
                        pointHoverRadius: 10
                    }, {
                        label: 'Point from Cartesian',
                        data: [],
                        backgroundColor: '#f97316', // Bright Orange
                        pointRadius: 8,
                        pointHoverRadius: 10
                    }]
                },
                options: {
                    responsive: true,
                    aspectRatio: 2,
                    plugins: { legend: { labels: { color: '#e2e8f0' } } },
                    scales: {
                        x: { min: -5, max: 5, title: { display: true, text: 'x', color: '#9ca3af' }, ticks: { color: '#9ca3af' }, grid: { color: '#4b5563' } },
                        y: { min: -5, max: 5, title: { display: true, text: 'y', color: '#9ca3af' }, ticks: { color: '#9ca3af' }, grid: { color: '#4b5563' } }
                    }
                }
            });
            updateConversion();
        }

        rInput.addEventListener('input', updateConversion);
        thetaInput.addEventListener('input', updateConversion);
        xInput.addEventListener('input', updateConversion);
        yInput.addEventListener('input', updateConversion);


        // --- INITIALIZE ALL CHARTS ON LOAD ---
        window.onload = function() {
            // This function will be called automatically when the page is loaded.
            renderMathInElement(document.body, {
              // customised options
              // • auto-render specific keys, e.g.:
              delimiters: [
                  {left: '$$', right: '$$', display: true},
                  {left: '$', right: '$', display: false},
                  {left: '\\(', right: '\\)', display: false},
                  {left: '\\[', right: '\\]', display: true}
              ],
              // • rendering keys that should be ignored by auto-render:
              ignoredTags: [
                  'script', 'noscript', 'style', 'textarea', 'pre', 'code', 'option'
              ],
              // • rendering keys that should always be rendered as math,
              //   even if they don't contain a delimiter:
              include_in_header: true,
              // • whether to throw an error if the expression contained in
              //   the delimiter does not parse:
              throwOnError : false
            });

            createParametricSlopeChart();
            createParametricArcChart();
            createPolarAreaChart();
            createPolarArcChart();
            createConversionChart();
        };

    </script>
</body>
</html>