12 KiB
12 KiB
Algebra Reference
Algebraic concepts and interactive visualizations for middle school to high school.
Variables & Expressions
Visual Variables
// Mystery box representation
function drawVariable(name, value, canvas) {
const ctx = canvas.getContext('2d');
// Draw box
ctx.fillStyle = '#667eea';
ctx.fillRect(50, 50, 100, 100);
ctx.strokeStyle = '#333';
ctx.lineWidth = 3;
ctx.strokeRect(50, 50, 100, 100);
// Variable name
ctx.fillStyle = 'white';
ctx.font = 'bold 40px Arial';
ctx.textAlign = 'center';
ctx.fillText(name, 100, 110);
// Value (revealed)
if (value !== undefined) {
ctx.fillStyle = '#FFD700';
ctx.font = 'bold 30px Arial';
ctx.fillText(`= ${value}`, 100, 170);
} else {
ctx.fillStyle = '#FFF';
ctx.font = '20px Arial';
ctx.fillText('?', 100, 170);
}
}
Expression Evaluator
function evaluateExpression(expr, variables) {
// Replace variables with values
let result = expr;
for (const [name, value] of Object.entries(variables)) {
result = result.replace(new RegExp(name, 'g'), value);
}
try {
return {
expression: expr,
substituted: result,
result: eval(result),
steps: showSteps(expr, variables)
};
} catch (e) {
return { error: 'Invalid expression' };
}
}
function showSteps(expr, variables) {
const steps = [];
steps.push(`Original: ${expr}`);
let current = expr;
for (const [name, value] of Object.entries(variables)) {
current = current.replace(new RegExp(name, 'g'), value);
steps.push(`Substitute ${name} = ${value}: ${current}`);
}
steps.push(`Evaluate: ${eval(current)}`);
return steps;
}
Linear Equations
Equation Solver
// Solve ax + b = c for x
function solveLinear(a, b, c) {
const x = (c - b) / a;
return {
equation: `${a}x + ${b} = ${c}`,
steps: [
`${a}x + ${b} = ${c}`,
`${a}x = ${c - b}`,
`x = ${(c - b)}/${a}`,
`x = ${x}`
],
solution: x,
verification: `${a}(${x}) + ${b} = ${a * x + b} ✓`
};
}
Balance Scale Visualization
function drawBalanceScale(left, right, canvas) {
const ctx = canvas.getContext('2d');
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
// Calculate balance
const diff = left - right;
const angle = Math.atan(diff / 10);
// Draw fulcrum
ctx.fillStyle = '#333';
ctx.beginPath();
ctx.moveTo(centerX - 20, centerY + 50);
ctx.lineTo(centerX, centerY);
ctx.lineTo(centerX + 20, centerY + 50);
ctx.closePath();
ctx.fill();
// Draw beam
ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate(angle);
ctx.fillStyle = '#8B4513';
ctx.fillRect(-150, -10, 300, 20);
// Left side
ctx.fillStyle = '#667eea';
ctx.fillRect(-140, -60, 80, 80);
ctx.fillStyle = 'white';
ctx.font = 'bold 24px Arial';
ctx.textAlign = 'center';
ctx.fillText(left, -100, -10);
// Right side
ctx.fillStyle = '#FF6347';
ctx.fillRect(60, -60, 80, 80);
ctx.fillStyle = 'white';
ctx.fillText(right, 100, -10);
ctx.restore();
// Status
ctx.fillStyle = '#333';
ctx.font = '20px Arial';
ctx.textAlign = 'center';
const status = Math.abs(diff) < 0.1 ? '⚖️ Balanced!' :
diff > 0 ? '⬅️ Left heavier' : '➡️ Right heavier';
ctx.fillText(status, centerX, centerY + 100);
}
Quadratic Equations
Quadratic Formula
function solveQuadratic(a, b, c) {
const discriminant = b * b - 4 * a * c;
const result = {
equation: `${a}x² + ${b}x + ${c} = 0`,
discriminant: discriminant,
a, b, c
};
if (discriminant > 0) {
const x1 = (-b + Math.sqrt(discriminant)) / (2 * a);
const x2 = (-b - Math.sqrt(discriminant)) / (2 * a);
result.solutions = [x1, x2];
result.type = 'Two real solutions';
result.message = '🎉 Two x-intercepts!';
} else if (discriminant === 0) {
const x = -b / (2 * a);
result.solutions = [x];
result.type = 'One real solution';
result.message = '🎯 One x-intercept (vertex on x-axis)!';
} else {
const realPart = -b / (2 * a);
const imagPart = Math.sqrt(-discriminant) / (2 * a);
result.solutions = [
`${realPart} + ${imagPart}i`,
`${realPart} - ${imagPart}i`
];
result.type = 'Two complex solutions';
result.message = '👻 No x-intercepts (complex numbers)!';
}
return result;
}
Parabola Grapher
function drawParabola(a, b, c, canvas) {
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
// Clear canvas
ctx.clearRect(0, 0, width, height);
// Draw axes
drawAxes(ctx, width, height);
// Calculate vertex
const vertexX = -b / (2 * a);
const vertexY = a * vertexX * vertexX + b * vertexX + c;
// Draw parabola
ctx.beginPath();
ctx.strokeStyle = '#667eea';
ctx.lineWidth = 3;
for (let x = -10; x <= 10; x += 0.1) {
const y = a * x * x + b * x + c;
const px = (x + 10) * (width / 20);
const py = height - ((y + 10) * (height / 20));
if (x === -10) ctx.moveTo(px, py);
else ctx.lineTo(px, py);
}
ctx.stroke();
// Mark vertex
const vx = (vertexX + 10) * (width / 20);
const vy = height - ((vertexY + 10) * (height / 20));
ctx.fillStyle = '#FF6347';
ctx.beginPath();
ctx.arc(vx, vy, 8, 0, Math.PI * 2);
ctx.fill();
// Vertex label
ctx.fillStyle = '#333';
ctx.font = '14px Arial';
ctx.fillText(`Vertex: (${vertexX.toFixed(2)}, ${vertexY.toFixed(2)})`,
vx + 10, vy - 10);
// Draw axis of symmetry
ctx.strokeStyle = '#FFD700';
ctx.setLineDash([5, 5]);
ctx.beginPath();
ctx.moveTo(vx, 0);
ctx.lineTo(vx, height);
ctx.stroke();
ctx.setLineDash([]);
return { vertexX, vertexY };
}
function drawAxes(ctx, width, height) {
ctx.strokeStyle = '#CCC';
ctx.lineWidth = 1;
// X-axis
ctx.beginPath();
ctx.moveTo(0, height / 2);
ctx.lineTo(width, height / 2);
ctx.stroke();
// Y-axis
ctx.beginPath();
ctx.moveTo(width / 2, 0);
ctx.lineTo(width / 2, height);
ctx.stroke();
// Grid
ctx.strokeStyle = '#F0F0F0';
for (let i = 0; i < width; i += width / 20) {
ctx.beginPath();
ctx.moveTo(i, 0);
ctx.lineTo(i, height);
ctx.stroke();
}
for (let i = 0; i < height; i += height / 20) {
ctx.beginPath();
ctx.moveTo(0, i);
ctx.lineTo(width, i);
ctx.stroke();
}
}
Functions
Function Visualizer
const commonFunctions = {
linear: (x, m, b) => m * x + b,
quadratic: (x, a, b, c) => a * x * x + b * x + c,
cubic: (x, a) => a * x * x * x,
exponential: (x, a) => Math.pow(a, x),
logarithmic: (x, a) => Math.log(x) / Math.log(a),
sine: (x, a) => a * Math.sin(x),
cosine: (x, a) => a * Math.cos(x),
absolute: (x) => Math.abs(x),
squareRoot: (x) => Math.sqrt(x)
};
function plotFunction(fn, xMin, xMax, canvas) {
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
drawAxes(ctx, width, height);
ctx.beginPath();
ctx.strokeStyle = '#667eea';
ctx.lineWidth = 3;
const step = (xMax - xMin) / width;
for (let x = xMin; x <= xMax; x += step) {
try {
const y = fn(x);
if (!isNaN(y) && isFinite(y)) {
const px = ((x - xMin) / (xMax - xMin)) * width;
const py = height - ((y - (-10)) / 20) * height;
if (x === xMin) ctx.moveTo(px, py);
else ctx.lineTo(px, py);
}
} catch (e) {
// Skip invalid points
}
}
ctx.stroke();
}
Domain & Range Finder
function analyzeFunctionDomainRange(type, params) {
const analysis = {
type: type,
params: params
};
switch(type) {
case 'linear':
analysis.domain = '(-∞, ∞)';
analysis.range = '(-∞, ∞)';
break;
case 'quadratic':
const a = params.a;
const vertex = -params.b / (2 * a);
const vertexY = a * vertex * vertex + params.b * vertex + params.c;
analysis.domain = '(-∞, ∞)';
analysis.range = a > 0 ? `[${vertexY.toFixed(2)}, ∞)` :
`(-∞, ${vertexY.toFixed(2)}]`;
analysis.vertex = { x: vertex, y: vertexY };
break;
case 'squareRoot':
analysis.domain = '[0, ∞)';
analysis.range = '[0, ∞)';
break;
case 'logarithmic':
analysis.domain = '(0, ∞)';
analysis.range = '(-∞, ∞)';
break;
}
return analysis;
}
Systems of Equations
Graphical Solution
function solveSystemGraphically(eq1, eq2, canvas) {
// eq1 and eq2 are linear equations in form {m: slope, b: intercept}
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
drawAxes(ctx, width, height);
// Plot first equation
ctx.strokeStyle = '#667eea';
ctx.lineWidth = 3;
ctx.beginPath();
for (let x = -10; x <= 10; x += 0.1) {
const y = eq1.m * x + eq1.b;
const px = (x + 10) * (width / 20);
const py = height - ((y + 10) * (height / 20));
if (x === -10) ctx.moveTo(px, py);
else ctx.lineTo(px, py);
}
ctx.stroke();
// Plot second equation
ctx.strokeStyle = '#FF6347';
ctx.beginPath();
for (let x = -10; x <= 10; x += 0.1) {
const y = eq2.m * x + eq2.b;
const px = (x + 10) * (width / 20);
const py = height - ((y + 10) * (height / 20));
if (x === -10) ctx.moveTo(px, py);
else ctx.lineTo(px, py);
}
ctx.stroke();
// Find intersection
// eq1.m * x + eq1.b = eq2.m * x + eq2.b
// (eq1.m - eq2.m) * x = eq2.b - eq1.b
const x = (eq2.b - eq1.b) / (eq1.m - eq2.m);
const y = eq1.m * x + eq1.b;
// Mark intersection
const px = (x + 10) * (width / 20);
const py = height - ((y + 10) * (height / 20));
ctx.fillStyle = '#FFD700';
ctx.beginPath();
ctx.arc(px, py, 10, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = '#333';
ctx.font = 'bold 16px Arial';
ctx.fillText(`(${x.toFixed(2)}, ${y.toFixed(2)})`, px + 15, py - 15);
return { x, y };
}
Polynomials
Polynomial Evaluator
function evaluatePolynomial(coefficients, x) {
// coefficients = [a0, a1, a2, ...] for a0 + a1*x + a2*x^2 + ...
let result = 0;
let term = 1;
const terms = [];
for (let i = 0; i < coefficients.length; i++) {
const value = coefficients[i] * term;
result += value;
terms.push({
coefficient: coefficients[i],
power: i,
value: value,
display: i === 0 ? `${coefficients[i]}` :
i === 1 ? `${coefficients[i]}x` :
`${coefficients[i]}x^${i}`
});
term *= x;
}
return {
x: x,
result: result,
terms: terms,
polynomial: formatPolynomial(coefficients)
};
}
function formatPolynomial(coefficients) {
return coefficients.map((c, i) => {
if (c === 0) return '';
if (i === 0) return `${c}`;
if (i === 1) return `${c}x`;
return `${c}x^${i}`;
}).filter(t => t).join(' + ');
}
Interactive Elements
Slider for Coefficients
function createCoefficientSliders(equation) {
const sliders = {};
const params = ['a', 'b', 'c'];
params.forEach(param => {
const slider = document.createElement('input');
slider.type = 'range';
slider.min = -10;
slider.max = 10;
slider.step = 0.1;
slider.value = equation[param] || 0;
slider.addEventListener('input', () => {
equation[param] = parseFloat(slider.value);
updateGraph();
updateEquationDisplay();
});
sliders[param] = slider;
});
return sliders;
}
Summary
Algebra patterns provide:
- Visual equation solving with balance scales
- Interactive function graphing
- Step-by-step solutions
- Real-time parameter manipulation
- Geometric representations of algebraic concepts
These tools make abstract algebra concrete and interactive!