Completing the Square with Algebra Tiles: Choose an Expression
Loading the math board and drawing, please wait…
This interactive GeoGebra lesson demonstrates the process of completing the square by letting students choose their own algebraic expression and then observing how algebra tiles model the step-by-step transformation. It focuses on rewriting a quadratic expression into an equivalent completed-square form, highlighting how terms and coefficients are adjusted to preserve equality. Key concepts include completing the square for solving quadratic equations, coefficient matching, algebraic equivalence, and understanding why adding a constant to finish the square requires adding the corresponding negative/compensating quantity as well. Construction and interaction are driven by programmatic parameter generation and UI control: randomization is used to select values (RandomUniform, Sequence, Max, If), various geometric and text objects are composed and positioned to build the visual model (Text, Segment, Vector, PixelsToPoint/PointToPixels, Translate, Join, Zip, Flatten, Take, Corner, Element), and app behavior is managed with scripting elements to reset the app and toggle hints/answers (showanswer, showhint, scriptResetApp, scriptFixAllText, scriptEmptyInputBoxes, button controls). Best suited for grades 9–12, classroom exploration, and guided practice of completing-the-square problem solving.
GeoGebra Commands & Parameters
RandomUniform(0, 0.99, 200) → allRandomSeeds, {0.8548254949126582, 0.8243255808539557, 0.7053537997663649, 0.5946431173553146, 0.1933366589400638, 0.5815387405495404, 0.7558949230858008, 0.4748264926115612, 0.4010455984507947, 0.7489214548777103, 0.9792670669916175, 0.044054862893809305, 0.019248765430733804, 0.22022913856092435, 0.249495865385833, 0.6319422221139752, 0.4593472751067925, 0.25020255148237586, 0.953566225962684, 0.7128823629942047, 0.0773307093276081, 0.42172646570247124, 0.4326254416052949, 0.21090037978669407, 0.8557573425616123, 0.9117201558238112, 0.9131135776330537, 0.23989808060489587, 0.681077783419194, 0.6263475956985084, 0.17503712671902794, 0.8112439515476332, 0.7240599301966252, 0.6119069270930962, 0.7356085429981243, 0.39127327189274, 0.7506736914291409, 0.3107177830470188, 0.5321673543985873, 0.9640667064196731, 0.1400806698260495, 0.8114716068108491, 0.958679272971693, 0.6498658285873696, 0.6653482484311628, 0.2908436901047139, 0.5551784752751239, 0.06666220593902177, 0.8711705791006473, 0.16768779621947907, 0.9792735629738891, 0.10186119548006432, 0.9612275066796402, 0.4628423673190306, 0.48328151128174984, 0.8324749744971062, 0.5058503031475466, 0.9464749522030766, 0.8396847387174243, 0.24603946179637454, 0.6683874758378703, 0.2809740428377824, 0.5814243301498342, 0.5303769754356413, 0.2160758852721784, 0.5006703006822191, 0.43204886196595793, 0.6084424517050515, 0.31832219721378885, 0.6001275403049549, 0.9639315611727436, 0.14479338227510524, 0.12208690193692093, 0.7203898980502166, 0.1006487383495816, 0.08271380204135219, 0.050537245096163044, 0.8074067785354367, 0.07218189843969866, 0.44570066450300133, 0.037298095962063314, 0.29887736994835506, 0.9288608178486034, 0.33388588938765107, 0.3244793779207024, 0.2649663826371737, 0.6119086922169998, 0.7350204831051192, 0.8481949669838652, 0.24473878660498175, 0.2750812887749394, 0.9208866904783966, 0.12051375903460239, 0.4637453397183963, 0.32321020491069485, 0.4434329389674912, 0.05169485879944131, 0.8489621524034654, 0.1494666518701368, 0.7905402684226256, 0.6311589018312113, 0.5752468688938315, 0.6438547610651368, 0.0391327504690752, 0.959934113274367, 0.24261971074125807, 0.7308252007426114, 0.2533342268736919, 0.9112911647074451, 0.12601290027408807, 0.2439674259941245, 0.9275512321700546, 0.8799421887242275, 0.9686517852555591, 0.08049526322088184, 0.7687275369725027, 0.9135290612567649, 0.9869418563534376, 0.05768375967028661, 0.30856832213859514, 0.0531639836688145, 0.5486304986232309, 0.5675459291182771, 0.11527221933934333, 0.8525085251753861, 0.1270978870697112, 0.1548566092465979, 0.9652373306669274, 0.12729100570757157, 0.6829016990785025, 0.9871364066528167, 0.5683222638123578, 0.9392603320560312, 0.46916012655826334, 0.7234019957848487, 0.7655463850048272, 0.7803624862695742, 0.6700036792665761, 0.13136997642820966, 0.4356033503445888, 0.8244000873154919, 0.11116046954923754, 0.8703699774281334, 0.16623979606697462, 0.3945972506363663, 0.27876108396134813, 0.19947819102265874, 0.9284166873729707, 0.3163423143536776, 0.6166581772674675, 0.08732638969460937, 0.9152227095280532, 0.9849174661191601, 0.9239523478548932, 0.6616716947755308, 0.20375039092575944, 0.21824908907079124, 0.08299986241677385, 0.5431315147793093, 0.08657254017683928, 0.014625085164798811, 0.18394927385308843, 0.16849315692100925, 0.12007200844870991, 0.39492439341264207, 0.30481314097976236, 0.6947014551479902, 0.6596809428751073, 0.48819181860507166, 0.6862270267003541, 0.5850085672655166, 0.01707536720601408, 0.3483650840113017, 0.1773826553124577, 0.6538381969251288, 0.701549029752595, 0.6686238615078947, 0.18414305647891713, 0.5466727047292412, 0.5871554471252861, 0.8981795231978387, 0.2020565423587069, 0.3957145440441569, 0.6787600811808708, 0.2543620371952242, 0.18588339645529334, 0.8312047697859359, 0.5638845538315781, 0.8605845250438718, 0.6333321030962124, 0.8520993554564408, 0.3631526445592118, 0.6981783974843492, 0.4539747834347205, 0.5283100280016995, 0.8802632335770939, 0.6871917891019502, 0.8047689904495958, 0.3599096425469103, 0.6027176562411295}Take(allRandomSeeds, randIndex, randIndex + numRandoms - 1) → currentRandomSeedsCorner(5) → layoutAppSizeonboardingTextOffset(Corner[onboardingText, 1], Corner[onboardingText, 3], onboardingCase, (xMin, yMin), (xMax, yMax), (800, 500)) → OnboardingTextOffsetElement({-10, -8, -6, -4, -2, 2, 4, 6, 8, 10}, slideB) → coeffBPixelsToPoint((xMin, yMin), (xMax, yMax), (800, 500), (120, 250)) → AnchorSquaredcenterBox(xHeight, xHeight, AnchorSquared) → squaredBoxSequence(AnchorX + ((A * (xWidth + gap)), 0), A, 0, abs(absCoeffB) - 1) → anchorsXMax(Min[1, 1 + animateControl - ceil(animateControl)], 0) → animateCurrentIf(floor(animateControl) < absCoeffB, 0, If[floor(animateControl) ≟ absCoeffB, animateControl - absCoeffB, 1]) → animateStage3AIf(floor(animateControl) < absCoeffB, 0, If[floor(animateControl) ≟ absCoeffB, animateControl - absCoeffB, 1]) → animateStage3Vector(AnchorStage3 - AnchorStage1) → vShiftSequence(AnchorUnitStart + (A * (xWidth + gap, 0)) + (animateStage3A * vShift), A, 0, abs(absCoeffC)) → anchorUnitsSequence(AnchorSquared + ((0.5 * (xHeight + xWidth)) + gap + (A * (xWidth + gap)), 0), A, 0, floor(abs(absCoeffB) / 2) - 1) → anchorsXStage2ASequence(AnchorSquared - (0, (0.5 * (xHeight + xWidth)) + gap + (A * (xWidth + gap))), A, 0, floor(abs(absCoeffB) / 2) - 1) → anchorsXStage2BJoin({anchorsXStage2A, anchorsXStage2B}) → anchorsXStage2Zip(Vector[B - A], A, anchorsX, B, anchorsXStage2) → vMoveMin(ceil(animateControl), absCoeffB) → animateIndexBIf(animateIndexB ≤ absCoeffB / 2, 0, pi / 2) → rotateAngleTranslate(Rotate[centerBox[xWidth, xHeight, anchorsX(animateIndexB)], (animateCurrent * rotateAngle), anchorsX(animateIndexB)], (animateCurrent * vMove(animateIndexB))) → moveBoxBMin(If[isNegativeC, 0, (absCoeffB / 2)^(2)], absCoeffC) → numUnitsMoveFlatten(Sequence[Sequence[(x(anchorsXStage2A(i)), y(anchorsXStage2B(j))), i, 1, absCoeffB / 2], j, 1, absCoeffB / 2]) → anchorUnitsStage2If(floor(animateControl) < absCoeffB + 2, 0, If[floor(animateControl) ≟ absCoeffB + 2, animateControl - absCoeffB - 2, 1]) → animateStage4Flatten(Sequence[Sequence[anchorUnits(1) + ((A * (xWidth + gap)), ((-K) * (xWidth + gap))), A, 0, absCoeffB / 2 - 1], K, 1, absCoeffB / 2]) → anchorUnitsStage3If(floor(animateControl) < absCoeffB + 3, 0, If[floor(animateControl) ≟ absCoeffB + 3, animateControl - absCoeffB - 3, 1]) → animateStage5Translate(anchorUnitsStage3, Vector[((1 - animateStage5) * Vector[AnchorSubtractStage3 - AnchorStage3])]) → anchorsSubtractStage3Zip(Vector[B - A], A, anchorUnitsStage3, B, anchorUnitsStage2) → vMoveUnitsMax(Min[ceil(animateControl) - absCoeffB - 4, numUnitsMove], 0) → animateIndexStage6Zip(centerBox[xWidth, xWidth, A], A, anchorUnitsStage2) → unitsStage2FramesZip(Vector[B - A], A, anchorsSubtractStage3, B, anchorUnits) → vMoveSubtractTranslate(centerBox[xWidth, xWidth, anchorsSubtractStage3(animateIndexStage6)], (animateCurrent * vMoveSubtract(animateIndexStage6))) → moveSubtractBoxcenterBox(squareWidth, squareWidth, CenterSquare) → squareFrameText("x", AnchorSquared - (xHeight / 2, 0), true, true, -1, 0) → lblSideXZip(centerBox[xWidth, xWidth, A], A, anchorUnitsStage3) → unitsStage4Zip(centerBox[xWidth, xWidth, A + (animateStage5 * B)], A, anchorUnitsStage3, Vector[B], vMoveUnits) → unitsStage5Sequence(centerBox[xWidth, xWidth, anchorUnits(A)], A, 1, absCoeffC) → unitsStage1Zip(centerBox[xWidth, xWidth, A], A, Take[anchorsSubtractStage3, animateIndexStage6 + 1]) → subtractStage3If(floor(animateControl) < absCoeffB + 4 + numUnitsMove, 0, If[floor(animateControl) ≟ absCoeffB + 4 + numUnitsMove, animateControl - absCoeffB - 4 - numUnitsMove, 1]) → animateStage7Take(unitsStage1, 1, If[animateStage7 ≟ 0, animateIndexStage6 - 1, numUnitsMove]) → unitsSubtractStage5PixelsToPoint((xMin, yMin), (xMax, yMax), (800, 500), (If[animateControl ≤ 4, 310, 16], 60)) → PExprElement({("" * finalConstant), "", ("+" * finalConstant)}, sgn(finalConstant) + 2) → finalConstantLatexIf(absCoeffC < 0, ("" * absCoeffC), If[absCoeffC ≟ 0, "", ("+" * absCoeffC)]) → coeffCLatexText(fullExpression, PExpr, true, true, If[animateControl ≤ 4, 0, 1], -1) → displayExprSegment((((-xWidth)) / 2, ((-xHeight)) / 2), (xWidth / 2, xHeight / 2)) → templateSlashXSequence(centerBox[xWidth, xHeight, anchorsX(A)], A, animateIndexB + 1, abs(absCoeffB)) → xBlocksStartSequence(centerBox[If[A > abs(absCoeffB) / 2, xHeight, xWidth], If[A > abs(absCoeffB) / 2, xWidth, xHeight], anchorsXStage2(A)], A, 1, Min[ceil(animateControl) - 1, abs(absCoeffB)]) → xBlocksStage2Vector(AnchorStage1 - AnchorStage3) → vSlideSubtractAppend((1000, 1000), Take[anchorUnits, 1, Min[animateIndexStage6, numUnitsMove]]) → anchorsCrossesSequence(Translate[crossTemplate, anchorUnits(A)], A, 1, absCoeffC) → possibleCrossesFlatten(Take[possibleCrosses, 1, If[animateStage7 ≟ 0, animateIndexStage6 - 1, numUnitsMove]]) → displayCrossesSequence(centerBox[(1.4 * xWidth), (1.4 * xWidth), anchorUnits(A)], A, 1, absCoeffC) → possibleFadesTake(possibleFades, 1, If[animateStage7 ≟ 0, animateIndexStage6 - 1, numUnitsMove]) → fadeBoxesZip(centerBox[xWidth - (2 * borderWidth), xWidth - (2 * borderWidth), A], A, Take[anchorsSubtractStage3, animateIndexStage6 + 1]) → subtractStage3CentersTranslate(centerBox[xWidth - (2 * borderWidth), xWidth - (2 * borderWidth), anchorsSubtractStage3(animateIndexStage6)], (animateCurrent * vMoveSubtract(animateIndexStage6))) → moveSubtractCenterZip(centerBox[xWidth, xWidth, A], A, Join[{anchorUnitsStage3, anchorsSubtractStage3}]) → fadeCoverStage4Sequence(centerBox[xWidth - (2 * gap), xWidth - (2 * gap), anchorUnits(A)], A, 1, absCoeffC) → negativeUnitsStage1Sequence(centerBox[xWidth - (2 * gap), xHeight - (2 * gap), anchorsX(A)], A, animateIndexB + 1, abs(absCoeffB)) → negativeXStage1Translate(Rotate[centerBox[xWidth - (2 * gap), xHeight - (2 * gap), anchorsX(animateIndexB)], (animateCurrent * rotateAngle), anchorsX(animateIndexB)], (animateCurrent * vMove(animateIndexB))) → negativeMoveBoxPointToPixels((xMin, yMin), (xMax, yMax), (800, 500), CenterX) → CenterXPXPointToPixels((xMin, yMin), (xMax, yMax), (800, 500), AnchorUnitStart) → CenterUnitsPXSequence(centerBox[If[A > abs(absCoeffB) / 2, xHeight - (2 * gap), xWidth - (2 * gap)], If[A > abs(absCoeffB) / 2, xWidth - (2 * gap), xHeight - (2 * gap)], anchorsXStage2(A)], A, 1, Min[ceil(animateControl) - 1, abs(absCoeffB)]) → negativeXStage2Text("\vphantom{4}x", AnchorSquared + (0, xHeight / 2), true, true, 0, 1) → lblTopAText(("\vphantom{x^2}" * LaTeX[((If[isNegativeB, "-", ""] * absCoeffB) * "x")]), CenterX + (0, ((-xHeight)) / 2), true, true, 0, -1) → captionSlideBText(("\vphantom{x^2}" * LaTeX[(If[isNegativeC, "-", ""] * absCoeffC)]), CenterUnit + (0, ((-xHeight)) / 2), true, true, 0, -1) → captionSlideCText(("" * coeffB / 2), AnchorSquared - ((0.5 * xHeight), (xHeight * 0.5) + (xWidth * absCoeffB / 4)), true, true, -1, 0) → lblSideBText(("" * coeffB / 2), AnchorSquared + ((0.5 * xHeight) + (xWidth * absCoeffB / 4), (0.5 * xHeight)), true, true, 0, 1) → lblTopBText("x^2", AnchorSquared + (0, ((-xHeight)) / 2), true, true, 0, -1) → lblSqStage1
AI Drawing Prompt Reference
This is a visual representation of the completing the square method. The graphic consists of a series of algebraic tiles that initially show a quadratic expression. Users can drag and add tiles to gradually transform the expression into a perfect square form. A central area represents the perfect square part, along with labels and text that annotate the current expression and steps. The tiles are arranged in a specific order to demonstrate how to adjust coefficients by adding and moving tiles, ultimately yielding an equivalent perfect square expression. The graphic dynamically illustrates the completing the square process, helping to understand how to add a constant to complete the square.
The prompt above was compiled from the original drawing commands and is for reference only.