Show description
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
<!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>