(* Content-type: application/mathematica *) (*** Wolfram Notebook File ***) (* http://www.wolfram.com/nb *) (* CreatedBy='Mathematica 7.0' *) (*CacheID: 234*) (* Internal cache information: NotebookFileLineBreakTest NotebookFileLineBreakTest NotebookDataPosition[ 145, 7] NotebookDataLength[ 29139, 778] NotebookOptionsPosition[ 27037, 714] NotebookOutlinePosition[ 27735, 739] CellTagsIndexPosition[ 27692, 736] WindowFrame->Normal*) (* Beginning of Notebook Content *) Notebook[{ Cell["Modeling physics", "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}, {3.3954170292761545`*^9, 3.3954170434566865`*^9}, {3.3954987906173086`*^9, 3.395498815643794*^9}, { 3.3954996494493756`*^9, 3.3954996553680043`*^9}, 3.3955127068553963`*^9, 3.395512766322091*^9, {3.3956844424441867`*^9, 3.395684443886275*^9}, { 3.395684548407611*^9, 3.395684549589322*^9}, {3.3956847400751266`*^9, 3.395684744681797*^9}}], Cell["\<\ Comp 160 Course Module 11 \ \>", "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.3954170235578747`*^9, {3.3954987841378627`*^9, 3.3954987842880816`*^9}, { 3.3955127681247187`*^9, 3.3955127701576824`*^9}, {3.395684447491495*^9, 3.395684448603104*^9}, {3.427130015770479*^9, 3.4271300159307165`*^9}, { 3.46382695221875*^9, 3.463826954734375*^9}}], Cell[TextData[{ "With the ability to perform continuous computations using ", Cell[BoxData["Dynamic"]], ", we can now add more physical realism to our game. In this module, we \ review the some basic physics and add a simple physics-based model of \ movement to ", StyleBox["Disasteroids", FontSlant->"Italic"], "." }], "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, {3.3954173283091245`*^9, 3.3954174277330804`*^9}, { 3.3954962908229303`*^9, 3.3954963027503185`*^9}, {3.395499665052122*^9, 3.3954997904148855`*^9}, {3.3955127784798155`*^9, 3.395512783637334*^9}, 3.3955129641705284`*^9, {3.3956016552547894`*^9, 3.3956017652841005`*^9}, { 3.3956844525888753`*^9, 3.3956844559637613`*^9}, {3.3956848503347716`*^9, 3.3956848853454638`*^9}, {3.396105040978711*^9, 3.396105088537572*^9}}], Cell[CellGroupData[{ Cell[TextData[{ "The current state of ", StyleBox["Disasteroids", FontSlant->"Italic"] }], "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, {3.3954171137785053`*^9, 3.395417121559772*^9}}], Cell[TextData[{ "Since we will spend several modules working on ", StyleBox["Disasteroids", FontSlant->"Italic"], ", we will start with a clean version from the last module. Our \ implementation consisted of a background, a ship whose position was \ parameterized by a position and orientation, the helper function ", Cell[BoxData["vectorToAngle"]], " and the helper function ", Cell[BoxData["wrap"]], "." }], "Text", CellChangeTimes->{{3.3954174417233367`*^9, 3.395417535108549*^9}, { 3.395601419633633*^9, 3.3956014395024014`*^9}, {3.3956843879452777`*^9, 3.3956844014848814`*^9}, {3.3961056712913413`*^9, 3.3961056713414135`*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"background", "=", RowBox[{"Rectangle", "[", RowBox[{ RowBox[{"{", RowBox[{ RowBox[{"-", "1"}], ",", RowBox[{"-", "1"}]}], "}"}], ",", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]}], "]"}]}], ";"}], "\n", 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[{ RowBox[{ RowBox[{"ship", "[", RowBox[{"p_", ",", "\[Theta]_"}], "]"}], ":=", RowBox[{"Translate", "[", RowBox[{ RowBox[{"Rotate", "[", RowBox[{ RowBox[{"Scale", "[", RowBox[{"shipModel", ",", FractionBox["1", "10"]}], "]"}], ",", "\[Theta]"}], "]"}], ",", "p"}], "]"}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"vectorToAngle", "[", RowBox[{"{", RowBox[{"x_", ",", "y_"}], "}"}], "]"}], ":=", "\[IndentingNewLine]", RowBox[{"If", "[", RowBox[{ RowBox[{"y", "\[GreaterEqual]", "0"}], ",", RowBox[{"ArcCos", "[", "x", "]"}], ",", RowBox[{ RowBox[{"2", "\[Pi]"}], "-", RowBox[{"ArcCos", "[", "x", "]"}]}]}], "]"}]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"wrap", "[", "p_", "]"}], ":=", RowBox[{ RowBox[{"Mod", "[", RowBox[{ RowBox[{"p", "+", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]}], ",", "2"}], "]"}], "-", RowBox[{"{", RowBox[{"1", ",", "1"}], "}"}]}]}]}], "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}, { 3.395417155168434*^9, 3.3954171685077477`*^9}, {3.3956014098094087`*^9, 3.395601410981105*^9}, {3.395684096333052*^9, 3.3956841000684605`*^9}, { 3.3956843522235565`*^9, 3.395684353355195*^9}}], Cell[TextData[{ "Here is my latest version of ", StyleBox["Disasteroids", FontSlant->"Italic"], " that uses the gamepad controls in a natural manner." }], "Text", CellChangeTimes->{{3.3956015301236115`*^9, 3.3956015644833612`*^9}, 3.3956710740695677`*^9, {3.3956844090157857`*^9, 3.3956844270819435`*^9}, { 3.39568472067704*^9, 3.3956847314826856`*^9}}], Cell[BoxData[ RowBox[{"DynamicModule", "[", RowBox[{ RowBox[{"{", RowBox[{ RowBox[{"p", "=", RowBox[{"{", RowBox[{"0", ",", "0"}], "}"}]}], ",", RowBox[{"\[Theta]", "=", "0"}], ",", RowBox[{"c", "=", ".1"}]}], "}"}], ",", "\[IndentingNewLine]", RowBox[{"Panel", "[", RowBox[{ RowBox[{"Column", "[", RowBox[{"{", "\[IndentingNewLine]", RowBox[{ RowBox[{"Graphics", "[", RowBox[{ RowBox[{"{", "\[IndentingNewLine]", RowBox[{ "background", ",", "\[IndentingNewLine]", "White", ",", "\[IndentingNewLine]", RowBox[{"Dynamic", "[", "\[IndentingNewLine]", RowBox[{ RowBox[{"p", "+=", RowBox[{"c", " ", RowBox[{"{", RowBox[{ RowBox[{"Cos", "[", "\[Theta]", "]"}], ",", RowBox[{"Sin", "[", "\[Theta]", "]"}]}], "}"}], RowBox[{"(", RowBox[{ RowBox[{"ControllerState", "[", "\"\\"", "]"}], " ", "-", RowBox[{"ControllerState", "[", "\"\\"", "]"}]}], ")"}]}]}], ";", "\[IndentingNewLine]", RowBox[{"\[Theta]", "=", RowBox[{"vectorToAngle", "[", RowBox[{"Normalize", "[", RowBox[{"{", RowBox[{ RowBox[{ "ControllerState", "[", "\"\\"", "]"}], ",", RowBox[{"-", RowBox[{ "ControllerState", "[", "\"\\"", "]"}]}]}], "}"}], "]"}], "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"ship", "[", RowBox[{ RowBox[{"wrap", "[", "p", "]"}], ",", "\[Theta]"}], "]"}]}], "]"}]}], "}"}], ",", "\[IndentingNewLine]", RowBox[{"PlotRange", "\[Rule]", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{ RowBox[{"-", "1.1"}], ",", "1.1"}], "}"}], ",", RowBox[{"{", RowBox[{ RowBox[{"-", "1.1"}], ",", "1.1"}], "}"}]}], "}"}]}]}], "]"}], ",", "\[IndentingNewLine]", RowBox[{"Button", "[", RowBox[{"\"\\"", ",", RowBox[{ RowBox[{"\[Theta]", "=", "0"}], ";", RowBox[{"p", "=", RowBox[{"{", RowBox[{"0", ",", "0"}], "}"}]}]}]}], "]"}]}], "}"}], "]"}], ",", "\[IndentingNewLine]", RowBox[{"Style", "[", RowBox[{"\"\\"", ",", RowBox[{"FontSize", "\[Rule]", "36"}], ",", "Red", ",", "Italic"}], "]"}], ",", "Top"}], "]"}]}], "]"}]], "Input", CellChangeTimes->{{3.3944607240579944`*^9, 3.3944608783529367`*^9}, { 3.394460909508357*^9, 3.39446105302759*^9}, {3.3944611755261765`*^9, 3.3944612086544733`*^9}, {3.394461376819637*^9, 3.394461394565508*^9}, { 3.394461498316764*^9, 3.394461581467988*^9}, {3.3944616120726056`*^9, 3.394461855096904*^9}, {3.3944621652090073`*^9, 3.394462165869971*^9}, { 3.3944622961298733`*^9, 3.3944622987236547`*^9}, {3.3945600411282554`*^9, 3.39456008757597*^9}, {3.3945601200433035`*^9, 3.394560154613703*^9}, { 3.3954172615524673`*^9, 3.3954172657385283`*^9}, {3.3954195203529863`*^9, 3.395419556375142*^9}, {3.3954974223725843`*^9, 3.395497423263883*^9}, { 3.3954974922945213`*^9, 3.3954975070360126`*^9}, {3.3954982630581956`*^9, 3.3954983590481367`*^9}, {3.39550331643537*^9, 3.3955034100017776`*^9}, { 3.3955034569101644`*^9, 3.3955034940843596`*^9}, {3.395503525570262*^9, 3.3955035490344696`*^9}, 3.395503685092825*^9, {3.3955842937170095`*^9, 3.3955843973971276`*^9}, {3.395584451906051*^9, 3.3955845333639936`*^9}, { 3.395584590546789*^9, 3.3955846053181763`*^9}, {3.3955846862753944`*^9, 3.3955847021784205`*^9}, {3.3955848806368103`*^9, 3.395584882008797*^9}, { 3.39558512009352*^9, 3.3955851669012933`*^9}, {3.395598929928788*^9, 3.395599047418902*^9}, {3.395599102658884*^9, 3.3955991123829637`*^9}, { 3.395599179910737*^9, 3.3955991901956286`*^9}, {3.395599532180789*^9, 3.3955995364169226`*^9}, {3.3955995679325542`*^9, 3.3955995731100507`*^9}, {3.3955996393359394`*^9, 3.3955996461357846`*^9}, {3.395599689007859*^9, 3.395599689879121*^9}, { 3.395599724479218*^9, 3.3955997262017117`*^9}, {3.395599801010027*^9, 3.3955998072690897`*^9}, {3.3956001144338336`*^9, 3.3956002078090315`*^9}, 3.39560024539345*^9, {3.395668727081362*^9, 3.395668752197728*^9}, { 3.3956688026607933`*^9, 3.395668841336793*^9}, 3.3956814597555504`*^9, { 3.395681499533144*^9, 3.3956815695945864`*^9}, {3.395681604905713*^9, 3.395681611795689*^9}, {3.3956816469666133`*^9, 3.395681669098658*^9}, { 3.395682336555069*^9, 3.395682339248969*^9}, {3.3956824090500345`*^9, 3.3956824127253556`*^9}, {3.3956826037319145`*^9, 3.395682634516487*^9}, { 3.3956841478576546`*^9, 3.395684176529168*^9}, {3.463916848171875*^9, 3.463916884046875*^9}, {3.464016688868986*^9, 3.4640167155112734`*^9}, { 3.4640168132175293`*^9, 3.4640168414885817`*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Discretizing physical equations", "Section", CellChangeTimes->{{3.3956846149940214`*^9, 3.3956846200112863`*^9}, { 3.395684908288683*^9, 3.3956849408257933`*^9}}], Cell[TextData[{ "Up to now, our control models for the ship in ", StyleBox["Disasteroids", FontSlant->"Italic"], " have been based on control of the absolute position and orientation of the \ ship or control of the relative position and orientation of the ship. To \ build a more refined control model for the ship, we first must review some \ basis calculus and physics and then derive a second-order model of the ship \ motion based on acceleration." }], "Text", CellChangeTimes->{{3.395684823726245*^9, 3.3956848356835585`*^9}, { 3.396105140492798*^9, 3.396105248018484*^9}, {3.3961062926510077`*^9, 3.3961063160548944`*^9}, 3.39610921884785*^9}], Cell[TextData[{ "The traditional approach to incorporating physics into a game is to \ derive/recall the appropriate physical laws in their continuous form and then \ derive a discrete version of these laws that takes into account the discrete \ nature of physical simulations using the computer. To begin, let ", Cell[BoxData[ RowBox[{"p", "[", "t", "]"}]]], " denote the position of the ship at time ", Cell[BoxData["t"]], ". According to basic calculus, the velocity of the ship is simply the \ derivative of ", Cell[BoxData[ RowBox[{"p", "[", "t", "]"}]]], ", that is," }], "Text", CellChangeTimes->{{3.396105249841123*^9, 3.3961053141842856`*^9}, { 3.396105380700595*^9, 3.3961055453590035`*^9}, 3.463827134703125*^9}], Cell[BoxData[ RowBox[{ RowBox[{"v", "[", "t", "]"}], "=", RowBox[{ RowBox[{ SuperscriptBox["p", "\[Prime]", MultilineFunction->None], "[", "t", "]"}], "."}]}]], "DisplayFormula", CellChangeTimes->{{3.396105562193378*^9, 3.3961055835042343`*^9}}], Cell[TextData[{ "Similarly, the acceleration ", Cell[BoxData[ RowBox[{"a", "[", "t", "]"}]]], " of the ship is the derivative of the velocity ", Cell[BoxData[ RowBox[{"v", "[", "t", "]"}]]], ", that is," }], "Text", CellChangeTimes->{{3.3961055878204837`*^9, 3.396105623692423*^9}, 3.463827046625*^9, 3.463827137390625*^9}], Cell[BoxData[ RowBox[{ RowBox[{"a", "[", "t", "]"}], "=", RowBox[{ RowBox[{ SuperscriptBox["v", "\[Prime]", MultilineFunction->None], "[", "t", "]"}], "."}]}]], "DisplayFormula", CellChangeTimes->{{3.396105562193378*^9, 3.3961055835042343`*^9}, { 3.3961056314636745`*^9, 3.3961056334665747`*^9}}], Cell[TextData[{ "Given these continuous equations, our goal is to compute a set of discrete \ values ", Cell[BoxData[ RowBox[{"p", "[", SubscriptBox["t", "i"], "]"}]]], ", ", Cell[BoxData[ RowBox[{"v", "[", SubscriptBox["t", "i"], "]"}]]], ", and ", Cell[BoxData[ RowBox[{"a", "[", SubscriptBox["t", "i"], "]"}]]], " at a set of time steps ", Cell[BoxData[ SubscriptBox["t", "0"]]], ", ", Cell[BoxData[ SubscriptBox["t", "1"]]], ", ", Cell[BoxData[ SubscriptBox["t", "2"]]], ", ", Cell[BoxData["\[Ellipsis]"]], " that ", StyleBox["approximately", FontSlant->"Italic"], " satisfy the continuous equations. The key to this discretization is to \ recall the definition of the derivative." }], "Text", CellChangeTimes->{{3.3961057221549864`*^9, 3.396105743716205*^9}, { 3.396105775482199*^9, 3.3961059086450057`*^9}, {3.46382706071875*^9, 3.463827061984375*^9}}], Cell[BoxData[ RowBox[{ RowBox[{ SuperscriptBox["p", "\[Prime]", MultilineFunction->None], "[", "t", "]"}], "=", " ", RowBox[{ UnderscriptBox["lim", RowBox[{"\[Epsilon]", "\[Rule]", "0"}]], " ", RowBox[{ FractionBox[ RowBox[{ RowBox[{"p", "[", RowBox[{"t", "+", "\[Epsilon]"}], "]"}], "-", RowBox[{"p", "[", "t", "]"}]}], "\[Epsilon]"], "."}]}]}]], "DisplayFormula", CellChangeTimes->{{3.396105756654939*^9, 3.396105764285988*^9}, { 3.3961059190701*^9, 3.396105969703412*^9}}], Cell["\<\ In our particular case, this definition leads to two sets of discrete \ equations\ \>", "Text", CellChangeTimes->{{3.396105977274374*^9, 3.3961060168316493`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"v", "[", SubscriptBox["t", "i"], "]"}], "=", FractionBox[ RowBox[{ RowBox[{"p", "[", SubscriptBox["t", RowBox[{"i", "+", "1"}]], "]"}], "-", RowBox[{"p", "[", SubscriptBox["t", "i"], "]"}]}], RowBox[{ SubscriptBox["t", RowBox[{"i", "+", "1"}]], "-", SubscriptBox["t", "i"]}]]}], ",", "\[IndentingNewLine]", RowBox[{ RowBox[{"a", "[", SubscriptBox["t", "i"], "]"}], "=", RowBox[{ FractionBox[ RowBox[{ RowBox[{"v", "[", SubscriptBox["t", RowBox[{"i", "+", "1"}]], "]"}], "-", RowBox[{"v", "[", SubscriptBox["t", "i"], "]"}]}], RowBox[{ SubscriptBox["t", RowBox[{"i", "+", "1"}]], "-", SubscriptBox["t", "i"]}]], "."}]}]}]], "DisplayFormula", CellChangeTimes->{{3.396105756654939*^9, 3.396105764285988*^9}, { 3.3961059190701*^9, 3.396105969703412*^9}, {3.396106027106526*^9, 3.396106092290907*^9}}], Cell[TextData[{ "If we assume that the time spacing is uniform, that is, ", Cell[BoxData[ RowBox[{"\[Delta]", "=", RowBox[{ SubscriptBox["t", RowBox[{"i", "+", "1"}]], "-", SubscriptBox["t", "i"]}]}]]], " for all ", Cell[BoxData["i"]], ", these equations reduce to " }], "Text", CellChangeTimes->{{3.396106098770288*^9, 3.396106129695064*^9}, { 3.396106260344231*^9, 3.3961062624372616`*^9}, 3.46382712928125*^9}], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"p", "[", SubscriptBox["t", RowBox[{"i", "+", "1"}]], "]"}], "=", RowBox[{ RowBox[{"p", "[", SubscriptBox["t", "i"], "]"}], "+", RowBox[{"\[Delta]", " ", RowBox[{"v", "[", SubscriptBox["t", "i"], "]"}]}]}]}], ",", "\[IndentingNewLine]", RowBox[{ RowBox[{"v", "[", SubscriptBox["t", RowBox[{"i", "+", "1"}]], "]"}], "=", RowBox[{ RowBox[{"v", "[", SubscriptBox["t", "i"], "]"}], "+", RowBox[{"\[Delta]", " ", RowBox[{ RowBox[{"a", "[", SubscriptBox["t", "i"], "]"}], "."}]}]}]}]}]], "DisplayFormula", CellChangeTimes->{{3.396105756654939*^9, 3.396105764285988*^9}, { 3.3961059190701*^9, 3.396105969703412*^9}, {3.396106027106526*^9, 3.396106092290907*^9}, {3.396106471540022*^9, 3.396106496165677*^9}}], Cell["\<\ Simplifying these equation even further, we can drop the subscripts and \ arrive at the recurrences\ \>", "Text", CellChangeTimes->{{3.3961063302955136`*^9, 3.396106373888632*^9}, { 3.396106427866787*^9, 3.396106433394791*^9}, 3.400335830961361*^9}], Cell[BoxData[ RowBox[{ RowBox[{"p", "=", RowBox[{"p", "+", RowBox[{"\[Delta]", " ", "v"}]}]}], ",", "\[IndentingNewLine]", RowBox[{"v", "=", RowBox[{"v", "+", RowBox[{"\[Delta]", " ", "a"}]}]}], ",", "\[IndentingNewLine]", RowBox[{"a", "=", "\[Ellipsis]"}], " ", ","}]], "DisplayFormula", CellChangeTimes->{{3.396105756654939*^9, 3.396105764285988*^9}, { 3.3961059190701*^9, 3.396105969703412*^9}, {3.396106027106526*^9, 3.396106092290907*^9}, {3.396106471540022*^9, 3.3961065372752*^9}}], Cell[TextData[{ "where the current ", Cell[BoxData[ FormBox[ StyleBox["p", FontFamily->"Courier New", FontSlant->"Plain"], TraditionalForm]]], " and ", Cell[BoxData[ FormBox[ StyleBox["v", FontFamily->"Courier New", FontSlant->"Plain"], TraditionalForm]]], " are computed from their previous values, and the current acceleration ", Cell[BoxData["a"]], " is usually computed from controller input. Note that to start this \ recurrence, we must supply initial values for ", Cell[BoxData["p"]], ", ", Cell[BoxData["v"]], ", and ", Cell[BoxData["a"]], "." }], "Text", CellChangeTimes->{{3.3961065397888393`*^9, 3.3961065865465393`*^9}, { 3.3961092572534575`*^9, 3.396109257623994*^9}, {3.463827177625*^9, 3.46382720128125*^9}, {3.463827255046875*^9, 3.46382727375*^9}}], Cell[CellGroupData[{ Cell["Exercise", "Exercise", CellChangeTimes->{{3.3956848103669024`*^9, 3.395684812099411*^9}, { 3.3961053094574413`*^9, 3.3961053103787756`*^9}}], Cell[TextData[{ StyleBox["1. Construct a second-order physical control model for the ship \ based on this recurrence. I suggest that you set the acceleration ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["a"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" to be a scalar multiple of the current forward vector for the \ ship. Thus, in this model, the left joystick control the orientation (and \ forward vector) in an absolute manner while the triggers control the \ acceleration in this direction.", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.3956818915407324`*^9, 3.395682322044058*^9}, { 3.395682725878771*^9, 3.395682727090525*^9}, {3.3956830647994943`*^9, 3.395683101112071*^9}, {3.3956831377250834`*^9, 3.3956832851986103`*^9}, { 3.3956833907013674`*^9, 3.3956834280454383`*^9}, 3.3956834858992047`*^9, { 3.395684820271243*^9, 3.395684820441489*^9}, {3.3961066093996286`*^9, 3.3961067718248043`*^9}}], Cell[TextData[{ StyleBox["2. Modify your physical model to add a friction term to the \ acceleration ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["a"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[". The acceleration due to friction should be in the opposite \ direction of the velocity vector ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["v"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[".", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.3956818915407324`*^9, 3.395682322044058*^9}, { 3.395682725878771*^9, 3.395682727090525*^9}, {3.3956830647994943`*^9, 3.395683101112071*^9}, {3.3956831377250834`*^9, 3.3956832851986103`*^9}, { 3.3956833907013674`*^9, 3.3956834280454383`*^9}, {3.3956834858992047`*^9, 3.3956834956433134`*^9}, {3.3956835312048025`*^9, 3.3956835546687765`*^9}, {3.396107329231874*^9, 3.3961073730352974`*^9}, { 3.3961074558952703`*^9, 3.396107499638606*^9}, 3.4003358350707626`*^9}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["Particle systems", "Section", CellChangeTimes->{{3.394476039152499*^9, 3.394476043749201*^9}, { 3.3945574695592384`*^9, 3.394557483559649*^9}}], Cell[TextData[{ "Arcade games like ", StyleBox["Robotron", FontSlant->"Italic"], " and ", StyleBox["Asteroids", FontSlant->"Italic"], " consist of not just a character or ship moving around the screen, but also \ a number of adversaries that move around the screen. Newer games such a ", StyleBox["Half-Life", FontSlant->"Italic"], " and ", StyleBox["Halo", FontSlant->"Italic"], " include lots of visual effects in which multiple objects (such as \ explosion effects) briefly appear on the screen to add to the visual \ complexity to the game. A typical method for implementing such effects is \ known as a ", StyleBox["particle system", FontSlant->"Italic"], ". A particle system consist of a set of points moving according to some \ simple physical laws. Attach to each point is some type of simple visual \ effect that may vary over time. In ", StyleBox["Asteroids", FontSlant->"Italic"], ", the visual effect was simply a line model of a boulder. In ", StyleBox["Robotron", FontSlant->"Italic"], ", the visual effect was a 2D image/animation." }], "Text", CellChangeTimes->{{3.394477161588867*^9, 3.394477169810854*^9}, 3.395684595135268*^9, {3.396107764331856*^9, 3.396108010037613*^9}, { 3.3961081873843937`*^9, 3.3961081898279314`*^9}, {3.463827348625*^9, 3.46382735321875*^9}}], Cell[TextData[{ "For games built in ", StyleBox["C#", FontSlant->"Italic"], " and other languages that support threading, particles are usually \ implemented as a separate thread that runs concurrently with the other \ threads. The advantage of this approach is that the particle thread can be \ given a low priority since particles are primarily responsible for visual \ effects and any slow-down in the particle thread won't affect the core \ gameplay. Since ", StyleBox["Mathematica", FontSlant->"Italic"], " does not support explicit threading, we will simulate threading by a \ second chuck of code inside ", Cell[BoxData["Dynamic"]], " that updates a particle system each time the physical model for the ship \ is updated." }], "Text", CellChangeTimes->{{3.3944746100461073`*^9, 3.39447461867852*^9}, { 3.394477175709453*^9, 3.394477227715271*^9}, {3.39610823422221*^9, 3.396108493778021*^9}}], Cell[CellGroupData[{ Cell["Exercises", "Exercise", CellChangeTimes->{{3.396108526966074*^9, 3.3961085294096117`*^9}}], Cell[TextData[{ StyleBox["1. Our final task for this module is to add a crude particle \ system to ", FontColor->RGBColor[0.5, 0, 0.5]], StyleBox["Disasteroids", FontSlant->"Italic", FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" that models a set of disk-shaped asteroids move on the \ background. We will represent each particle as a pair corresponding to its \ current position and velocity. To keep our particle code organized, we will \ construct two helper functions: ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"makeAst", "[", "n", "]"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" builds a list of ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["n"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" particles (using ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["RandomReal"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[") and ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"updateAstPos", "[", "ast", "]"}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" takes a list of particles and updates their position using their \ associated velocity.", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.3961085545860653`*^9, 3.3961088239661007`*^9}, 3.4003358501958594`*^9, 3.4638274456875*^9}], Cell[TextData[{ StyleBox["2. Modify your implementation of ", FontColor->RGBColor[0.5, 0, 0.5]], StyleBox["Disasteroids", FontSlant->"Italic", FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" to include the particle system above. I suggest that you add an \ update of the form ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData[ RowBox[{"ast", "=", RowBox[{"updateAstPos", "[", "ast", "]"}]}]], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" inside ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["Dynamic"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" in your implementation. Use the function ", FontColor->RGBColor[0.5, 0, 0.5]], Cell[BoxData["wrap"], FontColor->RGBColor[0.5, 0, 0.5]], StyleBox[" to handle the asteroids moving off of the background.", FontColor->RGBColor[0.5, 0, 0.5]] }], "ExerciseText", CellChangeTimes->{{3.3961085545860653`*^9, 3.3961088239661007`*^9}, { 3.3961088694719887`*^9, 3.3961089488869734`*^9}, {3.3961091345257597`*^9, 3.396109156838066*^9}}] }, Open ]] }, Open ]] }, WindowToolbars->{}, WindowSize->{1016, 1023}, WindowMargins->{{0, Automatic}, {Automatic, 0}}, PrintingCopies->1, PrintingPageRange->{1, Automatic}, PrintingOptions->{"PrintCellBrackets"->False, "PrintMultipleHorizontalPages"->False, "PrintRegistrationMarks"->True, "PrintingMargins"->{{54, 54}, {72, 72}}}, ShowSelection->True, Magnification:>FEPrivate`If[ FEPrivate`Equal[FEPrivate`$VersionNumber, 6.], 2., 2. Inherited], 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, 708, 10, 109, "Title"], Cell[1256, 32, 549, 10, 120, "Subtitle"], Cell[1808, 44, 1021, 18, 114, "Text"], Cell[CellGroupData[{ Cell[2854, 66, 451, 9, 107, "Section"], Cell[3308, 77, 649, 14, 148, "Text"], Cell[3960, 93, 2264, 67, 451, "Input"], Cell[6227, 162, 366, 8, 47, "Text"], Cell[6596, 172, 5276, 104, 602, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[11909, 281, 171, 2, 107, "Section"], Cell[12083, 285, 663, 12, 179, "Text"], Cell[12749, 299, 740, 16, 182, "Text"], Cell[13492, 317, 264, 7, 51, "DisplayFormula"], Cell[13759, 326, 337, 10, 48, "Text"], Cell[14099, 338, 317, 8, 51, "DisplayFormula"], Cell[14419, 348, 910, 33, 115, "Text"], Cell[15332, 383, 538, 16, 75, "DisplayFormula"], Cell[15873, 401, 173, 4, 47, "Text"], Cell[16049, 407, 1007, 33, 140, "DisplayFormula"], Cell[17059, 442, 443, 13, 81, "Text"], Cell[17505, 457, 852, 25, 86, "DisplayFormula"], Cell[18360, 484, 263, 5, 47, "Text"], Cell[18626, 491, 521, 11, 120, "DisplayFormula"], Cell[19150, 504, 810, 26, 116, "Text"], Cell[CellGroupData[{ Cell[19985, 534, 149, 2, 74, "Exercise"], Cell[20137, 538, 974, 17, 114, "ExerciseText"], Cell[21114, 557, 980, 20, 116, "ExerciseText"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[22143, 583, 152, 2, 107, "Section"], Cell[22298, 587, 1333, 33, 278, "Text"], Cell[23634, 622, 917, 20, 246, "Text"], Cell[CellGroupData[{ Cell[24576, 646, 97, 1, 74, "Exercise"], Cell[24676, 649, 1308, 33, 214, "ExerciseText"], Cell[25987, 684, 1022, 26, 148, "ExerciseText"] }, Open ]] }, Open ]] } ] *) (* End of internal cache information *)