Transform a parent function (e.g., y = x²) based on specified parameters.
y = x² (Quadratic)
y = √x (Square Root)
y = |x| (Absolute Value)
y = sin(x) (Sine)
y = cos(x) (Cosine)
y = log(x) (Logarithmic)
y = e^x (Exponential)
Example Parent Function: y = x²
No
Yes
No
Yes
Understanding Graph Transformations
Graph transformations are operations that move, resize, or reflect a parent graph on the coordinate plane. These transformations allow us to analyze and sketch complex functions by relating them to simpler, well-known functions (parent functions).
The General Form
A general form for a transformed function is often represented as:
y = a * f(b(x - h)) + k
Where:
f(x) is the parent function (e.g., x², √x, |x|, sin(x)).
a represents vertical stretches and compressions. If |a| > 1, it's a stretch. If 0 < |a| < 1, it's a compression. If a is negative, it also includes a reflection across the x-axis.
b represents horizontal stretches and compressions. If |b| > 1, it's a compression. If 0 < |b| < 1, it's a stretch. If b is negative, it also includes a reflection across the y-axis.
h represents horizontal shifts. A positive h shifts the graph h units to the right, while a negative h shifts it |h| units to the left. Note the (x - h) term.
k represents vertical shifts. A positive k shifts the graph k units up, while a negative k shifts it |k| units down.
How the Calculator Works
This calculator takes a selected parent function and applies the following transformations based on your input:
Horizontal Transformation (inside the function): The input x is transformed into b(x - h).
Vertical Transformation (outside the function): The result of the parent function is multiplied by a and then k is added.
Reflections:
If "Reflection across x-axis" is 'Yes', the entire expression is multiplied by -1 (equivalent to a = -a).
If "Reflection across y-axis" is 'Yes', the x inside the function is replaced with -x (equivalent to replacing b with -b).
The calculator constructs the new function string based on these rules. Note that for simplicity, reflections are applied directly to a and b if selected.
Example Use Case
Let's transform the parent function y = x².
Parent Function: y = x²
a = 3 (Vertical stretch by 3)
b = 0.5 (Horizontal stretch by 2)
h = -2 (Shift 2 units left)
k = 1 (Shift 1 unit up)
Reflection across x-axis: No
Reflection across y-axis: No
Applying the general form y = a * f(b(x - h)) + k:
y = 3 * (0.5 * (x - (-2)))² + 1
y = 3 * (0.5 * (x + 2))² + 1
Simplifying:
y = 3 * (0.25 * (x + 2)²) + 1
y = 0.75 * (x + 2)² + 1
The calculator will output this transformed function string.
function getElementValue(id) {
var element = document.getElementById(id);
if (element && element.value !== "") {
return parseFloat(element.value);
}
return NaN; // Return Not-a-Number if value is missing or not a valid number
}
function updateFunctionExample() {
var functionType = document.getElementById("functionType").value;
var functionExampleSpan = document.getElementById("functionExample");
var displayMap = {
"x^2": "y = x²",
"sqrt(x)": "y = √x",
"abs(x)": "y = |x|",
"sin(x)": "y = sin(x)",
"cos(x)": "y = cos(x)",
"log(x)": "y = log(x)",
"exp(x)": "y = e^x"
};
functionExampleSpan.textContent = displayMap[functionType] || "y = f(x)";
}
function calculateTransformation() {
var functionType = document.getElementById("functionType").value;
var a = getElementValue("a");
var b = getElementValue("b");
var h = getElementValue("h");
var k = getElementValue("k");
var reflectionX = document.getElementById("reflectionX").value === "true";
var reflectionY = document.getElementById("reflectionY").value === "true";
var resultDiv = document.getElementById("result");
resultDiv.textContent = ""; // Clear previous result
// Validate inputs
if (isNaN(a) || isNaN(b) || isNaN(h) || isNaN(k)) {
resultDiv.textContent = "Error: Please enter valid numbers for all parameters.";
resultDiv.style.backgroundColor = "#dc3545"; // Red for error
return;
}
// Apply reflections to parameters first
var effectiveA = a;
var effectiveB = b;
if (reflectionX) {
effectiveA *= -1;
}
if (reflectionY) {
effectiveB *= -1;
}
// Construct the transformed function string
var transformedFunctionString = "y = ";
var innerPart = "";
var outerPart = "";
// Handle horizontal transformation: b(x – h)
var innerExpression = "x";
if (effectiveB !== 1) {
innerExpression = effectiveB + "x";
}
if (h !== 0) {
if (h > 0) {
innerExpression = innerExpression.replace("x", "(x – " + h + ")");
} else {
innerExpression = innerExpression.replace("x", "(x + " + Math.abs(h) + ")");
}
}
// Special case: if innerExpression is just 'x' and b is 1, we don't need redundant parentheses unless h is involved
if (effectiveB === 1 && h === 0) {
innerExpression = "x";
} else if (effectiveB === 1 && h !== 0) {
innerExpression = "(x" + (h > 0 ? " – " + h : " + " + Math.abs(h)) + ")";
} else if (effectiveB !== 1 && h === 0) {
innerExpression = effectiveB + "x";
} else { // effectiveB !== 1 and h !== 0
innerExpression = effectiveB + "x" + (h > 0 ? " – " + h : " + " + Math.abs(h));
}
// Ensure parentheses around the inner part if it's not just 'x'
if (innerExpression !== "x") {
innerPart = "(" + innerExpression + ")";
} else {
innerPart = innerExpression;
}
// Combine parent function with inner part
var parentCall = "";
if (functionType === "x^2") {
parentCall = innerPart + "^2";
} else if (functionType === "sqrt(x)") {
parentCall = "√" + innerPart;
} else if (functionType === "abs(x)") {
parentCall = "|" + innerPart + "|";
} else if (functionType === "sin(x)") {
parentCall = "sin(" + innerPart + ")";
} else if (functionType === "cos(x)") {
parentCall = "cos(" + innerPart + ")";
} else if (functionType === "log(x)") {
parentCall = "log(" + innerPart + ")";
} else if (functionType === "exp(x)") {
parentCall = "e^(" + innerPart + ")";
} else {
parentCall = "f(" + innerPart + ")"; // Generic fallback
}
// Handle vertical transformation: a * f(…) + k
if (effectiveA !== 1) {
outerPart = effectiveA + " * " + parentCall;
} else {
outerPart = parentCall;
}
if (k !== 0) {
if (k > 0) {
outerPart += " + " + k;
} else {
outerPart += " – " + Math.abs(k);
}
}
transformedFunctionString += outerPart;
// Basic simplification for common cases (can be expanded)
transformedFunctionString = transformedFunctionString.replace(/\+-/g, '-').replace(/ \+ -/g, ' – '); // Fix +- to –
transformedFunctionString = transformedFunctionString.replace(/1 \* /g, "); // Remove 1 *
transformedFunctionString = transformedFunctionString.replace(/ \+ 0/g, "); // Remove + 0
transformedFunctionString = transformedFunctionString.replace(/ – 0/g, "); // Remove – 0
// More specific simplifications
if (functionType === "x^2") {
if (effectiveA === 1 && h === 0 && k === 0 && !reflectionX && !reflectionY) {
transformedFunctionString = "y = x^2"; // Base case
} else if (effectiveA === 1 && k === 0 && !reflectionX && !reflectionY) {
// y = (b(x-h))^2 simplified
var simplifiedInner = "";
if (b === 1 && h === 0) simplifiedInner = "x";
else if (b === 1) simplifiedInner = "(x" + (h > 0 ? " – " + h : " + " + Math.abs(h)) + ")";
else simplifiedInner = b + "x" + (h > 0 ? " – " + h : " + " + Math.abs(h));
transformedFunctionString = "y = (" + simplifiedInner + ")^2";
} else if (effectiveB === 1 && effectiveA === 1 && !reflectionX && !reflectionY) {
// y = (x-h)^2 + k
transformedFunctionString = "y = (x" + (h > 0 ? " – " + h : " + " + Math.abs(h)) + ")^2 + " + k;
}
}
// Handle cases where initial value is zero, leading to x^2 without explicit factor
if (functionType === "x^2" && effectiveA === 1 && effectiveB === 1 && h === 0 && k === 0 && !reflectionX && !reflectionY) {
transformedFunctionString = "y = x^2";
}
resultDiv.textContent = transformedFunctionString;
resultDiv.style.backgroundColor = "var(–success-green)"; // Reset to green
}
// Initialize the example function on load
window.onload = updateFunctionExample;