StepWise-Math-AI / examples /005-visual-proof-sum-of-rhombus-diagonals.json
DreamyDetective's picture
feat: added application files
69ac033 verified
{
"appName": "VisualMath AI Export",
"exportedAt": "2025-11-24T19:41:49.518Z",
"input": {
"mode": "text",
"text": "Area of a Rhombus of perimeter 56 cms is 100 sq cms. Find the sum of the lengths of its diagonals."
},
"concept": {
"conceptTitle": "Sum of Rhombus Diagonals",
"educationalGoal": "To understand how to calculate the sum of the diagonals of a rhombus given its perimeter and area, by applying properties of a rhombus, the Pythagorean theorem, and an algebraic identity.",
"explanation": "A **rhombus** is a fascinating four-sided shape where all four sides are equal in length. Its diagonals have a special relationship: they **bisect each other at right angles**. This creates four identical right-angled triangles inside the rhombus! We're going to use this property, along with the area formula and a key algebraic identity, to solve our problem.",
"steps": [
{
"stepTitle": "1. Understand the Rhombus and its Side",
"instruction": "A rhombus has four equal sides. Given the perimeter is 56 cm, calculate the length of one side. Click Next to reveal the side length.",
"visualFocus": "A rhombus with all four sides labeled 's'. Highlight one side 's' and the perimeter calculation (Perimeter = 4s)."
},
{
"stepTitle": "2. Area and the Product of Diagonals",
"instruction": "The area of a rhombus is half the product of its diagonals. Given the area is 100 sq cm, find the product of the diagonals (d1 * d2). Click Next to see the calculation.",
"visualFocus": "The rhombus with its two diagonals d1 and d2 drawn. Display the area formula: Area = (1/2) * d1 * d2. Highlight the calculation of d1 * d2."
},
{
"stepTitle": "3. Diagonals, Side, and Pythagoras",
"instruction": "The diagonals of a rhombus bisect each other at right angles. This creates four right-angled triangles. Focus on one of these triangles: its legs are half the diagonals (d1/2, d2/2) and its hypotenuse is the side (s) of the rhombus. Apply the Pythagorean theorem. Click Next to see how this relates d1, d2, and s.",
"visualFocus": "The rhombus with diagonals. Highlight one of the four right-angled triangles formed at the center. Label its legs as d1/2 and d2/2, and its hypotenuse as 's'. Show the Pythagorean theorem: (d1/2)^2 + (d2/2)^2 = s^2, and its simplified form: d1^2 + d2^2 = 4s^2."
},
{
"stepTitle": "4. Connecting with Algebra: Finding the Sum",
"instruction": "Now we have values for 'd1 * d2' and 'd1^2 + d2^2'. We want to find 'd1 + d2'. Recall the algebraic identity: (a + b)^2 = a^2 + b^2 + 2ab. Substitute our values for 'a' as d1 and 'b' as d2. Click Next to complete the final calculation!",
"visualFocus": "Display the algebraic identity (d1 + d2)^2 = d1^2 + d2^2 + 2d1d2. Show the substitution of the calculated values for d1^2 + d2^2 and 2 * d1 * d2. Highlight the final calculation steps leading to d1 + d2."
}
],
"visualSpec": {
"elements": [
"A dynamic rhombus shape, labeled ABCD.",
"Sides of the rhombus labeled 's'.",
"Diagonals of the rhombus, labeled 'd1' (longer) and 'd2' (shorter).",
"A right-angle symbol at the intersection of the diagonals.",
"Highlighting capability for one of the four right-angled triangles formed by the diagonals and sides.",
"Text display areas for: Perimeter, Area, Side Length (s), d1*d2, d1^2+d2^2, (d1+d2)^2, and d1+d2."
],
"interactions": [
"A 'Next' button to advance through the steps.",
"Potentially a 'Reset' button to restart the proof from step 1."
],
"mathLogic": "1. Side Length (s): s = Perimeter / 4. 2. Product of Diagonals: d1 * d2 = 2 * Area. 3. Pythagorean Theorem: (d1/2)^2 + (d2/2)^2 = s^2, which simplifies to d1^2 + d2^2 = 4s^2. 4. Algebraic Identity: (d1 + d2)^2 = d1^2 + d2^2 + 2 * (d1 * d2). 5. Final Answer: d1 + d2 = sqrt((d1 + d2)^2)."
}
},
"sourceCode": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Sum of Rhombus Diagonals Visualization</title>\n <style>\n :root {\n --bg-color: #0f172a;\n --panel-bg: #1e293b;\n --text-color: #e2e8f0;\n --accent-cyan: #38bdf8;\n --accent-pink: #f472b6;\n --accent-yellow: #facc15;\n --accent-green: #4ade80;\n --border-color: #334155;\n }\n\n * {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n body {\n font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;\n background-color: var(--bg-color);\n color: var(--text-color);\n height: 100vh;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n header {\n padding: 1rem 2rem;\n border-bottom: 1px solid var(--border-color);\n background-color: var(--panel-bg);\n flex-shrink: 0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n h1 {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--accent-cyan);\n }\n\n .container {\n display: flex;\n flex: 1;\n overflow: hidden;\n flex-direction: row; /* Side by side layout */\n }\n\n /* Canvas Area */\n #canvas-wrapper {\n flex: 3;\n position: relative;\n background-color: #0f172a; /* Darker distinct from panel */\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: hidden;\n }\n\n canvas {\n display: block;\n }\n\n /* Info Panel Area */\n #info-panel {\n flex: 2;\n background-color: var(--panel-bg);\n border-left: 1px solid var(--border-color);\n padding: 2rem;\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n overflow-y: auto;\n min-width: 320px;\n box-shadow: -4px 0 15px rgba(0,0,0,0.3);\n }\n\n .step-indicator {\n font-size: 0.85rem;\n text-transform: uppercase;\n letter-spacing: 1px;\n color: #94a3b8;\n margin-bottom: 0.5rem;\n }\n\n .step-title {\n font-size: 1.5rem;\n font-weight: 700;\n margin-bottom: 1.5rem;\n color: var(--text-color);\n line-height: 1.3;\n }\n\n .instruction-box {\n background-color: rgba(255, 255, 255, 0.05);\n border-radius: 8px;\n padding: 1.5rem;\n margin-bottom: 2rem;\n border: 1px solid var(--border-color);\n }\n\n .math-block {\n font-family: 'Courier New', Courier, monospace;\n background-color: rgba(0, 0, 0, 0.3);\n padding: 1rem;\n border-radius: 4px;\n margin: 1rem 0;\n border-left: 4px solid var(--accent-cyan);\n font-size: 1.1rem;\n line-height: 1.6;\n }\n\n .highlight-text {\n color: var(--accent-yellow);\n font-weight: bold;\n }\n\n .variable {\n font-style: italic;\n font-family: serif;\n }\n\n /* Controls */\n .controls {\n margin-top: auto;\n display: flex;\n gap: 1rem;\n padding-top: 1rem;\n border-top: 1px solid var(--border-color);\n }\n\n button {\n flex: 1;\n padding: 0.75rem 1.5rem;\n border: none;\n border-radius: 6px;\n font-size: 1rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n button.prev {\n background-color: transparent;\n border: 1px solid var(--border-color);\n color: var(--text-color);\n }\n\n button.prev:hover:not(:disabled) {\n background-color: rgba(255, 255, 255, 0.1);\n }\n\n button.next {\n background-color: var(--accent-cyan);\n color: #0f172a;\n }\n\n button.next:hover:not(:disabled) {\n background-color: #7dd3fc;\n transform: translateY(-1px);\n }\n\n button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n }\n\n /* Responsive Adjustments */\n @media (max-width: 768px) {\n .container {\n flex-direction: column;\n }\n \n #canvas-wrapper {\n flex: 1;\n min-height: 300px;\n }\n\n #info-panel {\n flex: 1;\n border-left: none;\n border-top: 1px solid var(--border-color);\n min-width: 100%;\n }\n }\n </style>\n</head>\n<body>\n\n <header>\n <h1>Math Visualizer</h1>\n <div style=\"font-size: 0.9rem; color: #94a3b8;\">Rhombus Properties</div>\n </header>\n\n <div class=\"container\">\n <div id=\"canvas-wrapper\">\n <canvas id=\"geometryCanvas\"></canvas>\n </div>\n\n <aside id=\"info-panel\">\n <div class=\"step-indicator\">Step <span id=\"step-number\">1</span> of 4</div>\n <h2 class=\"step-title\" id=\"step-title\">Title</h2>\n \n <div class=\"instruction-box\">\n <p id=\"step-desc\">Description goes here.</p>\n <div id=\"math-content\" class=\"math-block\">\n <!-- Math formulas inserted via JS -->\n </div>\n </div>\n\n <div class=\"controls\">\n <button id=\"btn-prev\" class=\"prev\">Previous</button>\n <button id=\"btn-next\" class=\"next\">Next</button>\n </div>\n </aside>\n </div>\n\n <script>\n /**\n * APPLICATION STATE\n */\n const state = {\n currentStep: 0,\n perimeter: 56,\n area: 100,\n side: 14, // 56 / 4\n productDiagonals: 200, // 100 * 2\n sumSquares: 784, // 4 * 14^2\n sumDiagonalsSq: 1184, // 784 + 2*200\n finalAnswer: 34.41 // sqrt(1184)\n };\n\n /**\n * STEP DATA\n */\n const steps = [\n {\n title: \"Understand the Rhombus and its Side\",\n desc: \"A rhombus has four equal sides. We are given the Perimeter = 56 cm. Since all sides are equal, we can find the length of one side (s).\",\n math: `Perimeter = 4<span class=\"variable\">s</span> = 56<br>\n <span class=\"variable\">s</span> = 56 / 4<br>\n <span class=\"highlight-text\"><span class=\"variable\">s</span> = 14 cm</span>`,\n drawState: 'step1'\n },\n {\n title: \"Area and the Product of Diagonals\",\n desc: \"The area of a rhombus is half the product of its diagonals (<span class='variable'>d₁</span> and <span class='variable'>d₂</span>). Given Area = 100 sq cm, let's find <span class='variable'>d₁</span> × <span class='variable'>d₂</span>.\",\n math: `Area = ½ × <span class=\"variable\">d₁</span> × <span class=\"variable\">d₂</span> = 100<br>\n <span class=\"variable\">d₁</span> × <span class=\"variable\">d₂</span> = 100 × 2<br>\n <span class=\"highlight-text\"><span class=\"variable\">d₁</span><span class=\"variable\">d₂</span> = 200</span>`,\n drawState: 'step2'\n },\n {\n title: \"Diagonals, Side, and Pythagoras\",\n desc: \"Diagonals bisect each other at 90°. This forms four right-angled triangles. Looking at one triangle, the legs are half the diagonals, and the hypotenuse is side <span class='variable'>s</span>.\",\n math: `(<span class=\"variable\">d₁</span>/2)² + (<span class=\"variable\">d₂</span>/2)² = <span class=\"variable\">s</span>²<br>\n <span class=\"variable\">d₁</span>²/4 + <span class=\"variable\">d₂</span>²/4 = <span class=\"variable\">s</span>²<br>\n <span class=\"variable\">d₁</span>² + <span class=\"variable\">d₂</span>² = 4<span class=\"variable\">s</span>²<br>\n Substitute <span class=\"variable\">s</span>=14: 4(196)<br>\n <span class=\"highlight-text\"><span class=\"variable\">d₁</span>² + <span class=\"variable\">d₂</span>² = 784</span>`,\n drawState: 'step3'\n },\n {\n title: \"Connecting with Algebra: Finding the Sum\",\n desc: \"We need <span class='variable'>d₁</span> + <span class='variable'>d₂</span>. We know <span class='variable'>d₁</span>² + <span class='variable'>d₂</span>² and <span class='variable'>d₁</span><span class='variable'>d₂</span>. We use the algebraic identity <span class='variable'>(a+b)² = a² + b² + 2ab</span>.\",\n math: `(<span class=\"variable\">d₁</span>+<span class=\"variable\">d₂</span>)² = (<span class=\"variable\">d₁</span>² + <span class=\"variable\">d₂</span>²) + 2(<span class=\"variable\">d₁</span><span class=\"variable\">d₂</span>)<br>\n Substitute values:<br>\n (<span class=\"variable\">d₁</span>+<span class=\"variable\">d₂</span>)² = 784 + 2(200) = 1184<br>\n <span class=\"variable\">d₁</span>+<span class=\"variable\">d₂</span> = √1184<br>\n <span class=\"highlight-text\">Sum ≈ 34.41 cm</span>`,\n drawState: 'step4'\n }\n ];\n\n /**\n * DOM ELEMENTS\n */\n const canvas = document.getElementById('geometryCanvas');\n const ctx = canvas.getContext('2d');\n const wrapper = document.getElementById('canvas-wrapper');\n \n // UI Elements\n const els = {\n stepNum: document.getElementById('step-number'),\n title: document.getElementById('step-title'),\n desc: document.getElementById('step-desc'),\n math: document.getElementById('math-content'),\n prev: document.getElementById('btn-prev'),\n next: document.getElementById('btn-next')\n };\n\n /**\n * INITIALIZATION\n */\n function init() {\n window.addEventListener('resize', handleResize);\n els.prev.addEventListener('click', () => changeStep(-1));\n els.next.addEventListener('click', () => changeStep(1));\n handleResize(); // Initial draw\n updateUI();\n }\n\n function handleResize() {\n const rect = wrapper.getBoundingClientRect();\n canvas.width = rect.width;\n canvas.height = rect.height;\n draw();\n }\n\n function changeStep(delta) {\n const newStep = state.currentStep + delta;\n if (newStep >= 0 && newStep < steps.length) {\n state.currentStep = newStep;\n updateUI();\n draw();\n }\n }\n\n function updateUI() {\n const step = steps[state.currentStep];\n els.stepNum.textContent = state.currentStep + 1;\n els.title.textContent = step.title;\n els.desc.innerHTML = step.desc;\n els.math.innerHTML = step.math;\n\n els.prev.disabled = state.currentStep === 0;\n els.next.disabled = state.currentStep === steps.length - 1;\n \n // Change button text on last step\n if (state.currentStep === steps.length - 1) {\n els.next.textContent = \"Done\";\n } else {\n els.next.textContent = \"Next\";\n }\n }\n\n /**\n * DRAWING LOGIC\n */\n function draw() {\n const width = canvas.width;\n const height = canvas.height;\n const cx = width / 2;\n const cy = height / 2;\n\n // Clear\n ctx.clearRect(0, 0, width, height);\n \n // Config for the rhombus visualization\n // To make it look nice, we pick a scale that fits. \n // Given s=14, let's assume d1 is roughly 24 and d2 roughly 11 (fits math approx).\n // We scale these logic units to pixels.\n \n const scale = Math.min(width, height) / 30; \n // Visual dimensions (not strictly 1:1 to math to ensure visibility of labels)\n const d1_vis = 24; \n const d2_vis = 12; \n \n const halfW = (d1_vis * scale) / 2;\n const halfH = (d2_vis * scale) / 2;\n\n // Vertices\n const top = { x: cx, y: cy - halfH };\n const right = { x: cx + halfW, y: cy };\n const bottom = { x: cx, y: cy + halfH };\n const left = { x: cx - halfW, y: cy };\n\n // Save context for transformations\n ctx.save();\n\n // 1. Draw Rhombus Shape\n ctx.beginPath();\n ctx.moveTo(top.x, top.y);\n ctx.lineTo(right.x, right.y);\n ctx.lineTo(bottom.x, bottom.y);\n ctx.lineTo(left.x, left.y);\n ctx.closePath();\n \n ctx.lineWidth = 3;\n ctx.strokeStyle = '#38bdf8'; // cyan\n ctx.stroke();\n ctx.fillStyle = 'rgba(56, 189, 248, 0.05)';\n ctx.fill();\n\n // 2. Corner Labels (A, B, C, D)\n drawLabel(\"A\", top.x, top.y - 20, \"#94a3b8\");\n drawLabel(\"B\", right.x + 20, right.y, \"#94a3b8\");\n drawLabel(\"C\", bottom.x, bottom.y + 20, \"#94a3b8\");\n drawLabel(\"D\", left.x - 20, left.y, \"#94a3b8\");\n\n const s = state.currentStep;\n\n // Step 1: Side Lengths\n if (s === 0) {\n drawLabel(\"s\", (top.x + right.x)/2 + 10, (top.y + right.y)/2 - 10, \"#facc15\");\n drawLabel(\"s\", (right.x + bottom.x)/2 + 10, (right.y + bottom.y)/2 + 10, \"#facc15\");\n drawLabel(\"s\", (bottom.x + left.x)/2 - 10, (bottom.y + left.y)/2 + 10, \"#facc15\");\n drawLabel(\"s\", (left.x + top.x)/2 - 10, (left.y + top.y)/2 - 10, \"#facc15\");\n }\n\n // Step 2, 3, 4: Diagonals\n if (s >= 1) {\n // Draw Diagonals\n ctx.beginPath();\n ctx.moveTo(top.x, top.y);\n ctx.lineTo(bottom.x, bottom.y);\n ctx.moveTo(left.x, left.y);\n ctx.lineTo(right.x, right.y);\n ctx.lineWidth = 2;\n ctx.strokeStyle = '#f472b6'; // pink\n ctx.setLineDash([5, 5]);\n ctx.stroke();\n ctx.setLineDash([]);\n\n // Labels for Diagonals\n // d1 is horizontal (left-right), d2 is vertical (top-bottom)\n if (s === 1) {\n drawLabel(\"d₁\", left.x + 20, left.y - 10, \"#f472b6\");\n drawLabel(\"d₂\", top.x + 10, top.y + 30, \"#f472b6\");\n }\n }\n\n // Step 3: Highlight Triangle & Pythagoras\n if (s >= 2) {\n // Highlight top-right triangle\n ctx.beginPath();\n ctx.moveTo(cx, cy);\n ctx.lineTo(cx, top.y);\n ctx.lineTo(right.x, right.y);\n ctx.lineTo(cx, cy);\n ctx.fillStyle = 'rgba(250, 204, 21, 0.2)'; // Yellow transparent\n ctx.fill();\n ctx.strokeStyle = '#facc15';\n ctx.stroke();\n\n // Right Angle Symbol\n ctx.beginPath();\n ctx.strokeStyle = '#e2e8f0';\n ctx.lineWidth = 1;\n const raSize = 15;\n ctx.moveTo(cx + raSize, cy);\n ctx.lineTo(cx + raSize, cy - raSize);\n ctx.lineTo(cx, cy - raSize);\n ctx.stroke();\n\n // Labels for Triangle parts\n drawLabel(\"s=14\", (top.x + right.x)/2 + 20, (top.y + right.y)/2 - 10, \"#facc15\");\n \n // Legs\n // Horizontal leg\n drawLabel(\"d₁/2\", cx + halfW/2, cy + 20, \"#f472b6\");\n // Vertical leg\n drawLabel(\"d₂/2\", cx - 35, cy - halfH/2, \"#f472b6\");\n }\n\n // Step 4: Just reinforce the highlighting\n if (s === 3) {\n // Maybe pulse the whole shape or specific parts?\n // For now, the static visual with the equation updates is sufficient.\n }\n\n ctx.restore();\n }\n\n /**\n * Helper to draw text with background for readability\n */\n function drawLabel(text, x, y, color) {\n ctx.font = \"bold 16px sans-serif\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n \n const metrics = ctx.measureText(text);\n const bgPadding = 4;\n \n ctx.fillStyle = \"rgba(15, 23, 42, 0.8)\"; // Semi-transparent dark bg\n ctx.fillRect(\n x - metrics.width/2 - bgPadding, \n y - 10 - bgPadding, \n metrics.width + bgPadding*2, \n 20 + bgPadding*2\n );\n\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n }\n\n // Run\n init();\n\n </script>\n</body>\n</html>"
}