(* Content-type: application/mathematica *) (*** Wolfram Notebook File ***) (* http://www.wolfram.com/nb *) (* CreatedBy='Mathematica 6.0' *) (*CacheID: 234*) (* Internal cache information: NotebookFileLineBreakTest NotebookFileLineBreakTest NotebookDataPosition[ 145, 7] NotebookDataLength[ 50118, 1505] NotebookOptionsPosition[ 45156, 1346] NotebookOutlinePosition[ 45756, 1369] CellTagsIndexPosition[ 45713, 1366] WindowFrame->Normal*) (* Beginning of Notebook Content *) Notebook[{ Cell["Coordinates systems and transformations", "Title", CellChangeTimes->{{3.3907458272729015`*^9, 3.390745835374874*^9}, { 3.390746922311163*^9, 3.3907469286805754`*^9}, {3.390747109577908*^9, 3.390747121535579*^9}, {3.3949919891510243`*^9, 3.3949920025093*^9}, { 3.395346125984375*^9, 3.39534614046875*^9}, {3.3954160997502937`*^9, 3.3954160998804817`*^9}}], Cell["\<\ Comp160 Course Module 5 \ \>", "Subtitle", CellChangeTimes->{{3.390745838950158*^9, 3.3907458395911055`*^9}, 3.3907469187659235`*^9, {3.394991909622219*^9, 3.394991911955411*^9}, 3.3949920154269733`*^9, {3.395346122265625*^9, 3.395346122453125*^9}, { 3.4271298569257364`*^9, 3.427129857106003*^9}, 3.4592583865*^9}], Cell[TextData[{ "Organizing the graphical components of a game requires that each element be \ correctly positioned. In this model, we review the basics of coordinate \ systems and affine transformation. We begin by discussing the math behind \ these concepts and then describe ", StyleBox["Mathematica", FontSlant->"Italic"], "'s approach to handling transformations." }], "Text", CellChangeTimes->{{3.394992012613124*^9, 3.3949921192690425`*^9}, { 3.395346151296875*^9, 3.395346266640625*^9}, {3.3954112081877975`*^9, 3.3954112189633994`*^9}, {3.3954161134100714`*^9, 3.3954161204402504`*^9}, 3.3954165079413137`*^9}], Cell[CellGroupData[{ Cell["Points and vectors", "Section", CellChangeTimes->{{3.394304801130623*^9, 3.3943048133285275`*^9}, 3.394460354238846*^9, {3.394462761989036*^9, 3.3944627632308464`*^9}, { 3.395346284703125*^9, 3.395346289859375*^9}}], Cell[TextData[{ "For 2D games, the most fundamental graphical element is a ", StyleBox["point", FontSlant->"Italic"], ". In ", StyleBox["Mathematica", FontSlant->"Italic"], ", a point is represented as ", Cell[BoxData[ RowBox[{"Point", "[", RowBox[{"{", RowBox[{"x", ",", "y"}], "}"}], "]"}]]], " where the pair ", Cell[BoxData[ RowBox[{"{", RowBox[{"x", ",", "y"}], "}"}]]], " are the ", StyleBox["Cartesian coordinates", FontSlant->"Italic"], " of the point. Here is a plot of ", Cell[BoxData[ RowBox[{"Point", "[", RowBox[{"{", RowBox[{"2", ",", "1"}], "}"}], "]"}]]], "." }], "Text", CellChangeTimes->{{3.395346412140625*^9, 3.3953464343125*^9}, { 3.39534647478125*^9, 3.39534666771875*^9}, {3.395346697765625*^9, 3.395346733953125*^9}, {3.3953467855625*^9, 3.39534680790625*^9}, { 3.39534688903125*^9, 3.3953468928125*^9}, {3.395347045375*^9, 3.39534709459375*^9}, {3.395347130921875*^9, 3.395347228390625*^9}, { 3.395347496546875*^9, 3.395347509109375*^9}, 3.459258800625*^9}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"Graphics", "[", RowBox[{"Point", "[", RowBox[{"{", RowBox[{"2", ",", "1"}], "}"}], "]"}], "]"}]], "Input", CellChangeTimes->{{3.39534751259375*^9, 3.3953475256875*^9}}], Cell[BoxData[ GraphicsBox[PointBox[{2, 1}], ImageSize->{143.3333333333332, Automatic}]], "Output", CellChangeTimes->{3.395347526109375*^9}] }, Open ]], Cell["\<\ Observe this picture doesn't make to much geometric sense since the point is \ drawn with no frame of reference. To give the point geometric location, \ let's redo the plot with an origin and axes drawn.\ \>", "Text", CellChangeTimes->{{3.39534753425*^9, 3.395347547390625*^9}, { 3.39534757775*^9, 3.39534758571875*^9}, {3.395347627828125*^9, 3.3953476755625*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"Graphics", "[", RowBox[{ RowBox[{"Point", "[", RowBox[{"{", RowBox[{"2", ",", "1"}], "}"}], "]"}], ",", RowBox[{"PlotRange", "\[Rule]", "3"}], ",", RowBox[{"Axes", "\[Rule]", "True"}]}], "]"}]], "Input", CellChangeTimes->{{3.395347101046875*^9, 3.39534712321875*^9}, { 3.39534724484375*^9, 3.395347249125*^9}}], Cell[BoxData[ GraphicsBox[PointBox[{2, 1}], Axes->True, ImageSize->{159.33333333333323`, Automatic}, PlotRange->3]], "Output", CellChangeTimes->{{3.395347115453125*^9, 3.395347123703125*^9}, 3.395347249859375*^9}] }, Open ]], Cell[TextData[{ "Now, the point has a geometric position in terms of the origin and the two \ axes. For this example, the point is drawn at a position that is offset from \ the origin by two units in the ", Cell[BoxData["x"]], " direction (horizontal) and two units in the ", Cell[BoxData["y"]], " direction (vertical)." }], "Text", CellChangeTimes->{{3.395347232296875*^9, 3.395347238859375*^9}, { 3.395347424578125*^9, 3.39534748690625*^9}, {3.395347689328125*^9, 3.395347758296875*^9}, 3.395347967453125*^9, {3.3954161449857903`*^9, 3.3954161451560364`*^9}, 3.3986870469720583`*^9}], Cell[TextData[{ "Another fundamental entity is a ", StyleBox["vector", FontSlant->"Italic"], ". Given two points ", Cell[BoxData["p"]], " and ", Cell[BoxData["q"]], ", a vector ", Cell[BoxData["v"]], " is the displacement from a tail point ", Cell[BoxData["p"]], " to a head point ", Cell[BoxData["q"]], ". In ", StyleBox["Mathematica", FontSlant->"Italic"], ", the function ", Cell[BoxData["Arrow"]], " can be used to draw vectors. " }], "Text", CellChangeTimes->{{3.395346412140625*^9, 3.3953464343125*^9}, { 3.39534647478125*^9, 3.39534666771875*^9}, {3.395346697765625*^9, 3.395346733953125*^9}, {3.3953467855625*^9, 3.39534680790625*^9}, { 3.39534688903125*^9, 3.3953468928125*^9}, {3.395347045375*^9, 3.39534705140625*^9}, {3.39534776434375*^9, 3.395347817828125*^9}, { 3.395347853328125*^9, 3.395347893296875*^9}, {3.39534858040625*^9, 3.3953487201875*^9}, {3.395349447*^9, 3.395349473640625*^9}, { 3.395349805453125*^9, 3.39534981165625*^9}, {3.395355982203125*^9, 3.395355993890625*^9}, 3.3986870489949875`*^9}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"Graphics", "[", RowBox[{ RowBox[{"Arrow", "[", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "0"}], "}"}], ",", RowBox[{"{", RowBox[{"2", ",", "1"}], "}"}]}], "}"}], "]"}], ",", RowBox[{"PlotRange", "\[Rule]", "3"}], ",", RowBox[{"Axes", "\[Rule]", "True"}]}], "]"}]], "Input", CellChangeTimes->{{3.395348777671875*^9, 3.39534881603125*^9}}], Cell[BoxData[ GraphicsBox[ArrowBox[{{1, 0}, {2, 1}}], Axes->True, ImageSize->{156.00000000000003`, Automatic}, PlotRange->3]], "Output", CellChangeTimes->{{3.3953488031875*^9, 3.395348816375*^9}}] }, Open ]], Cell[TextData[{ "Mathematically, vector ", Cell[BoxData["v"]], " can be represented as a pair of real numbers ", Cell[BoxData[ RowBox[{"{", RowBox[{"a", ",", "b"}], "}"}]]], " computed by simply taking the difference of the coordinates of the head \ point ", Cell[BoxData["p"]], " and tail point ", Cell[BoxData["q"]], " defining the vector; ", Cell[BoxData[ RowBox[{"v", "=", RowBox[{"p", "-", "q"}]}]]], ". Note that if we shift both the head and tail points by the same amount ", Cell[BoxData["w"]], ", this shift cancels out via" }], "Text", CellChangeTimes->{{3.395346412140625*^9, 3.3953464343125*^9}, { 3.39534647478125*^9, 3.39534666771875*^9}, {3.395346697765625*^9, 3.395346733953125*^9}, {3.3953467855625*^9, 3.39534680790625*^9}, { 3.39534688903125*^9, 3.3953468928125*^9}, {3.395347045375*^9, 3.39534705140625*^9}, {3.39534776434375*^9, 3.395347817828125*^9}, { 3.395347853328125*^9, 3.395347893296875*^9}, {3.39534858040625*^9, 3.395348693859375*^9}, {3.395348833453125*^9, 3.39534891659375*^9}, { 3.3953490231875*^9, 3.3953490299375*^9}, {3.39534907365625*^9, 3.395349091890625*^9}, {3.39534932125*^9, 3.395349337125*^9}, { 3.3953494605*^9, 3.395349566171875*^9}, {3.395349750515625*^9, 3.395349874546875*^9}, {3.395355757375*^9, 3.39535585928125*^9}, { 3.395355998109375*^9, 3.395356002421875*^9}, {3.395356477015625*^9, 3.395356480125*^9}}], Cell[BoxData[ RowBox[{" ", RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"p", "+", "w"}], ")"}], "-", RowBox[{"(", RowBox[{"q", "+", "w"}], ")"}]}], "=", RowBox[{ RowBox[{"p", "-", "q"}], "=", "v", " "}]}]}]], "DisplayFormula", CellChangeTimes->{{3.395346412140625*^9, 3.3953464343125*^9}, { 3.39534647478125*^9, 3.39534666771875*^9}, {3.395346697765625*^9, 3.395346733953125*^9}, {3.3953467855625*^9, 3.39534680790625*^9}, { 3.39534688903125*^9, 3.3953468928125*^9}, {3.395347045375*^9, 3.39534705140625*^9}, {3.39534776434375*^9, 3.395347817828125*^9}, { 3.395347853328125*^9, 3.395347893296875*^9}, {3.39534858040625*^9, 3.395348693859375*^9}, {3.395348833453125*^9, 3.39534891659375*^9}, { 3.3953490231875*^9, 3.3953490299375*^9}, {3.39534907365625*^9, 3.395349091890625*^9}, {3.39534932125*^9, 3.395349337125*^9}, { 3.3953494605*^9, 3.395349566171875*^9}, {3.395349750515625*^9, 3.395349874546875*^9}, {3.395355757375*^9, 3.395355873203125*^9}, { 3.39535648396875*^9, 3.395356491421875*^9}}], Cell[TextData[{ "yielding the same vector ", Cell[BoxData["v"]], ". For example, the plot" }], "Text", CellChangeTimes->{{3.395346412140625*^9, 3.3953464343125*^9}, { 3.39534647478125*^9, 3.39534666771875*^9}, {3.395346697765625*^9, 3.395346733953125*^9}, {3.3953467855625*^9, 3.39534680790625*^9}, { 3.39534688903125*^9, 3.3953468928125*^9}, {3.395347045375*^9, 3.39534705140625*^9}, {3.39534776434375*^9, 3.395347817828125*^9}, { 3.395347853328125*^9, 3.395347893296875*^9}, {3.39534858040625*^9, 3.395348693859375*^9}, {3.395348833453125*^9, 3.39534891659375*^9}, { 3.3953490231875*^9, 3.3953490299375*^9}, {3.39534907365625*^9, 3.395349091890625*^9}, {3.39534932125*^9, 3.395349337125*^9}, { 3.3953494605*^9, 3.395349566171875*^9}, {3.395349750515625*^9, 3.395349874546875*^9}, {3.395355757375*^9, 3.39535586209375*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"Graphics", "[", RowBox[{ RowBox[{"Arrow", "[", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"0", ",", "0"}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]}], "}"}], "]"}], ",", RowBox[{"PlotRange", "\[Rule]", "3"}], ",", RowBox[{"Axes", "\[Rule]", "True"}]}], "]"}]], "Input", CellChangeTimes->{{3.395348924296875*^9, 3.395348945671875*^9}}], Cell[BoxData[ GraphicsBox[ArrowBox[{{0, 0}, {1, 1}}], Axes->True, ImageSize->{161.99999999999991`, Automatic}, PlotRange->3]], "Output", CellChangeTimes->{3.39534894615625*^9}] }, Open ]], Cell["\<\ produces the same vector shifted down and to the left by a unit.\ \>", "Text", CellChangeTimes->{{3.395346412140625*^9, 3.3953464343125*^9}, { 3.39534647478125*^9, 3.39534666771875*^9}, {3.395346697765625*^9, 3.395346733953125*^9}, {3.3953467855625*^9, 3.39534680790625*^9}, { 3.39534688903125*^9, 3.3953468928125*^9}, {3.395347045375*^9, 3.39534705140625*^9}, {3.39534776434375*^9, 3.395347817828125*^9}, { 3.395347853328125*^9, 3.395347893296875*^9}, {3.39534858040625*^9, 3.395348693859375*^9}, {3.395348833453125*^9, 3.39534891659375*^9}, { 3.395348957390625*^9, 3.3953489670625*^9}, {3.39534987934375*^9, 3.395349912453125*^9}}], Cell[TextData[{ "As you have probably learned in physics, vectors form a ", StyleBox["linear", FontSlant->"Italic"], " space; that is, they can be added and scaled to form new vectors. This \ operation can simply be computed on a coordinate by coordinate basis. For \ example, the sum of the vectors ", Cell[BoxData[ RowBox[{"{", RowBox[{"1", ",", "0"}], "}"}]]], " and ", Cell[BoxData[ RowBox[{"{", RowBox[{"0", ",", "1"}], "}"}]]], " is the vector ", Cell[BoxData[ RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]]], "." }], "Text", CellChangeTimes->{{3.3954113517556696`*^9, 3.395411409799711*^9}, { 3.395411464348693*^9, 3.395411581658546*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"Graphics", "[", RowBox[{ RowBox[{"{", RowBox[{ RowBox[{"Arrow", "[", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}], ",", RowBox[{"{", RowBox[{"2", ",", "1"}], "}"}]}], "}"}], "]"}], ",", RowBox[{"Arrow", "[", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"2", ",", "1"}], "}"}], ",", RowBox[{"{", RowBox[{"2", ",", "2"}], "}"}]}], "}"}], "]"}], ",", RowBox[{"Arrow", "[", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}], ",", RowBox[{"{", RowBox[{"2", ",", "2"}], "}"}]}], "}"}], "]"}]}], "}"}], ",", RowBox[{"PlotRange", "\[Rule]", "3"}], ",", RowBox[{"Axes", "\[Rule]", "True"}]}], "]"}]], "Input", CellChangeTimes->{{3.3954115878174634`*^9, 3.3954116485253625`*^9}}], Cell[BoxData[ GraphicsBox[{ArrowBox[{{1, 1}, {2, 1}}], ArrowBox[{{2, 1}, {2, 2}}], ArrowBox[{{1, 1}, {2, 2}}]}, Axes->True, ImageSize->{183.33333333333312`, Automatic}, PlotRange->3]], "Output", CellChangeTimes->{{3.395411633874149*^9, 3.39541164967703*^9}}] }, Open ]], Cell["\<\ Taking combinations of points is a trickier task. The obvious approach would \ be to add and scale the underlying coordinates of the points. However, as we \ shall see when we consider transformations, this approach has some peril.\ \>", "Text", CellChangeTimes->{{3.3954116703169146`*^9, 3.3954118547739897`*^9}, { 3.3954119325365825`*^9, 3.3954119649635334`*^9}}], Cell[CellGroupData[{ Cell["Exercises", "Exercise", CellChangeTimes->{{3.395349969671875*^9, 3.395349970484375*^9}, { 3.39535005603125*^9, 3.395350060609375*^9}}], Cell[TextData[{ StyleBox["1. Write a function ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"vector", "[", RowBox[{"p", ",", "v"}], "]"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" that draws a vector ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["v"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" with tail at point ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["p"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[".", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.39534998446875*^9, 3.395349998765625*^9}, { 3.395350063515625*^9, 3.39535008565625*^9}, {3.395353260671875*^9, 3.3953532925625*^9}}], Cell[TextData[{ StyleBox["2. Write a function ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"midpt", "[", RowBox[{"p", ",", "q"}], "]"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" that returns the point halfway between the points ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["p"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" and ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["q"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[".", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.39534998446875*^9, 3.39534998459375*^9}, 3.395350137609375*^9, {3.39535331746875*^9, 3.39535335490625*^9}, { 3.39535462303125*^9, 3.395354657140625*^9}, {3.395356499515625*^9, 3.395356501109375*^9}, {3.39535795996875*^9, 3.3953579616875*^9}, { 3.45925877684375*^9, 3.45925877771875*^9}}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["Translation, rotation and scaling", "Section", CellChangeTimes->{{3.395346295703125*^9, 3.395346317015625*^9}, { 3.3953552399375*^9, 3.395355246796875*^9}}], Cell["\<\ In 2D games, graphical objects typically move and change shape in response to \ the user's action. For now, we will focus on transformations applied to \ points. Mathematically, we will model a transformation as a function that \ takes a point as input and returns a new point as output.\ \>", "Text", CellChangeTimes->{{3.395346319609375*^9, 3.39534632209375*^9}, { 3.395354760046875*^9, 3.395354781921875*^9}, {3.395355125890625*^9, 3.395355139796875*^9}, {3.39535520509375*^9, 3.395355220296875*^9}, { 3.395355271296875*^9, 3.395355357953125*^9}, {3.3953570890625*^9, 3.395357192484375*^9}, {3.3953584161875*^9, 3.3953584250625*^9}, { 3.3954161989339013`*^9, 3.39541620046612*^9}}], Cell[CellGroupData[{ Cell["Translations", "Subsection", CellChangeTimes->{{3.395346324984375*^9, 3.395346327*^9}, { 3.395355152921875*^9, 3.395355154953125*^9}}], Cell[TextData[{ "The simplest and most common transformation in 2D graphics is a \ translation. A translation takes a point ", Cell[BoxData["p"]], " and displaces it by a vector ", Cell[BoxData["v"]], " to yield a new point ", Cell[BoxData[ RowBox[{"translate", "[", RowBox[{"p", ",", "v"}], "]"}]]], " according to" }], "Text", CellChangeTimes->{{3.395355924234375*^9, 3.39535596034375*^9}, { 3.395356506796875*^9, 3.395356522484375*^9}, {3.3953565976875*^9, 3.395356618140625*^9}, {3.3953571339375*^9, 3.395357134671875*^9}, { 3.395357196328125*^9, 3.395357219171875*^9}, {3.395357316953125*^9, 3.39535732034375*^9}, {3.395357787421875*^9, 3.3953577878125*^9}, { 3.395412367556448*^9, 3.3954123682073903`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"translate", "[", RowBox[{"p_", ",", "v_"}], "]"}], ":=", RowBox[{"p", "+", "v"}]}]], "Input", CellChangeTimes->{{3.395357783796875*^9, 3.395357795171875*^9}}], Cell[TextData[{ "For example, the following function translates the point ", Cell[BoxData[ RowBox[{"{", RowBox[{"1", ",", "0"}], "}"}]]], " by the vector ", Cell[BoxData[ RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]]], "," }], "Text", CellChangeTimes->{{3.395357222921875*^9, 3.3953572574375*^9}, { 3.39535776640625*^9, 3.395357777875*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"translate", "[", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "0"}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]}], "]"}]], "Input", CellChangeTimes->{{3.395357803734375*^9, 3.39535780846875*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"2", ",", "1"}], "}"}]], "Output", CellChangeTimes->{3.395357809015625*^9}] }, Open ]], Cell["Graphically, this example appears as", "Text", CellChangeTimes->{{3.395357286125*^9, 3.3953572960625*^9}, { 3.395357731765625*^9, 3.395357761484375*^9}, {3.3953579233125*^9, 3.3953579441875*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"p", "=", RowBox[{"{", RowBox[{"1", ",", "0"}], "}"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"v", "=", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]}], ";"}], "\[IndentingNewLine]", RowBox[{"Graphics", "[", RowBox[{ RowBox[{"{", RowBox[{ RowBox[{"Point", "[", "p", "]"}], ",", RowBox[{"Point", "[", RowBox[{"translate", "[", RowBox[{"p", ",", "v"}], "]"}], "]"}]}], "}"}], ",", RowBox[{"PlotRange", "\[Rule]", "3"}], ",", RowBox[{"Axes", "\[Rule]", "True"}]}], "]"}]}], "Input", CellChangeTimes->{{3.3953572705*^9, 3.395357277390625*^9}, { 3.395357854265625*^9, 3.395357910140625*^9}}], Cell[BoxData[ GraphicsBox[{PointBox[{1, 0}], PointBox[{2, 1}]}, Axes->True, ImageSize->{197.33333333333334`, Automatic}, PlotRange->3]], "Output", CellChangeTimes->{{3.39535788534375*^9, 3.39535791134375*^9}}] }, Open ]], Cell["\<\ Note that translating both endpoints of a vector does not change the vector \ itself.\ \>", "Text", CellChangeTimes->{{3.395358486140625*^9, 3.395358494625*^9}, { 3.3954113007918787`*^9, 3.3954113025844746`*^9}, {3.4592592005*^9, 3.459259221375*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Rotations", "Subsection", CellChangeTimes->{{3.395346324984375*^9, 3.395346327*^9}}], Cell[TextData[{ "Another common transformation is rotation. A rotation takes a point ", Cell[BoxData["p"]], " and an angle ", Cell[BoxData["\[Theta]"]], " and rotates the point ", Cell[BoxData["p"]], " around the origin counterclockwise by ", Cell[BoxData["\[Theta]"]], " radians. This operation can be implemented by multiply the coordinate \ vector for the point ", Cell[BoxData["p"]], " by a rotation matrix of the form" }], "Text", CellChangeTimes->{{3.395358158359375*^9, 3.395358178625*^9}, { 3.3954123481984196`*^9, 3.395412419491645*^9}, {3.3954125198068914`*^9, 3.3954125647519674`*^9}, {3.395412670935711*^9, 3.3954126735394807`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"MatrixForm", "[", RowBox[{"RotationMatrix", "[", "\[Theta]", "]"}], "]"}]], "Input", CellChangeTimes->{{3.3954125677162595`*^9, 3.3954125769095707`*^9}}], Cell[BoxData[ TagBox[ RowBox[{"(", "\[NoBreak]", GridBox[{ { RowBox[{"Cos", "[", "\[Theta]", "]"}], RowBox[{"-", RowBox[{"Sin", "[", "\[Theta]", "]"}]}]}, { RowBox[{"Sin", "[", "\[Theta]", "]"}], RowBox[{"Cos", "[", "\[Theta]", "]"}]} }, GridBoxAlignment->{ "Columns" -> {{Left}}, "ColumnsIndexed" -> {}, "Rows" -> {{Baseline}}, "RowsIndexed" -> {}}, GridBoxSpacings->{"Columns" -> { Offset[0.27999999999999997`], { Offset[0.7]}, Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> { Offset[0.2], { Offset[0.4]}, Offset[0.2]}, "RowsIndexed" -> {}}], "\[NoBreak]", ")"}], Function[BoxForm`e$, MatrixForm[BoxForm`e$]]]], "Output", CellChangeTimes->{3.3954125775104403`*^9}] }, Open ]], Cell[TextData[{ "In ", StyleBox["Mathematica", FontSlant->"Italic"], ", we can now define a function ", Cell[BoxData[ RowBox[{"rotate", "[", RowBox[{"p", ",", "\[Theta]"}], "]"}]]], " that multiplies this matrix times ", Cell[BoxData["p"]], ". ", StyleBox["Mathematica", FontSlant->"Italic"], " uses a \"dot\" (a period) for matrix multiplication." }], "Text", CellChangeTimes->{{3.3954125895478697`*^9, 3.3954126282038393`*^9}, { 3.459259376203125*^9, 3.45925941971875*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"rotate", "[", RowBox[{"p_", ",", "\[Theta]_"}], "]"}], ":=", RowBox[{ RowBox[{"RotationMatrix", "[", "\[Theta]", "]"}], ".", "p"}]}]], "Input", CellChangeTimes->{{3.395412431448958*^9, 3.3954124764140625`*^9}, 3.395412509602116*^9}], Cell[TextData[{ "For example, we can rotate the point ", Cell[BoxData[ RowBox[{"{", RowBox[{"2", ",", "0"}], "}"}]]], " by ", Cell[BoxData[ FractionBox["\[Pi]", "4"]]], " radians" }], "Text", CellChangeTimes->{{3.395412640371457*^9, 3.395412683483879*^9}, { 3.3954127328553643`*^9, 3.3954127456338663`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"Graphics", "[", RowBox[{ RowBox[{"{", RowBox[{ RowBox[{"Point", "[", RowBox[{"{", RowBox[{"2", ",", "0"}], "}"}], "]"}], ",", RowBox[{"Point", "[", RowBox[{"rotate", "[", RowBox[{ RowBox[{"{", RowBox[{"2", ",", "0"}], "}"}], ",", FractionBox["\[Pi]", "4"]}], "]"}], "]"}]}], "}"}], ",", "\[IndentingNewLine]", RowBox[{"PlotRange", "\[Rule]", "3"}], ",", RowBox[{"Axes", "\[Rule]", "True"}]}], "]"}]], "Input", CellChangeTimes->{{3.395412685817258*^9, 3.3954127480273323`*^9}}], Cell[BoxData[ GraphicsBox[{PointBox[{2, 0}], PointBox[NCache[{2^Rational[1, 2], 2^Rational[1, 2]}, {1.4142135623730951`, 1.4142135623730951`}]]}, Axes->True, ImageSize->{169.99999999999977`, Automatic}, PlotRange->3]], "Output", CellChangeTimes->{{3.395412708349883*^9, 3.395412749168985*^9}}] }, Open ]], Cell[TextData[{ "Rotating a vector involves an identical multiplication by ", Cell[BoxData[ RowBox[{"RotationMatrix", "[", "\[Theta]", "]"}]]], "." }], "Text", CellChangeTimes->{{3.3954127954259605`*^9, 3.39541281476396*^9}, { 3.395412922800386*^9, 3.3954129473158817`*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Scaling", "Subsection", CellChangeTimes->{{3.395346328875*^9, 3.39534632984375*^9}}], Cell[TextData[{ "Translation and rotation were examples of ", StyleBox["rigid", FontSlant->"Italic"], " transformations. If we apply a translation or rotation to an entire \ object, the size and shape of the object does not change, just its position. \ Using scaling, we can increase the size of an object by repositioning the \ points that comprise the object. " }], "Text", CellChangeTimes->{{3.395358158359375*^9, 3.395358178625*^9}, 3.39535834184375*^9, {3.3954129581816144`*^9, 3.395413129800101*^9}}], Cell[TextData[{ "A scaling transformation (around the origin) takes a point ", Cell[BoxData["p"]], " and two constants ", Cell[BoxData[ RowBox[{"{", RowBox[{"sx", ",", "sy"}], "}"}]]], "and multiplies the ", Cell[BoxData["x"]], " and ", Cell[BoxData["y"]], " coordinates of ", Cell[BoxData["p"]], " by ", Cell[BoxData["sx"]], " and ", Cell[BoxData["sy"]], ", respectively. This multiplication can be implemented as a matrix/vector \ multiplication where the matrix is the diagonal matrix" }], "Text", CellChangeTimes->{{3.3954132777643385`*^9, 3.3954134177269907`*^9}, { 3.3954135573291206`*^9, 3.395413560924326*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"MatrixForm", "[", RowBox[{"DiagonalMatrix", "[", RowBox[{"{", RowBox[{"sx", ",", "sy"}], "}"}], "]"}], "]"}]], "Input", CellChangeTimes->{{3.395413363478444*^9, 3.395413364489908*^9}, { 3.3954134199101515`*^9, 3.3954134300848837`*^9}}], Cell[BoxData[ TagBox[ RowBox[{"(", "\[NoBreak]", GridBox[{ {"sx", "0"}, {"0", "sy"} }, GridBoxAlignment->{ "Columns" -> {{Left}}, "ColumnsIndexed" -> {}, "Rows" -> {{Baseline}}, "RowsIndexed" -> {}}, GridBoxSpacings->{"Columns" -> { Offset[0.27999999999999997`], { Offset[0.7]}, Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> { Offset[0.2], { Offset[0.4]}, Offset[0.2]}, "RowsIndexed" -> {}}], "\[NoBreak]", ")"}], Function[BoxForm`e$, MatrixForm[BoxForm`e$]]]], "Output", CellChangeTimes->{3.3954134306857533`*^9}] }, Open ]], Cell[TextData[{ "Now, we can define our own function ", Cell[BoxData["scale"]], " that performs this operation" }], "Text", CellChangeTimes->{{3.395413436624352*^9, 3.3954134594874554`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"scale", "[", RowBox[{"p_", ",", "s_"}], "]"}], ":=", RowBox[{ RowBox[{"DiagonalMatrix", "[", "s", "]"}], ".", "p"}]}]], "Input", CellChangeTimes->{{3.3954134610096593`*^9, 3.3954134761315546`*^9}}], Cell[TextData[{ "If the two scaling factors are equal, the scaling is a ", StyleBox["uniform", FontSlant->"Italic"], " scaling. For example, we can uniformly scale the point ", Cell[BoxData[ RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]]], " by a factor ", Cell[BoxData["2"]], " to create the point ", Cell[BoxData[ RowBox[{"{", RowBox[{"2", ",", "2"}], "}"}]]], "." }], "Text", CellChangeTimes->{{3.3954134862662287`*^9, 3.3954136054387784`*^9}, 3.3986870508676987`*^9}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"Graphics", "[", RowBox[{ RowBox[{"{", RowBox[{ RowBox[{"Point", "[", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}], "]"}], ",", RowBox[{"Point", "[", RowBox[{"scale", "[", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}], ",", RowBox[{"{", RowBox[{"2", ",", "2"}], "}"}]}], "]"}], "]"}]}], "}"}], ",", "\[IndentingNewLine]", RowBox[{"PlotRange", "\[Rule]", "3"}], ",", RowBox[{"Axes", "\[Rule]", "True"}]}], "]"}]], "Input", CellChangeTimes->{{3.3954136074116344`*^9, 3.395413661099369*^9}}], Cell[BoxData[ GraphicsBox[{PointBox[{1, 1}], PointBox[{2, 2}]}, Axes->True, ImageSize->{186.66666666666657`, Automatic}, PlotRange->3]], "Output", CellChangeTimes->{{3.395413642642646*^9, 3.3954136616201234`*^9}}] }, Open ]], Cell["\<\ As was the case for rotations, vectors are also scaled by multiplication by \ the matrix.\ \>", "Text", CellChangeTimes->{{3.3954137206455865`*^9, 3.39541375252174*^9}, 3.4592594864375*^9}] }, Open ]], Cell[CellGroupData[{ Cell["Combinations of translations, rotations and scalings", "Subsection", CellChangeTimes->{{3.395355255*^9, 3.395355259015625*^9}, {3.395358183625*^9, 3.395358194765625*^9}}], Cell[TextData[{ "Taken together, translations, rotations and (non-uniform) scalings form a \ class of transformations known as ", StyleBox["affine", FontSlant->"Italic"], " transformations. In terms of coordinate computation, affine \ transformations have a simple representation. Given a ", Cell[BoxData[ RowBox[{"2", "\[Times]", "2"}]]], " matrix ", Cell[BoxData["M"]], " and a vector ", Cell[BoxData["v"]], ", the affine transformation of the point ", Cell[BoxData["p"]], " is simply ", Cell[BoxData[ RowBox[{ RowBox[{"M", ".", "p"}], "+", "v"}]]], "." }], "Text", CellChangeTimes->{{3.39535819715625*^9, 3.395358200125*^9}, { 3.395358393015625*^9, 3.3953583963125*^9}, 3.3953584458125*^9, { 3.3954137141762195`*^9, 3.3954137151376114`*^9}, {3.395413763928255*^9, 3.3954138454162416`*^9}, {3.3954139269142427`*^9, 3.395413999419223*^9}, 3.398687058939386*^9}], Cell[BoxData[ RowBox[{ RowBox[{"affine", "[", RowBox[{"p_", ",", RowBox[{"{", RowBox[{"M_", ",", "v_"}], "}"}]}], "]"}], "=", RowBox[{ RowBox[{"M", ".", "p"}], "+", "v"}]}]], "Input", CellChangeTimes->{{3.395414003014428*^9, 3.3954140223724566`*^9}}], Cell[TextData[{ "To apply an affine transformation to a vector, we simply ignore the \ translation vector (since vectors are unchanged by translation) and multiply \ the vector by the matrix ", Cell[BoxData["M"]], "." }], "Text", CellChangeTimes->{{3.395416279280235*^9, 3.3954163487107635`*^9}}], Cell["\<\ Clearly, translations, rotations and scaling can be written in this form. \ One nice property (that you will show in the exercises) is that the \ composition of two affine transformations is another affine transformation. \ Another interesting property of affine transformation is that they can always \ be expressed as a combination of a translation, a rotation and a non-uniform \ scaling. Due to these properties, affine transformation are a standard class \ of transformation used in 2D graphics and game design.\ \>", "Text", CellChangeTimes->{{3.39541403412948*^9, 3.3954140902006655`*^9}, { 3.3954141613336587`*^9, 3.395414197285714*^9}, {3.3954142643728495`*^9, 3.3954143538524065`*^9}, 3.398687066910928*^9}], Cell[CellGroupData[{ Cell["Exercises", "Exercise", CellChangeTimes->{{3.395412824457996*^9, 3.395412829315028*^9}}], Cell[TextData[{ StyleBox["1. ", FontColor->RGBColor[0.5, 0, 0.5]], StyleBox["Combining points", FontWeight->"Bold", FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[": Let's now revisit the problem of taking combinations of points \ in light of the affine transformation described above. Given the points ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"{", RowBox[{"1", ",", "0"}], "}"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" and ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"{", RowBox[{"0", ",", "1"}], "}"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[", we could define addition of points as being the result of adding \ their coordinates. However, this definition has an unfortunate property that \ the sum of two points in not invariant under translation. For example, \ consider the two following expressions", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.39541202862571*^9, 3.3954122139740763`*^9}, { 3.3954128363351927`*^9, 3.395412845338228*^9}, {3.3954128755419607`*^9, 3.395412875872439*^9}, {3.395414243853139*^9, 3.395414259595933*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{"translate", "[", RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"1", ",", "0"}], "}"}], "+", RowBox[{"{", RowBox[{"0", ",", "1"}], "}"}]}], ",", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]}], "]"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"translate", "[", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "0"}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]}], "]"}], "+", RowBox[{"translate", "[", RowBox[{ RowBox[{"{", RowBox[{"0", ",", "1"}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]}], "]"}]}]}], "Input", CellChangeTimes->{{3.3954121906503057`*^9, 3.3954122590493402`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{"2", ",", "2"}], "}"}]], "Output", CellChangeTimes->{3.395412259900573*^9}], Cell[BoxData[ RowBox[{"{", RowBox[{"3", ",", "3"}], "}"}]], "Output", CellChangeTimes->{3.3954122599306164`*^9}] }, Open ]], Cell[TextData[{ StyleBox["In the first example, we added the point and then translated to \ get the point ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"{", RowBox[{"2", ",", "2"}], "}"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[". In the second example, we translated the two points and then \ added them to get the point ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"{", RowBox[{"3", ",", "3"}], "}"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[". Ideally, we would like of our concept of combining points to \ invariant with respect to affine transformations; that is, if we combine \ points and apply an affine transformation, we get the same answer as applying \ the affine transformation to each point and combining the result.", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.395412263215372*^9, 3.3954122676718245`*^9}, { 3.3954143965642495`*^9, 3.3954145459605603`*^9}}], Cell[TextData[{ StyleBox["Verify that the function ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["midpoint"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" that you created in the first set of exercises has this property. \ Why did ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["midpoint"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" work when our example above failed? Derive a hypothesis on how \ point combination must be formulated to be invariant with respect to affine \ transformations.", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.395412263215372*^9, 3.3954122676718245`*^9}, { 3.3954143965642495`*^9, 3.395414441939949*^9}, {3.395414551108013*^9, 3.3954146568010464`*^9}, {3.395415249108649*^9, 3.3954152542761307`*^9}}], Cell[TextData[{ StyleBox["2. Write a function ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"combine", "[", RowBox[{ RowBox[{"{", RowBox[{"M1", ",", "v1"}], "}"}], ",", RowBox[{"{", RowBox[{"M2", ",", "v2"}], "}"}]}], "]"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" that returns the affine transformation ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"{", RowBox[{"M", ",", "v"}], "}"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" formed applying the affine transformation ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"{", RowBox[{"M1", ",", "v1"}], "}"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" and then ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"{", RowBox[{"M2", ",", "v2"}], "}"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" to a point. Use ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["combine"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" to construct an affine transformation that rotate a point ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ FractionBox["\[Pi]", "4"]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" radians around the point ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"{", RowBox[{"2", ",", "0"}], "}"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[".", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.39541202862571*^9, 3.3954122139740763`*^9}, { 3.3954128363351927`*^9, 3.395412845338228*^9}, {3.3954128755419607`*^9, 3.395412875872439*^9}, {3.395414243853139*^9, 3.395414259595933*^9}, { 3.395414682828732*^9, 3.395414762023398*^9}, {3.3954151749312477`*^9, 3.395415221959339*^9}, {3.3954163722448387`*^9, 3.3954163754795218`*^9}}] }, Open ]] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[TextData[{ "Transformations in", StyleBox[" Mathematica ", FontSlant->"Italic"], "using", StyleBox[" ", FontSlant->"Italic"], Cell[BoxData["Rotate"]], ", ", Cell[BoxData["Translate"]], ", ", Cell[BoxData["Scale"]] }], "Section", CellChangeTimes->{{3.394384127590186*^9, 3.3943841323971944`*^9}, { 3.3943860065394526`*^9, 3.394386016584097*^9}, {3.3943862806590843`*^9, 3.3943862835232596`*^9}, {3.3944627701709642`*^9, 3.3944627761697097`*^9}, {3.39534637065625*^9, 3.39534638284375*^9}, 3.395358350984375*^9}], Cell[TextData[{ "In the previous section, we implemented our own version of translation, \ rotation and scaling based on the coordinate representation of points. ", StyleBox["Mathematica", FontSlant->"Italic"], " incorporates its own support for geometric transformation that hides much \ of what we have discussed. In this last section, we will use ", StyleBox["Mathematica", FontSlant->"Italic"], "'s version of these operations to start building infrastructure for a ", StyleBox["Mathematica", FontSlant->"Italic"], " version of the arcade game ", StyleBox["Asteroids", FontSlant->"Italic"], " (which we shall call ", StyleBox["Disasteroids", FontSlant->"Italic"], ")." }], "Text", CellChangeTimes->{{3.3954148008796577`*^9, 3.395414937477438*^9}, 3.3986870729797153`*^9}], Cell[TextData[{ "To begin this process, I suggest that you briefly review the section ", ButtonBox["Geometric Transforms", BaseStyle->"Link", ButtonData->"paclet:guide/GeometricTransforms"], " and focus in particular on the ", StyleBox["Mathematica", FontSlant->"Italic"], " functions ", Cell[BoxData["Translate"]], ", ", Cell[BoxData["Rotate"]], ", and ", Cell[BoxData["Scale"]], ". There are two key differences between our version of these operations \ and ", StyleBox["Mathematica", FontSlant->"Italic"], "'s. First, our implementation of these affine transformations acts only on \ a point. ", StyleBox["Mathematica", FontSlant->"Italic"], "'s version can accept any 2D graphical object as input. Second, ", StyleBox["Mathematica", FontSlant->"Italic"], "'s versions of ", Cell[BoxData["Rotate"]], " and ", Cell[BoxData["Scale"]], " allow the user to specify the center of these transformations at arbitrary \ points. (Our version always assume the origin.)" }], "Text", CellChangeTimes->{{3.3954149443573995`*^9, 3.395415162222847*^9}, { 3.3954152682363443`*^9, 3.3954153090854893`*^9}, {3.3954164186720605`*^9, 3.3954164195232925`*^9}}], Cell[TextData[{ "To begin the process of building ", Cell[BoxData["Disasteroids"]], ", let use first choose a black background for our game with the coordinate \ system for this background reaching from ", Cell[BoxData[ RowBox[{"-", "1"}]]], " to ", Cell[BoxData["1"]], " in both direction." }], "Text", CellChangeTimes->{{3.3954153219340925`*^9, 3.3954153995765114`*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"background", "=", RowBox[{"Rectangle", "[", RowBox[{ RowBox[{"{", RowBox[{ RowBox[{"-", "1"}], ",", RowBox[{"-", "1"}]}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{"Graphics", "[", "background", "]"}]}], "Input", CellChangeTimes->{{3.394462114505088*^9, 3.3944621175595407`*^9}, { 3.394462182233827*^9, 3.3944622029840784`*^9}, {3.394559454232637*^9, 3.3945594679125805`*^9}, {3.3954154048541527`*^9, 3.395415411063143*^9}}], Cell[BoxData[ GraphicsBox[RectangleBox[{-1, -1}, {1, 1}], ImageSize->{159.99999999999991`, Automatic}]], "Output", CellChangeTimes->{3.395415411704071*^9, 3.3956836763048935`*^9}] }, Open ]], Cell["\<\ Next, we can construct a simple triangular model for a space ship as\ \>", "Text", CellChangeTimes->{{3.395415433756*^9, 3.395415459032598*^9}}], Cell[CellGroupData[{ Cell[BoxData[{ RowBox[{ RowBox[{"shipModel", "=", RowBox[{"Polygon", "[", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "0"}], "}"}], ",", RowBox[{"{", RowBox[{ RowBox[{"-", "1"}], ",", FractionBox["1", "2"]}], "}"}], ",", RowBox[{"{", RowBox[{ RowBox[{"-", "1"}], ",", FractionBox[ RowBox[{"-", "1"}], "2"]}], "}"}]}], "}"}], "]"}]}], ";"}], "\n", RowBox[{"Graphics", "[", RowBox[{"{", RowBox[{"background", ",", "White", ",", "shipModel"}], "}"}], "]"}]}], "Input", CellChangeTimes->{{3.3954154621070495`*^9, 3.3954154790015106`*^9}, { 3.3954155654967475`*^9, 3.395415578605728*^9}}], Cell[BoxData[ GraphicsBox[{RectangleBox[{-1, -1}, {1, 1}], {GrayLevel[1], PolygonBox[ NCache[{{1, 0}, {-1, Rational[1, 2]}, {-1, Rational[-1, 2]}}, {{1, 0}, {-1, 0.5}, {-1, -0.5}}]]}}, ImageSize->{146., Automatic}]], "Output", CellChangeTimes->{ 3.3945650842536488`*^9, 3.3945656948738546`*^9, 3.394565802370571*^9, 3.3948080717998834`*^9, 3.3948134071749763`*^9, 3.39491947875*^9, { 3.395415471190201*^9, 3.395415480503686*^9}, {3.395415575020537*^9, 3.3954155791164675`*^9}, {3.3956836737211523`*^9, 3.395683680010258*^9}}] }, Open ]], Cell[TextData[{ "An obvious problem here is that our ship is much too large for the \ background. So we can scale the ship using ", StyleBox["Mathematica", FontSlant->"Italic"], "'s function ", Cell[BoxData["Scale"]], "." }], "Text", CellChangeTimes->{{3.3954154985398006`*^9, 3.3954155330497675`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"Graphics", "[", RowBox[{"{", RowBox[{"background", ",", "White", ",", RowBox[{"Scale", "[", RowBox[{"shipModel", ",", FractionBox["1", "10"]}], "]"}]}], "}"}], "]"}]], "Input", CellChangeTimes->{{3.3945595781332684`*^9, 3.394559585293707*^9}, { 3.3954154914495344`*^9, 3.3954154921805925`*^9}, {3.3954155831022387`*^9, 3.3954155837531805`*^9}}], Cell[BoxData[ GraphicsBox[{RectangleBox[{-1, -1}, {1, 1}], {GrayLevel[1], GeometricTransformationBox[ PolygonBox[ NCache[{{1, 0}, {-1, Rational[1, 2]}, {-1, Rational[-1, 2]}}, {{1, 0}, {-1, 0.5}, {-1, -0.5}}]], {{{0.1, 0}, {0, 0.1}}, Center}]}}, ImageSize->{185., Automatic}]], "Output", CellChangeTimes->{3.3945650843237514`*^9, 3.394565694953972*^9, 3.3945658024607024`*^9, 3.3948080718900137`*^9, 3.394813407245077*^9, 3.394919478765625*^9, 3.395415492901637*^9, 3.3954155842238626`*^9}] }, Open ]], Cell["\<\ Your task in the next two exercises to add controls that allow the ship to \ move in response to sliders.\ \>", "Text", CellChangeTimes->{{3.395415614778102*^9, 3.395415677589046*^9}}], Cell[CellGroupData[{ Cell["Exercises", "Exercise", CellChangeTimes->{{3.3954156949642034`*^9, 3.3954157006624537`*^9}}], Cell[TextData[{ StyleBox["1. Construct a function ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"ship", "[", RowBox[{"p", ",", "\[Theta]"}], "]"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" that rotates the scaled ship model by ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["\[Theta]"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" radians and then translates the result to the position ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["p"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[".", FontColor->RGBColor[0.5, 0, 0.5]], " ", StyleBox["Note that if you do not specify a center for ", FontColor->RGBColor[1, 0, 0]], StyleBox["Mathematica", FontSlant->"Italic", FontColor->RGBColor[1, 0, 0]], StyleBox["'s ", FontColor->RGBColor[1, 0, 0]], Cell[BoxData["Rotate"], FontColor->RGBColor[1, 0, 0]], ", ", StyleBox["the default center is the center of the box bounding the graphics \ object.", FontColor->RGBColor[1, 0, 0]] }], "ExerciseText", CellChangeTimes->{{3.395415706831386*^9, 3.395415751636259*^9}, { 3.395415892380042*^9, 3.3954159934163322`*^9}, {3.3956836860990744`*^9, 3.3956837139393845`*^9}}], Cell[TextData[{ StyleBox["2. Construct a ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["DynamicModule"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" that display the ship and the background and includes sliders \ that allow the user to dynamically translate and rotate the ship.", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.395415706831386*^9, 3.395415751636259*^9}, { 3.395415892380042*^9, 3.3954160761661463`*^9}}] }, Open ]] }, Open ]] }, WindowToolbars->{}, WindowSize->{1016, 1033}, WindowMargins->{{0, Automatic}, {Automatic, 0}}, PrintingCopies->1, PrintingPageRange->{1, Automatic}, PrintingOptions->{"PrintCellBrackets"->False, "PrintMultipleHorizontalPages"->False, "PrintRegistrationMarks"->True, "PrintingMargins"->{{54, 54}, {72, 72}}}, Magnification->1.5, FrontEndVersion->"7.0 for Microsoft Windows (32-bit) (November 10, 2008)", StyleDefinitions->"Classroom.nb" ] (* End of Notebook Content *) (* Internal cache information *) (*CellTagsOutline CellTagsIndex->{} *) (*CellTagsIndex CellTagsIndex->{} *) (*NotebookFileOutline Notebook[{ Cell[545, 20, 371, 5, 81, "Title"], Cell[919, 27, 337, 7, 93, "Subtitle"], Cell[1259, 36, 638, 12, 84, "Text"], Cell[CellGroupData[{ Cell[1922, 52, 229, 3, 81, "Section"], Cell[2154, 57, 1049, 31, 62, "Text"], Cell[CellGroupData[{ Cell[3228, 92, 205, 5, 69, "Input"], Cell[3436, 99, 143, 3, 263, "Output"] }, Open ]], Cell[3594, 105, 381, 7, 60, "Text"], Cell[CellGroupData[{ Cell[4000, 116, 362, 9, 69, "Input"], Cell[4365, 127, 225, 6, 290, "Output"] }, Open ]], Cell[4605, 136, 603, 12, 136, "Text"], Cell[5211, 150, 1074, 29, 139, "Text"], Cell[CellGroupData[{ Cell[6310, 183, 427, 12, 154, "Input"], Cell[6740, 197, 204, 5, 640, "Output"] }, Open ]], Cell[6959, 205, 1414, 32, 195, "Text"], Cell[8376, 239, 1053, 21, 85, "DisplayFormula"], Cell[9432, 262, 854, 15, 81, "Text"], Cell[CellGroupData[{ Cell[10311, 281, 428, 12, 154, "Input"], Cell[10742, 295, 184, 5, 661, "Output"] }, Open ]], Cell[10941, 303, 664, 11, 78, "Text"], Cell[11608, 316, 677, 21, 193, "Text"], Cell[CellGroupData[{ Cell[12310, 341, 921, 28, 217, "Input"], Cell[13234, 371, 270, 6, 733, "Output"] }, Open ]], Cell[13519, 380, 380, 6, 135, "Text"], Cell[CellGroupData[{ Cell[13924, 390, 143, 2, 126, "Exercise"], Cell[14070, 394, 688, 20, 81, "ExerciseText"], Cell[14761, 416, 866, 22, 81, "ExerciseText"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[15676, 444, 165, 2, 181, "Section"], Cell[15844, 448, 709, 11, 189, "Text"], Cell[CellGroupData[{ Cell[16578, 463, 143, 2, 148, "Subsection"], Cell[16724, 467, 739, 17, 139, "Text"], Cell[17466, 486, 201, 5, 154, "Input"], Cell[17670, 493, 359, 12, 81, "Text"], Cell[CellGroupData[{ Cell[18054, 509, 248, 7, 154, "Input"], Cell[18305, 518, 115, 3, 153, "Output"] }, Open ]], Cell[18435, 524, 207, 3, 78, "Text"], Cell[CellGroupData[{ Cell[18667, 531, 701, 20, 279, "Input"], Cell[19371, 553, 217, 5, 780, "Output"] }, Open ]], Cell[19603, 561, 266, 6, 78, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[19906, 572, 91, 1, 148, "Subsection"], Cell[20000, 575, 663, 16, 193, "Text"], Cell[CellGroupData[{ Cell[20688, 595, 181, 3, 154, "Input"], Cell[20872, 600, 814, 23, 190, "Output"] }, Open ]], Cell[21701, 626, 498, 16, 136, "Text"], Cell[22202, 644, 282, 7, 154, "Input"], Cell[22487, 653, 323, 11, 96, "Text"], Cell[CellGroupData[{ Cell[22835, 668, 592, 17, 289, "Input"], Cell[23430, 687, 311, 7, 688, "Output"] }, Open ]], Cell[23756, 697, 282, 7, 81, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[24075, 709, 91, 1, 148, "Subsection"], Cell[24169, 712, 519, 10, 189, "Text"], Cell[24691, 724, 643, 21, 193, "Text"], Cell[CellGroupData[{ Cell[25359, 749, 274, 6, 154, "Input"], Cell[25636, 757, 629, 18, 186, "Output"] }, Open ]], Cell[26280, 778, 194, 5, 81, "Text"], Cell[26477, 785, 243, 6, 154, "Input"], Cell[26723, 793, 497, 17, 139, "Text"], Cell[CellGroupData[{ Cell[27245, 814, 619, 18, 217, "Input"], Cell[27867, 834, 221, 5, 744, "Output"] }, Open ]], Cell[28103, 842, 204, 5, 78, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[28344, 852, 180, 2, 148, "Subsection"], Cell[28527, 856, 901, 25, 193, "Text"], Cell[29431, 883, 275, 8, 154, "Input"], Cell[29709, 893, 300, 7, 136, "Text"], Cell[30012, 902, 738, 11, 244, "Text"], Cell[CellGroupData[{ Cell[30775, 917, 95, 1, 126, "Exercise"], Cell[30873, 920, 1158, 27, 247, "ExerciseText"], Cell[CellGroupData[{ Cell[32056, 951, 706, 23, 217, "Input"], Cell[32765, 976, 115, 3, 153, "Output"], Cell[32883, 981, 117, 3, 153, "Output"] }, Open ]], Cell[33015, 987, 975, 22, 249, "ExerciseText"], Cell[33993, 1011, 796, 17, 193, "ExerciseText"], Cell[34792, 1030, 1810, 51, 211, "ExerciseText"] }, Open ]] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[36663, 1088, 544, 17, 184, "Section"], Cell[37210, 1107, 802, 21, 244, "Text"], Cell[38015, 1130, 1187, 34, 303, "Text"], Cell[39205, 1166, 382, 11, 139, "Text"], Cell[CellGroupData[{ Cell[39612, 1181, 581, 14, 217, "Input"], Cell[40196, 1197, 183, 3, 648, "Output"] }, Open ]], Cell[40394, 1203, 155, 3, 78, "Text"], Cell[CellGroupData[{ Cell[40574, 1210, 712, 22, 276, "Input"], Cell[41289, 1234, 564, 11, 600, "Output"] }, Open ]], Cell[41868, 1248, 311, 9, 136, "Text"], Cell[CellGroupData[{ Cell[42204, 1261, 399, 9, 211, "Input"], Cell[42606, 1272, 529, 10, 730, "Output"] }, Open ]], Cell[43150, 1285, 195, 4, 78, "Text"], Cell[CellGroupData[{ Cell[43370, 1293, 99, 1, 126, "Exercise"], Cell[43472, 1296, 1185, 34, 193, "ExerciseText"], Cell[44660, 1332, 468, 10, 136, "ExerciseText"] }, Open ]] }, Open ]] } ] *) (* End of internal cache information *)