1+ {{/*
2+ Hugo Shortcode to find the equation of a CUBIC polynomial (y = ax^3 + bx^2 + cx + d)
3+ given two points and the slope at each of those points.
4+
5+ Usage:
6+ {{< cubic _from_points_slopes x1 ="0 " y1 ="1 " m1 ="0 " x2 ="2 " y2 ="9 " m2 ="12 " > }}
7+ (This solves for the cubic passing through (0,1) and (2,9) with slopes 0 and 12 at those points).
8+ The answer should be y = x^3 + 1.
9+ */}}
10+
11+ < script src ="https://cdn.jsdelivr.net/npm/mathjs@11.11.2/lib/browser/math.min.js "> </ script >
12+
13+ < style >
14+ /* Scoped CSS for the cubic equation solver */
15+ .cubic-eq-solver-container {
16+ max-width : 800px ;
17+ margin : 2rem auto;
18+ padding : 2.5rem ;
19+ background-color : # fefefe ;
20+ border : 1px solid # e0e0e0 ;
21+ border-radius : 12px ;
22+ box-shadow : 0 6px 20px rgba (0 , 0 , 0 , 0.08 );
23+ font-family : 'Segoe UI' , Tahoma, Geneva, Verdana, sans-serif;
24+ color : # 333 ;
25+ }
26+
27+ .cubic-eq-solver-container h3 {
28+ text-align : center;
29+ color : # 8c00b3 ; /* A different color for a cubic solver */
30+ margin-bottom : 2rem ;
31+ font-size : 1.8rem ;
32+ }
33+
34+ .cubic-equation-formula {
35+ font-family : 'Times New Roman' , Times, serif;
36+ font-style : italic;
37+ font-size : 1.8rem ;
38+ text-align : center;
39+ margin-bottom : 2rem ;
40+ color : # 1a1a1a ;
41+ background-color : # f7e6ff ;
42+ padding : 1rem ;
43+ border-radius : 8px ;
44+ border : 1px dashed # e0c2ff ;
45+ }
46+
47+ .input-row {
48+ display : flex;
49+ flex-wrap : wrap;
50+ gap : 1.5rem ;
51+ justify-content : center;
52+ margin-bottom : 2rem ;
53+ }
54+
55+ .input-group {
56+ display : flex;
57+ flex-direction : column;
58+ align-items : center;
59+ flex : 1 1 150px ; /* Flexbox for responsive layout */
60+ }
61+
62+ .input-group label {
63+ font-weight : 600 ;
64+ margin-bottom : 0.5rem ;
65+ color : # 555 ;
66+ text-align : center;
67+ }
68+
69+ .input-group input [type = "number" ] {
70+ width : 100% ;
71+ max-width : 150px ;
72+ padding : 0.8rem ;
73+ border : 1px solid # ccc ;
74+ border-radius : 6px ;
75+ font-size : 1.1rem ;
76+ text-align : center;
77+ transition : border-color 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
78+ }
79+
80+ .input-group input : focus {
81+ outline : none;
82+ border-color : # 8c00b3 ;
83+ box-shadow : 0 0 8px rgba (140 , 0 , 179 , 0.4 );
84+ }
85+
86+ .solver-button-container {
87+ text-align : center;
88+ }
89+
90+ .solver-button {
91+ padding : 1rem 2.5rem ;
92+ background-color : # 8c00b3 ;
93+ color : # fff ;
94+ border : none;
95+ border-radius : 8px ;
96+ font-size : 1.1rem ;
97+ font-weight : bold;
98+ cursor : pointer;
99+ transition : background-color 0.3s ease-in-out, transform 0.1s ease-in-out;
100+ }
101+
102+ .solver-button : hover {
103+ background-color : # 6a008c ;
104+ transform : translateY (-2px );
105+ }
106+
107+ .solver-result {
108+ margin-top : 2.5rem ;
109+ padding : 1.8rem ;
110+ background-color : # f3e6ff ;
111+ border-radius : 10px ;
112+ border : 1px solid # c299e6 ;
113+ line-height : 1.8 ;
114+ font-size : 1.1rem ;
115+ color : # 2e003a ;
116+ word-wrap : break-word;
117+ }
118+
119+ .result-item {
120+ margin-bottom : 0.8rem ;
121+ }
122+
123+ .result-label {
124+ font-weight : 700 ;
125+ color : # 8c00b3 ;
126+ }
127+
128+ .result-value {
129+ font-family : 'Courier New' , Courier, monospace;
130+ background-color : # fff ;
131+ padding : 0.2em 0.5em ;
132+ border-radius : 4px ;
133+ border : 1px solid # e0c2ff ;
134+ }
135+
136+ .solver-error {
137+ color : # dc3545 ;
138+ font-weight : bold;
139+ }
140+
141+ /* Dark mode support */
142+ html : is (.dark ) {
143+ .cubic-eq-solver-container {
144+ background-color : # 1a1622 ;
145+ border-color : # 32284a ;
146+ color : # e6e1f7 ;
147+ box-shadow : 0 6px 20px rgba (0 , 0 , 0 , 0.35 );
148+ }
149+ .cubic-eq-solver-container h3 {
150+ color : # e08cff ;
151+ }
152+ .cubic-equation-formula {
153+ background-color : # 2d1e3a ;
154+ color : # f3e6ff ;
155+ border-color : # 6a3fa7 ;
156+ }
157+ .input-group label {
158+ color : # bfa7e6 ;
159+ }
160+ .input-group input [type = "number" ] {
161+ background-color : # 221b2e ;
162+ color : # f3e6ff ;
163+ border-color : # 4a3570 ;
164+ }
165+ .input-group input : focus {
166+ border-color : # e08cff ;
167+ box-shadow : 0 0 8px rgba (224 , 140 , 255 , 0.3 );
168+ }
169+ .solver-button {
170+ background-color : # e08cff ;
171+ color : # 1a1622 ;
172+ }
173+ .solver-button : hover {
174+ background-color : # b366d6 ;
175+ }
176+ .solver-result {
177+ background-color : # 2d1e3a ;
178+ border-color : # 6a3fa7 ;
179+ color : # f3e6ff ;
180+ }
181+ .result-label {
182+ color : # e08cff ;
183+ }
184+ .result-value {
185+ background-color : # 1a1622 ;
186+ border-color : # 6a3fa7 ;
187+ color : # f3e6ff ;
188+ }
189+ .solver-error {
190+ color : # ff6b8a ;
191+ }
192+ }
193+
194+ @media (max-width : 600px ) {
195+ .cubic-eq-solver-container {
196+ padding : 1rem ;
197+ max-width : 98vw ;
198+ }
199+ .cubic-equation-formula {
200+ font-size : 1.2rem ;
201+ padding : 0.5rem ;
202+ }
203+ .input-row {
204+ flex-direction : column;
205+ gap : 0.8rem ;
206+ margin-bottom : 1.2rem ;
207+ }
208+ .input-group {
209+ flex : 1 1 100% ;
210+ align-items : stretch;
211+ }
212+ .input-group input [type = "number" ] {
213+ max-width : 100% ;
214+ font-size : 1rem ;
215+ padding : 0.6rem ;
216+ }
217+ .solver-button {
218+ width : 100% ;
219+ padding : 0.8rem 0 ;
220+ font-size : 1rem ;
221+ }
222+ .solver-result {
223+ padding : 1rem ;
224+ font-size : 1rem ;
225+ }
226+ }
227+ </ style >
228+
229+ < div class ="cubic-eq-solver-container ">
230+ < h3 > Cubic Equation from Two Points and Two Slopes</ h3 >
231+
232+ < div class ="parabola-equation-formula ">
233+ y = ax³ + bx² + cx + d
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 "0" }}">
240+ < input type ="number " id ="y1-input-{{ .Ordinal }} " value ="{{ .Get "y1 " | default "1" }}">
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 "0" }}">
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 "9" }}">
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 "12" }}">
254+ </ div >
255+ </ div >
256+
257+ < div class ="solver-button-container ">
258+ < button class ="solver-button " onclick ="findCubicEquation('{{ .Ordinal }}') "> Find Equation</ button >
259+ </ div >
260+
261+ < div class ="solver-result " id ="equation-output-{{ .Ordinal }} ">
262+ Equation coefficients will appear here.
263+ </ div >
264+ </ div >
265+
266+ < script >
267+ // Global function to solve the system of equations for a cubic polynomial.
268+ window . findCubicEquation = 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 ( 'equation-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." ) ;
289+ }
290+
291+ // --- Formulate the system of linear equations ---
292+ // We need to solve for a, b, c, and d.
293+ // Equation 1: a*x1^3 + b*x1^2 + c*x1 + d = y1
294+ // Equation 2: a*x2^3 + b*x2^2 + c*x2 + d = y2
295+ // Equation 3: 3*a*x1^2 + 2*b*x1 + c = m1
296+ // Equation 4: 3*a*x2^2 + 2*b*x2 + c = m2
297+
298+ // Create the coefficient matrix A_matrix for [a, b, c, d]
299+ const A_matrix = [
300+ [ x1 * x1 * x1 , x1 * x1 , x1 , 1 ] ,
301+ [ x2 * x2 * x2 , x2 * x2 , x2 , 1 ] ,
302+ [ 3 * x1 * x1 , 2 * x1 , 1 , 0 ] ,
303+ [ 3 * x2 * x2 , 2 * x2 , 1 , 0 ]
304+ ] ;
305+
306+ // Create the constant vector B_vector
307+ const B_vector = [ y1 , y2 , m1 , m2 ] ;
308+
309+ // Use Math.js to solve the linear system A_matrix * X = B_vector
310+ // where X is the vector [a, b, c, d]
311+ const solution = math . lusolve ( A_matrix , B_vector ) ;
312+
313+ if ( ! solution || solution . length === 0 ) {
314+ output . innerHTML = '<span class="solver-error">Could not find a unique solution. Please check the input values.</span>' ;
315+ return ;
316+ }
317+
318+ // Extract the coefficients a, b, c, and d from the solution vector
319+ const a = math . format ( solution [ 0 ] [ 0 ] , { precision : 6 } ) ;
320+ const b = math . format ( solution [ 1 ] [ 0 ] , { precision : 6 } ) ;
321+ const c = math . format ( solution [ 2 ] [ 0 ] , { precision : 6 } ) ;
322+ const d = math . format ( solution [ 3 ] [ 0 ] , { precision : 6 } ) ;
323+
324+ // Construct the final equation string with proper signs
325+ const equation = `y = ${ a } x³ ${ b >= 0 ? '+' : '' } ${ b } x² ${ c >= 0 ? '+' : '' } ${ c } x ${ d >= 0 ? '+' : '' } ${ d } ` ;
326+
327+ const resultHTML = `
328+ <div class="result-item"><span class="result-label">Coefficient a:</span> <span class="result-value">${ a } </span></div>
329+ <div class="result-item"><span class="result-label">Coefficient b:</span> <span class="result-value">${ b } </span></div>
330+ <div class="result-item"><span class="result-label">Coefficient c:</span> <span class="result-value">${ c } </span></div>
331+ <div class="result-item"><span class="result-label">Coefficient d:</span> <span class="result-value">${ d } </span></div>
332+ <hr style="margin: 1rem 0; border-color: #c299e6;">
333+ <div class="result-item"><span class="result-label">Cubic Equation:</span> <span class="result-value">${ equation } </span></div>
334+ ` ;
335+ output . innerHTML = resultHTML ;
336+
337+ } catch ( error ) {
338+ output . innerHTML = `<span class="solver-error">Error: ${ error . message } </span>` ;
339+ console . error ( "Cubic equation solver error:" , error ) ;
340+ }
341+ }
342+ </ script >
0 commit comments