Skip to content

Commit 6d5502f

Browse files
committed
Add Shortcode to solve parabola_from_slopes
1 parent e4b6474 commit 6d5502f

3 files changed

Lines changed: 374 additions & 2 deletions

File tree

content/_index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ width: normal
1212

1313
{{< home/quad_eq >}}
1414

15-
{{< home/parabola_solver >}}
15+
{{< home/parabola_solver >}}
16+
17+
{{< home/parabola_from_slopes x1="0" y1="1" m1="2" x2="2" y2="9" m2="6" >}}

content/exercises/graded-assignments/statistics-1/q1.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,18 @@ Find the cubic passing through (-1, 0) and (1, 4) with slopes of 3 and 15 at tho
112112

113113
### Your Own Points and Slopes
114114
Enter your own values to find the equation.
115-
{{< home/cubic_from_points_slopes >}}
115+
{{< home/cubic_from_points_slopes >}}
116+
117+
118+
119+
Let's find the value of `a` for the parabola equation $y=ax^2 + bx + c$ that passes through points (3, 2) and (2, 3), with slopes 31 at x=3 and 14 at x=2.
120+
121+
{{< home/parabola_from_slopes x1="3" y1="2" m1="31" x2="2" y2="3" m2="14" >}}
122+
123+
---
124+
125+
### A Consistent Example
126+
Let's find the parabola for two points and slopes that are consistent. For a parabola with the equation $y = x^2 + 2x + 1$:
127+
- Passes through (0, 1), with slope 2.
128+
- Passes through (2, 9), with slope 6.
129+
{{< home/parabola_from_slopes x1="0" y1="1" m1="2" x2="2" y2="9" m2="6" >}}
Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
{{/*
2+
Hugo Shortcode to find the equation of a parabola (y = ax^2 + bx + c) given two points and the slope at each.
3+
4+
Usage:
5+
{{< parabola_from_slopes x1="3" y1="2" m1="31" x2="2" y2="3" m2="14" >}}
6+
*/}}
7+
8+
<script src="https://cdn.jsdelivr.net/npm/mathjs@11.11.2/lib/browser/math.min.js"></script>
9+
10+
<style>
11+
/* Scoped CSS for the solver */
12+
.parabola-slopes-solver-container {
13+
max-width: 800px;
14+
margin: 2rem auto;
15+
padding: 2.5rem;
16+
background-color: #fefefe;
17+
border: 1px solid #e0e0e0;
18+
border-radius: 12px;
19+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
20+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
21+
color: #333;
22+
}
23+
24+
.parabola-slopes-solver-container h3 {
25+
text-align: center;
26+
color: #007bff;
27+
margin-bottom: 2rem;
28+
font-size: 1.8rem;
29+
}
30+
31+
.equation-display {
32+
font-family: 'Times New Roman', Times, serif;
33+
font-style: italic;
34+
font-size: 1.8rem;
35+
text-align: center;
36+
margin-bottom: 2rem;
37+
color: #1a1a1a;
38+
background-color: #f0f8ff;
39+
padding: 1rem;
40+
border-radius: 8px;
41+
border: 1px dashed #cce5ff;
42+
}
43+
44+
.input-row {
45+
display: flex;
46+
flex-wrap: wrap;
47+
gap: 1.5rem;
48+
justify-content: center;
49+
margin-bottom: 2rem;
50+
}
51+
52+
.input-group {
53+
display: flex;
54+
flex-direction: column;
55+
align-items: center;
56+
flex: 1 1 150px;
57+
}
58+
59+
.input-group label {
60+
font-weight: 600;
61+
margin-bottom: 0.5rem;
62+
color: #555;
63+
text-align: center;
64+
}
65+
66+
.input-group input[type="number"] {
67+
width: 100%;
68+
max-width: 150px;
69+
padding: 0.8rem;
70+
border: 1px solid #ccc;
71+
border-radius: 6px;
72+
font-size: 1.1rem;
73+
text-align: center;
74+
transition: border-color 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
75+
}
76+
77+
.input-group input:focus {
78+
outline: none;
79+
border-color: #007bff;
80+
box-shadow: 0 0 8px rgba(0, 123, 255, 0.4);
81+
}
82+
83+
.solver-button-container {
84+
text-align: center;
85+
}
86+
87+
.solver-button {
88+
padding: 1rem 2.5rem;
89+
background-color: #007bff;
90+
color: #fff;
91+
border: none;
92+
border-radius: 8px;
93+
font-size: 1.1rem;
94+
font-weight: bold;
95+
cursor: pointer;
96+
transition: background-color 0.3s ease-in-out, transform 0.1s ease-in-out;
97+
}
98+
99+
.solver-button:hover {
100+
background-color: #0056b3;
101+
transform: translateY(-2px);
102+
}
103+
104+
.solver-result {
105+
margin-top: 2.5rem;
106+
padding: 1.8rem;
107+
background-color: #eaf6ff;
108+
border-radius: 10px;
109+
border: 1px solid #b3d9ff;
110+
line-height: 1.8;
111+
font-size: 1.1rem;
112+
color: #1a2a3a;
113+
word-wrap: break-word;
114+
}
115+
116+
.result-item {
117+
margin-bottom: 0.8rem;
118+
}
119+
120+
.result-label {
121+
font-weight: 700;
122+
color: #0056b3;
123+
}
124+
125+
.result-value {
126+
font-family: 'Courier New', Courier, monospace;
127+
background-color: #fff;
128+
padding: 0.2em 0.5em;
129+
border-radius: 4px;
130+
border: 1px solid #d4e3f1;
131+
}
132+
133+
.solver-error {
134+
color: #dc3545;
135+
font-weight: bold;
136+
}
137+
138+
139+
html:is(.dark) {
140+
.parabola-slopes-solver-container {
141+
background-color: #181c24;
142+
border-color: #232a36;
143+
color: #e0e6ef;
144+
box-shadow: 0 6px 20px rgba(0,0,0,0.32);
145+
}
146+
.parabola-slopes-solver-container h3 {
147+
color: #6cb6ff;
148+
}
149+
.equation-display {
150+
background-color: #232a36;
151+
color: #e0e6ef;
152+
border-color: #2d3a4d;
153+
}
154+
.input-group label {
155+
color: #b3c6e0;
156+
}
157+
.input-group input[type="number"] {
158+
background-color: #232a36;
159+
color: #e0e6ef;
160+
border-color: #2d3a4d;
161+
}
162+
.input-group input:focus {
163+
border-color: #6cb6ff;
164+
box-shadow: 0 0 8px rgba(108,182,255,0.4);
165+
}
166+
.solver-button {
167+
background-color: #2563eb;
168+
color: #fff;
169+
}
170+
.solver-button:hover {
171+
background-color: #174ea6;
172+
}
173+
.solver-result {
174+
background-color: #232a36;
175+
border-color: #2d3a4d;
176+
color: #e0e6ef;
177+
}
178+
.result-label {
179+
color: #6cb6ff;
180+
}
181+
.result-value {
182+
background-color: #181c24;
183+
color: #e0e6ef;
184+
border-color: #2d3a4d;
185+
}
186+
.solver-error {
187+
color: #ff6b6b;
188+
}
189+
}
190+
191+
@media (max-width: 600px) {
192+
.parabola-slopes-solver-container {
193+
padding: 1rem;
194+
max-width: 100vw;
195+
border-radius: 0;
196+
box-shadow: none;
197+
}
198+
.equation-display {
199+
font-size: 1.2rem;
200+
padding: 0.5rem;
201+
}
202+
.input-row {
203+
flex-direction: column;
204+
gap: 0.8rem;
205+
margin-bottom: 1rem;
206+
}
207+
.input-group {
208+
flex: 1 1 100%;
209+
align-items: stretch;
210+
}
211+
.input-group input[type="number"] {
212+
max-width: 100%;
213+
font-size: 1rem;
214+
padding: 0.5rem;
215+
}
216+
.solver-button {
217+
width: 100%;
218+
padding: 0.8rem 0;
219+
font-size: 1rem;
220+
}
221+
.solver-result {
222+
padding: 1rem;
223+
font-size: 1rem;
224+
}
225+
}
226+
227+
</style>
228+
229+
<div class="parabola-slopes-solver-container">
230+
<h3>Find Parabola Equation from Two Points and Slopes</h3>
231+
232+
<div class="equation-display">
233+
y = ax² + bx + c
234+
</div>
235+
236+
<div class="input-row">
237+
<div class="input-group">
238+
<label>Point 1 (x₁, y₁):</label>
239+
<input type="number" id="x1-input-{{ .Ordinal }}" value="{{ .Get "x1" | default "3" }}">
240+
<input type="number" id="y1-input-{{ .Ordinal }}" value="{{ .Get "y1" | default "2" }}">
241+
</div>
242+
<div class="input-group">
243+
<label>Slope at x₁ (m₁):</label>
244+
<input type="number" id="m1-input-{{ .Ordinal }}" value="{{ .Get "m1" | default "31" }}">
245+
</div>
246+
<div class="input-group">
247+
<label>Point 2 (x₂, y₂):</label>
248+
<input type="number" id="x2-input-{{ .Ordinal }}" value="{{ .Get "x2" | default "2" }}">
249+
<input type="number" id="y2-input-{{ .Ordinal }}" value="{{ .Get "y2" | default "3" }}">
250+
</div>
251+
<div class="input-group">
252+
<label>Slope at x₂ (m₂):</label>
253+
<input type="number" id="m2-input-{{ .Ordinal }}" value="{{ .Get "m2" | default "14" }}">
254+
</div>
255+
</div>
256+
257+
<div class="solver-button-container">
258+
<button class="solver-button" onclick="findCoefficientsFromSlopes('{{ .Ordinal }}')">Find Coefficients</button>
259+
</div>
260+
261+
<div class="solver-result" id="results-output-{{ .Ordinal }}">
262+
Results will appear here.
263+
</div>
264+
</div>
265+
266+
<script>
267+
// Global function to solve for a, b, and c using slopes and points.
268+
window.findCoefficientsFromSlopes = function(ordinal) {
269+
const x1 = parseFloat(document.getElementById('x1-input-' + ordinal).value);
270+
const y1 = parseFloat(document.getElementById('y1-input-' + ordinal).value);
271+
const m1 = parseFloat(document.getElementById('m1-input-' + ordinal).value);
272+
const x2 = parseFloat(document.getElementById('x2-input-' + ordinal).value);
273+
const y2 = parseFloat(document.getElementById('y2-input-' + ordinal).value);
274+
const m2 = parseFloat(document.getElementById('m2-input-' + ordinal).value);
275+
const output = document.getElementById('results-output-' + ordinal);
276+
277+
if (typeof math === 'undefined') {
278+
output.innerHTML = '<span class="solver-error">Error: Math.js library not loaded.</span>';
279+
return;
280+
}
281+
282+
try {
283+
if (isNaN(x1) || isNaN(y1) || isNaN(m1) || isNaN(x2) || isNaN(y2) || isNaN(m2)) {
284+
throw new Error("Please enter valid numbers for all inputs.");
285+
}
286+
287+
if (x1 === x2) {
288+
throw new Error("The x-coordinates of the two points must be different to find a unique solution.");
289+
}
290+
291+
// --- Step 1: Solve for 'a' and 'b' using the slopes ---
292+
// System of equations:
293+
// 2*a*x1 + b = m1
294+
// 2*a*x2 + b = m2
295+
296+
// Coefficient matrix for [a, b]
297+
const A_matrix = [
298+
[2 * x1, 1],
299+
[2 * x2, 1]
300+
];
301+
302+
// Constant vector [m1, m2]
303+
const B_vector = [m1, m2];
304+
305+
// Solve using Math.js
306+
const solution_ab = math.lusolve(A_matrix, B_vector);
307+
308+
if (!solution_ab || solution_ab.length === 0) {
309+
output.innerHTML = '<span class="solver-error">Could not find a unique solution for a and b from the slopes.</span>';
310+
return;
311+
}
312+
313+
const a_solution = solution_ab[0][0];
314+
const b_solution = solution_ab[1][0];
315+
316+
// --- Step 2: Solve for 'c' using one of the points ---
317+
// Using Point 1: y1 = a*x1^2 + b*x1 + c
318+
// c = y1 - a*x1^2 - b*x1
319+
const c_solution = y1 - a_solution * Math.pow(x1, 2) - b_solution * x1;
320+
321+
// --- Step 3: Verify the consistency of the solutions with the second point ---
322+
// Check if Point 2 satisfies the equation with the found a, b, and c
323+
const y2_calculated = a_solution * Math.pow(x2, 2) + b_solution * x2 + c_solution;
324+
const isConsistent = math.abs(y2_calculated - y2) < 1e-9; // Use tolerance for floating-point comparison
325+
326+
// --- Format the final output ---
327+
const a_formatted = Number(a_solution).toLocaleString(undefined, { maximumFractionDigits: 6 });
328+
const b_formatted = Number(b_solution).toLocaleString(undefined, { maximumFractionDigits: 6 });
329+
const c_formatted = Number(c_solution).toLocaleString(undefined, { maximumFractionDigits: 6 });
330+
const y2_calculated_formatted = Number(y2_calculated).toLocaleString(undefined, { maximumFractionDigits: 6 });
331+
332+
let consistencyMessage = '';
333+
if (isConsistent) {
334+
consistencyMessage = `<span style="color: green; font-weight: bold;">The inputs are consistent. A unique parabola exists.</span>`;
335+
} else {
336+
consistencyMessage = `<span style="color: #dc3545; font-weight: bold;">The inputs are inconsistent. No single parabola can pass through both points with the given slopes.</span>`;
337+
}
338+
339+
const resultHTML = `
340+
<div class="result-item"><span class="result-label">Result from Slopes:</span> <span class="result-value">a = ${a_formatted}</span>, <span class="result-value">b = ${b_formatted}</span></div>
341+
<div class="result-item"><span class="result-label">Calculated 'c' from Point 1:</span> <span class="result-value">c = ${c_formatted}</span></div>
342+
<hr style="margin: 1rem 0; border-color: #cce5ff;">
343+
<div class="result-item"><span class="result-label">Calculated Equation:</span> <span class="result-value">y = ${a_formatted}${b_formatted >= 0 ? '+' : ''} ${b_formatted}x ${c_formatted >= 0 ? '+' : ''} ${c_formatted}</span></div>
344+
<div class="result-item"><span class="result-label">Checking with Point 2 (${x2}, ${y2}):</span><br>
345+
If x = ${x2}, the calculated y is <span class="result-value">${y2_calculated_formatted}</span> (expected y is <span class="result-value">${y2}</span>).</div>
346+
<hr style="margin: 1rem 0; border-color: #cce5ff;">
347+
<div class="result-item">${consistencyMessage}</div>
348+
`;
349+
output.innerHTML = resultHTML;
350+
351+
} catch (error) {
352+
output.innerHTML = `<span class="solver-error">Error: ${error.message}</span>`;
353+
console.error("Solver error:", error);
354+
}
355+
}
356+
</script>

0 commit comments

Comments
 (0)