Show description
Calc 2: 8-Bit Edition
Calc 2: 8-Bit Edition
CALC 2: PARAMETRIC & POLAR
PARAMETRIC CURVES
PARAMETRIC CALCULUS
POLAR COORDINATES
POLAR AREAS & LENGTHS
PARAMETRIC EQUATIONS
x = f(t)
y = g(t)
where t is the parameter
CONVERSION FORMULAS
Parametric → Cartesian:
Eliminate t from both equations
Example: x = t², y = 2t
t = y/2, so x = (y/2)² = y²/4
TIME: t
t = 6.28
ANIMATION SPEED
Speed: 1.0x
CIRCLE
LISSAJOUS
ASTROID
SPIRAL
CURRENT CURVE: Circle
EQUATIONS: x = cos(t), y = sin(t)
TANGENT LINE
dy/dx = (dy/dt)/(dx/dt)
Tangent line at t = t₀:
y - y₀ = (dy/dx)|ₜ₌ₜ₀ · (x - x₀)
ARC LENGTH
L = ∫ᵃᵇ √[(dx/dt)² + (dy/dt)²] dt
where a ≤ t ≤ b
POINT: t₀
t₀ = 1.57
SHOW TANGENT
SHOW ARC LENGTH
TANGENT SLOPE: 0
ARC LENGTH (0 to t₀): 0
POLAR COORDINATES
r = distance from origin
θ = angle from positive x-axis
Point: (r, θ)
CONVERSION FORMULAS
Polar → Cartesian:
x = r cos(θ)
y = r sin(θ)
Cartesian → Polar:
r = √(x² + y²)
θ = arctan(y/x)
ANGLE: θ
θ = 6.28
CIRCLE
CARDIOID
ROSE
SPIRAL
CURRENT CURVE: Circle
EQUATION: r = 2
AREA IN POLAR
A = (1/2) ∫ᵃᵇ r² dθ
where α ≤ θ ≤ β
ARC LENGTH IN POLAR
L = ∫ᵃᵇ √[r² + (dr/dθ)²] dθ
where α ≤ θ ≤ β
START ANGLE: α
α = 0
END ANGLE: β
β = 3.14
SHOW AREA
AREA: 0
ARC LENGTH: 0
Calc 2: 8-Bit Edition
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calc 2: 8-Bit Edition</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Press Start 2P', cursive;
background: #1a1a2e;
color: #eee;
line-height: 1.6;
overflow-x: hidden;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
h1 {
text-align: center;
color: #00ff00;
font-size: 24px;
margin-bottom: 30px;
text-shadow: 3px 3px 0px #008800;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.8; }
}
.tabs {
display: flex;
gap: 10px;
margin-bottom: 30px;
flex-wrap: wrap;
}
.tab {
background: #16213e;
border: 3px solid #0f3460;
padding: 10px 20px;
cursor: pointer;
font-size: 10px;
transition: all 0.3s;
position: relative;
}
.tab:hover {
background: #0f3460;
transform: translateY(-2px);
}
.tab.active {
background: #e94560;
border-color: #ff6b6b;
box-shadow: 0 5px 0 #a01e3e;
}
.content {
display: none;
background: #16213e;
border: 3px solid #0f3460;
padding: 30px;
min-height: 600px;
}
.content.active {
display: block;
}
.formula-box {
background: #0f3460;
border: 2px solid #00ff00;
padding: 20px;
margin: 20px 0;
font-size: 10px;
box-shadow: 5px 5px 0 #000;
}
.formula-title {
color: #00ff00;
margin-bottom: 10px;
font-size: 12px;
}
.formula {
color: #fff;
font-family: 'Courier New', monospace;
font-size: 14px;
line-height: 1.8;
letter-spacing: 1px;
}
.visualization {
display: flex;
gap: 30px;
margin: 30px 0;
flex-wrap: wrap;
}
.canvas-container {
flex: 1;
min-width: 400px;
}
canvas {
border: 3px solid #00ff00;
background: #000;
width: 100%;
max-width: 500px;
height: 400px;
image-rendering: pixelated;
box-shadow: 5px 5px 0 #008800;
}
.controls {
flex: 1;
min-width: 300px;
}
.control-group {
margin: 20px 0;
background: #0f3460;
padding: 15px;
border: 2px solid #00ff00;
}
.control-label {
display: block;
margin-bottom: 10px;
font-size: 10px;
color: #00ff00;
}
input[type="range"] {
width: 100%;
height: 20px;
background: #000;
outline: none;
border: 2px solid #00ff00;
cursor: pointer;
-webkit-appearance: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
background: #00ff00;
border: 2px solid #000;
cursor: pointer;
}
.value-display {
text-align: right;
color: #fff;
font-size: 10px;
margin-top: 5px;
}
.example-buttons {
display: flex;
gap: 10px;
margin: 20px 0;
flex-wrap: wrap;
}
.example-btn {
background: #e94560;
border: 2px solid #ff6b6b;
color: #fff;
padding: 10px 15px;
cursor: pointer;
font-size: 9px;
font-family: 'Press Start 2P', cursive;
transition: all 0.3s;
}
.example-btn:hover {
background: #ff6b6b;
transform: translateY(-2px);
}
.info-text {
font-size: 10px;
line-height: 2;
margin: 20px 0;
background: #0f3460;
padding: 15px;
border-left: 5px solid #00ff00;
}
@media (max-width: 768px) {
.tabs {
justify-content: center;
}
.visualization {
flex-direction: column;
}
canvas {
max-width: 100%;
}
}
</style>
</head>
<body>
<div class="container">
<h1>CALC 2: PARAMETRIC & POLAR</h1>
<div class="tabs">
<div class="tab active" data-tab="parametric">PARAMETRIC CURVES</div>
<div class="tab" data-tab="parametric-calc">PARAMETRIC CALCULUS</div>
<div class="tab" data-tab="polar">POLAR COORDINATES</div>
<div class="tab" data-tab="polar-calc">POLAR AREAS & LENGTHS</div>
</div>
<div class="content active" id="parametric">
<div class="formula-box">
<div class="formula-title">PARAMETRIC EQUATIONS</div>
<div class="formula">
x = f(t)<br>
y = g(t)<br><br>
where t is the parameter
</div>
</div>
<div class="formula-box">
<div class="formula-title">CONVERSION FORMULAS</div>
<div class="formula">
Parametric → Cartesian:<br>
Eliminate t from both equations<br><br>
Example: x = t², y = 2t<br>
t = y/2, so x = (y/2)² = y²/4
</div>
</div>
<div class="visualization">
<div class="canvas-container">
<canvas id="parametricCanvas"></canvas>
</div>
<div class="controls">
<div class="control-group">
<label class="control-label">TIME: t</label>
<input type="range" id="tRange" min="0" max="6.28" step="0.01" value="6.28">
<div class="value-display" id="tValue">t = 6.28</div>
</div>
<div class="control-group">
<label class="control-label">ANIMATION SPEED</label>
<input type="range" id="speedRange" min="0" max="5" step="0.1" value="1">
<div class="value-display" id="speedValue">Speed: 1.0x</div>
</div>
<div class="example-buttons">
<button class="example-btn" onclick="setParametricExample('circle')">CIRCLE</button>
<button class="example-btn" onclick="setParametricExample('lissajous')">LISSAJOUS</button>
<button class="example-btn" onclick="setParametricExample('astroid')">ASTROID</button>
<button class="example-btn" onclick="setParametricExample('spiral')">SPIRAL</button>
</div>
</div>
</div>
<div class="info-text">
CURRENT CURVE: <span id="currentParametric">Circle</span><br>
EQUATIONS: <span id="parametricEquations">x = cos(t), y = sin(t)</span>
</div>
</div>
<div class="content" id="parametric-calc">
<div class="formula-box">
<div class="formula-title">TANGENT LINE</div>
<div class="formula">
dy/dx = (dy/dt)/(dx/dt)<br><br>
Tangent line at t = t₀:<br>
y - y₀ = (dy/dx)|ₜ₌ₜ₀ · (x - x₀)
</div>
</div>
<div class="formula-box">
<div class="formula-title">ARC LENGTH</div>
<div class="formula">
L = ∫ᵃᵇ √[(dx/dt)² + (dy/dt)²] dt<br><br>
where a ≤ t ≤ b
</div>
</div>
<div class="visualization">
<div class="canvas-container">
<canvas id="parametricCalcCanvas"></canvas>
</div>
<div class="controls">
<div class="control-group">
<label class="control-label">POINT: t₀</label>
<input type="range" id="t0Range" min="0" max="6.28" step="0.01" value="1.57">
<div class="value-display" id="t0Value">t₀ = 1.57</div>
</div>
<div class="control-group">
<label class="control-label">SHOW TANGENT</label>
<input type="checkbox" id="showTangent" checked>
</div>
<div class="control-group">
<label class="control-label">SHOW ARC LENGTH</label>
<input type="checkbox" id="showArcLength" checked>
</div>
</div>
</div>
<div class="info-text">
TANGENT SLOPE: <span id="tangentSlope">0</span><br>
ARC LENGTH (0 to t₀): <span id="arcLength">0</span>
</div>
</div>
<div class="content" id="polar">
<div class="formula-box">
<div class="formula-title">POLAR COORDINATES</div>
<div class="formula">
r = distance from origin<br>
θ = angle from positive x-axis<br><br>
Point: (r, θ)
</div>
</div>
<div class="formula-box">
<div class="formula-title">CONVERSION FORMULAS</div>
<div class="formula">
Polar → Cartesian:<br>
x = r cos(θ)<br>
y = r sin(θ)<br><br>
Cartesian → Polar:<br>
r = √(x² + y²)<br>
θ = arctan(y/x)
</div>
</div>
<div class="visualization">
<div class="canvas-container">
<canvas id="polarCanvas"></canvas>
</div>
<div class="controls">
<div class="control-group">
<label class="control-label">ANGLE: θ</label>
<input type="range" id="thetaRange" min="0" max="12.56" step="0.01" value="6.28">
<div class="value-display" id="thetaValue">θ = 6.28</div>
</div>
<div class="example-buttons">
<button class="example-btn" onclick="setPolarExample('circle')">CIRCLE</button>
<button class="example-btn" onclick="setPolarExample('cardioid')">CARDIOID</button>
<button class="example-btn" onclick="setPolarExample('rose')">ROSE</button>
<button class="example-btn" onclick="setPolarExample('spiral')">SPIRAL</button>
</div>
</div>
</div>
<div class="info-text">
CURRENT CURVE: <span id="currentPolar">Circle</span><br>
EQUATION: <span id="polarEquation">r = 2</span>
</div>
</div>
<div class="content" id="polar-calc">
<div class="formula-box">
<div class="formula-title">AREA IN POLAR</div>
<div class="formula">
A = (1/2) ∫ᵃᵇ r² dθ<br><br>
where α ≤ θ ≤ β
</div>
</div>
<div class="formula-box">
<div class="formula-title">ARC LENGTH IN POLAR</div>
<div class="formula">
L = ∫ᵃᵇ √[r² + (dr/dθ)²] dθ<br><br>
where α ≤ θ ≤ β
</div>
</div>
<div class="visualization">
<div class="canvas-container">
<canvas id="polarCalcCanvas"></canvas>
</div>
<div class="controls">
<div class="control-group">
<label class="control-label">START ANGLE: α</label>
<input type="range" id="alphaRange" min="0" max="6.28" step="0.01" value="0">
<div class="value-display" id="alphaValue">α = 0</div>
</div>
<div class="control-group">
<label class="control-label">END ANGLE: β</label>
<input type="range" id="betaRange" min="0" max="6.28" step="0.01" value="3.14">
<div class="value-display" id="betaValue">β = 3.14</div>
</div>
<div class="control-group">
<label class="control-label">SHOW AREA</label>
<input type="checkbox" id="showArea" checked>
</div>
</div>
</div>
<div class="info-text">
AREA: <span id="polarArea">0</span><br>
ARC LENGTH: <span id="polarArcLength">0</span>
</div>
</div>
</div>
<script>
// Tab functionality
const tabs = document.querySelectorAll('.tab');
const contents = document.querySelectorAll('.content');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const targetId = tab.dataset.tab;
tabs.forEach(t => t.classList.remove('active'));
contents.forEach(c => c.classList.remove('active'));
tab.classList.add('active');
document.getElementById(targetId).classList.add('active');
// Initialize the canvas for the active tab
initializeCanvas(targetId);
});
});
// Canvas setup
const canvases = {
parametric: document.getElementById('parametricCanvas'),
parametricCalc: document.getElementById('parametricCalcCanvas'),
polar: document.getElementById('polarCanvas'),
polarCalc: document.getElementById('polarCalcCanvas')
};
const contexts = {};
Object.keys(canvases).forEach(key => {
contexts[key] = canvases[key].getContext('2d');
canvases[key].width = 500;
canvases[key].height = 400;
});
// Animation variables
let animationFrames = {};
let parametricType = 'circle';
let polarType = 'circle';
// Parametric curves
const parametricCurves = {
circle: {
name: 'Circle',
equations: 'x = cos(t), y = sin(t)',
x: t => Math.cos(t),
y: t => Math.sin(t),
tMax: 2 * Math.PI
},
lissajous: {
name: 'Lissajous Curve',
equations: 'x = sin(3t), y = sin(2t)',
x: t => Math.sin(3 * t),
y: t => Math.sin(2 * t),
tMax: 2 * Math.PI
},
astroid: {
name: 'Astroid',
equations: 'x = cos³(t), y = sin³(t)',
x: t => Math.pow(Math.cos(t), 3),
y: t => Math.pow(Math.sin(t), 3),
tMax: 2 * Math.PI
},
spiral: {
name: 'Spiral',
equations: 'x = t·cos(t)/4, y = t·sin(t)/4',
x: t => t * Math.cos(t) / 4,
y: t => t * Math.sin(t) / 4,
tMax: 4 * Math.PI
}
};
// Polar curves
const polarCurves = {
circle: {
name: 'Circle',
equation: 'r = 2',
r: theta => 2,
thetaMax: 2 * Math.PI
},
cardioid: {
name: 'Cardioid',
equation: 'r = 1 + cos(θ)',
r: theta => 1 + Math.cos(theta),
thetaMax: 2 * Math.PI
},
rose: {
name: 'Four-Petaled Rose',
equation: 'r = 2·cos(2θ)',
r: theta => 2 * Math.cos(2 * theta),
thetaMax: 2 * Math.PI
},
spiral: {
name: 'Archimedean Spiral',
equation: 'r = θ/2',
r: theta => theta / 2,
thetaMax: 4 * Math.PI
}
};
// Drawing functions
function drawGrid(ctx) {
ctx.strokeStyle = '#003300';
ctx.lineWidth = 1;
// Grid lines
for (let i = 0; i <= 10; i++) {
const x = i * 50;
const y = i * 40;
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, 400);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(500, y);
ctx.stroke();
}
// Axes
ctx.strokeStyle = '#00ff00';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(250, 0);
ctx.lineTo(250, 400);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, 200);
ctx.lineTo(500, 200);
ctx.stroke();
}
function toScreenCoords(x, y, scale = 80) {
return {
x: 250 + x * scale,
y: 200 - y * scale
};
}
// Parametric curve animation
function animateParametric() {
const ctx = contexts.parametric;
const t = parseFloat(document.getElementById('tRange').value);
const speed = parseFloat(document.getElementById('speedRange').value);
const curve = parametricCurves[parametricType];
ctx.clearRect(0, 0, 500, 400);
drawGrid(ctx);
// Draw curve
ctx.strokeStyle = '#00ff00';
ctx.lineWidth = 2;
ctx.beginPath();
const steps = 1000;
const dt = t / steps;
for (let i = 0; i <= steps; i++) {
const ti = i * dt;
const x = curve.x(ti);
const y = curve.y(ti);
const screen = toScreenCoords(x, y);
if (i === 0) {
ctx.moveTo(screen.x, screen.y);
} else {
ctx.lineTo(screen.x, screen.y);
}
}
ctx.stroke();
// Draw current point
const currentX = curve.x(t);
const currentY = curve.y(t);
const currentScreen = toScreenCoords(currentX, currentY);
ctx.fillStyle = '#ff0000';
ctx.fillRect(currentScreen.x - 4, currentScreen.y - 4, 8, 8);
// Auto-advance animation
if (speed > 0 && t < curve.tMax) {
document.getElementById('tRange').value = Math.min(t + 0.02 * speed, curve.tMax);
document.getElementById('tValue').textContent = `t = ${document.getElementById('tRange').value}`;
} else if (speed > 0 && t >= curve.tMax) {
document.getElementById('tRange').value = 0;
}
animationFrames.parametric = requestAnimationFrame(animateParametric);
}
// Parametric calculus visualization
function animateParametricCalc() {
const ctx = contexts.parametricCalc;
const t0 = parseFloat(document.getElementById('t0Range').value);
const showTangent = document.getElementById('showTangent').checked;
const showArcLength = document.getElementById('showArcLength').checked;
const curve = parametricCurves.circle; // Using circle for calc demo
ctx.clearRect(0, 0, 500, 400);
drawGrid(ctx);
// Draw full curve
ctx.strokeStyle = '#00ff00';
ctx.lineWidth = 2;
ctx.beginPath();
const steps = 1000;
const dt = 2 * Math.PI / steps;
let arcLength = 0;
for (let i = 0; i <= steps; i++) {
const ti = i * dt;
const x = curve.x(ti);
const y = curve.y(ti);
const screen = toScreenCoords(x, y);
if (i === 0) {
ctx.moveTo(screen.x, screen.y);
} else {
ctx.lineTo(screen.x, screen.y);
// Calculate arc length up to t0
if (ti <= t0 && showArcLength) {
const dx = curve.x(ti) - curve.x(ti - dt);
const dy = curve.y(ti) - curve.y(ti - dt);
arcLength += Math.sqrt(dx * dx + dy * dy);
}
}
}
ctx.stroke();
// Draw point at t0
const x0 = curve.x(t0);
const y0 = curve.y(t0);
const screen0 = toScreenCoords(x0, y0);
ctx.fillStyle = '#ff0000';
ctx.fillRect(screen0.x - 4, screen0.y - 4, 8, 8);
// Draw tangent line
if (showTangent) {
const dx = -Math.sin(t0); // derivative of cos(t)
const dy = Math.cos(t0); // derivative of sin(t)
const slope = dy / dx;
ctx.strokeStyle = '#ffff00';
ctx.lineWidth = 2;
ctx.beginPath();
// Extend tangent line
const extend = 2;
const x1 = x0 - extend * dx / Math.sqrt(dx * dx + dy * dy);
const y1 = y0 - extend * dy / Math.sqrt(dx * dx + dy * dy);
const x2 = x0 + extend * dx / Math.sqrt(dx * dx + dy * dy);
const y2 = y0 + extend * dy / Math.sqrt(dx * dx + dy * dy);
const screen1 = toScreenCoords(x1, y1);
const screen2 = toScreenCoords(x2, y2);
ctx.moveTo(screen1.x, screen1.y);
ctx.lineTo(screen2.x, screen2.y);
ctx.stroke();
// Update slope display
document.getElementById('tangentSlope').textContent = slope.toFixed(3);
}
// Update arc length display
document.getElementById('arcLength').textContent = arcLength.toFixed(3);
animationFrames.parametricCalc = requestAnimationFrame(animateParametricCalc);
}
// Polar curve animation
function animatePolar() {
const ctx = contexts.polar;
const theta = parseFloat(document.getElementById('thetaRange').value);
const curve = polarCurves[polarType];
ctx.clearRect(0, 0, 500, 400);
drawGrid(ctx);
// Draw curve
ctx.strokeStyle = '#00ff00';
ctx.lineWidth = 2;
ctx.beginPath();
const steps = 1000;
const dtheta = theta / steps;
for (let i = 0; i <= steps; i++) {
const thetai = i * dtheta;
const r = curve.r(thetai);
const x = r * Math.cos(thetai);
const y = r * Math.sin(thetai);
const screen = toScreenCoords(x, y);
if (i === 0) {
ctx.moveTo(screen.x, screen.y);
} else {
ctx.lineTo(screen.x, screen.y);
}
}
ctx.stroke();
// Draw current point
const currentR = curve.r(theta);
const currentX = currentR * Math.cos(theta);
const currentY = currentR * Math.sin(theta);
const currentScreen = toScreenCoords(currentX, currentY);
ctx.fillStyle = '#ff0000';
ctx.fillRect(currentScreen.x - 4, currentScreen.y - 4, 8, 8);
// Draw radius line
ctx.strokeStyle = '#ffff00';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(250, 200);
ctx.lineTo(currentScreen.x, currentScreen.y);
ctx.stroke();
animationFrames.polar = requestAnimationFrame(animatePolar);
}
// Polar calculus visualization
function animatePolarCalc() {
const ctx = contexts.polarCalc;
const alpha = parseFloat(document.getElementById('alphaRange').value);
const beta = parseFloat(document.getElementById('betaRange').value);
const showArea = document.getElementById('showArea').checked;
const curve = polarCurves.cardioid; // Using cardioid for calc demo
ctx.clearRect(0, 0, 500, 400);
drawGrid(ctx);
// Draw full curve
ctx.strokeStyle = '#00ff00';
ctx.lineWidth = 2;
ctx.beginPath();
const steps = 1000;
const dtheta = 2 * Math.PI / steps;
for (let i = 0; i <= steps; i++) {
const theta = i * dtheta;
const r = curve.r(theta);
const x = r * Math.cos(theta);
const y = r * Math.sin(theta);
const screen = toScreenCoords(x, y, 60);
if (i === 0) {
ctx.moveTo(screen.x, screen.y);
} else {
ctx.lineTo(screen.x, screen.y);
}
}
ctx.stroke();
// Draw and calculate area
if (showArea && beta > alpha) {
ctx.fillStyle = 'rgba(255, 0, 0, 0.3)';
ctx.beginPath();
ctx.moveTo(250, 200);
const areaSteps = 100;
const dtheta2 = (beta - alpha) / areaSteps;
let area = 0;
for (let i = 0; i <= areaSteps; i++) {
const theta = alpha + i * dtheta2;
const r = curve.r(theta);
const x = r * Math.cos(theta);
const y = r * Math.sin(theta);
const screen = toScreenCoords(x, y, 60);
ctx.lineTo(screen.x, screen.y);
if (i > 0) {
area += 0.5 * r * r * dtheta2;
}
}
ctx.closePath();
ctx.fill();
// Update area display
document.getElementById('polarArea').textContent = area.toFixed(3);
}
// Calculate arc length
let arcLength = 0;
if (beta > alpha) {
const arcSteps = 100;
const dtheta3 = (beta - alpha) / arcSteps;
for (let i = 1; i <= arcSteps; i++) {
const theta = alpha + i * dtheta3;
const thetaPrev = alpha + (i - 1) * dtheta3;
const r = curve.r(theta);
const rPrev = curve.r(thetaPrev);
// Approximate dr/dtheta
const dr = (r - rPrev) / dtheta3;
arcLength += Math.sqrt(r * r + dr * dr) * dtheta3;
}
document.getElementById('polarArcLength').textContent = arcLength.toFixed(3);
}
animationFrames.polarCalc = requestAnimationFrame(animatePolarCalc);
}
// Control event listeners
document.getElementById('tRange').addEventListener('input', (e) => {
document.getElementById('tValue').textContent = `t = ${parseFloat(e.target.value).toFixed(2)}`;
});
document.getElementById('speedRange').addEventListener('input', (e) => {
document.getElementById('speedValue').textContent = `Speed: ${parseFloat(e.target.value).toFixed(1)}x`;
});
document.getElementById('t0Range').addEventListener('input', (e) => {
document.getElementById('t0Value').textContent = `t₀ = ${parseFloat(e.target.value).toFixed(2)}`;
});
document.getElementById('thetaRange').addEventListener('input', (e) => {
document.getElementById('thetaValue').textContent = `θ = ${parseFloat(e.target.value).toFixed(2)}`;
});
document.getElementById('alphaRange').addEventListener('input', (e) => {
document.getElementById('alphaValue').textContent = `α = ${parseFloat(e.target.value).toFixed(2)}`;
});
document.getElementById('betaRange').addEventListener('input', (e) => {
document.getElementById('betaValue').textContent = `β = ${parseFloat(e.target.value).toFixed(2)}`;
});
// Example setters
function setParametricExample(type) {
parametricType = type;
const curve = parametricCurves[type];
document.getElementById('currentParametric').textContent = curve.name;
document.getElementById('parametricEquations').textContent = curve.equations;
document.getElementById('tRange').max = curve.tMax;
document.getElementById('tRange').value = curve.tMax;
document.getElementById('tValue').textContent = `t = ${curve.tMax.toFixed(2)}`;
}
function setPolarExample(type) {
polarType = type;
const curve = polarCurves[type];
document.getElementById('currentPolar').textContent = curve.name;
document.getElementById('polarEquation').textContent = curve.equation;
document.getElementById('thetaRange').max = curve.thetaMax;
document.getElementById('thetaRange').value = curve.thetaMax;
document.getElementById('thetaValue').textContent = `θ = ${curve.thetaMax.toFixed(2)}`;
}
// Initialize canvas for active tab
function initializeCanvas(tabId) {
// Cancel all animations
Object.values(animationFrames).forEach(frame => {
if (frame) cancelAnimationFrame(frame);
});
// Start appropriate animation
switch (tabId) {
case 'parametric':
animateParametric();
break;
case 'parametric-calc':
animateParametricCalc();
break;
case 'polar':
animatePolar();
break;
case 'polar-calc':
animatePolarCalc();
break;
}
}
// Start with parametric tab
initializeCanvas('parametric');
</script>
</body>
</html>