So far we have delt with simple scenes consisting of a few lines and shapes. In most situations we will want to deal with much more complex scenes consisting of many objects. One way to draw multiple objects would be to simply repeat code. But for large numbers of objects it can be easier to declare a record that describes a type of object's properties and then use an array of that record to store and draw multiple objects.
Excercise 3-15.
We're going to write a program that fills the screen with flower-like polygons that appear to bloom.
  1.   Create a record that defines the properties of a single flower. These properties should be Position, PetalCount, and Color. Then create a dynamic array variable of this record.
  2.   Now define a procedure that draws a flower given an instance of TFlower. Don't implement the procedure yet, just define the header (i.e. procedure DrawFlower(...)). This procedure will take 2 arguments: Flower and Radius (the latter will be used for the "bloom" effect).
  3.   Call DrawFlower (even though we haven't implemented it yet) inside of OnEnterFrame. You'll need to create an instance of TFlower locally in order to do so. Initialize this instance to be positioned at the origin, to have 5 petals, and to be any color you like. The radius passed to DrawFlower should be about 5. The reason we are doing this is so that we can easily debug DrawFlower as we are writing it.
  4.   Now we will implement DrawFlower. As a start, write code inside DrawFlower that would draw an octagon (8 sides) using MoveTo and LineTo statements. Hint: Think circles. You'll probably want to use the following code:
    function PolarToXY(Theta,Radius : Double) : TVector2D;
    begin
      Result.X := cos(Theta*PI/180)*Radius;
      Result.Y := sin(Theta*PI/180)*Radius;
    end;
  5.   Modify the code to draw any regular polygon (use N as variable that represents the number of sides). Start with N = 5, but try other values to make sure your code works.
  6.   Instead of using MoveTo-LineTo statements. Let's draw a filled regular polygon with one call to FillPolygon(Points,LineColor,FillColor). In order to do this we need an array of points. We can get such an array by declaring a dynamic array Points and then using SetLength(ArrayName,Size) to set the size of the array where size is the number of vertices. We then use a similar loop in which we define the coordinates of each vertex using Points[K].
  7.   Now we have code that draws a polygon but this doesn't really look like a flower. Assuming a flower has a star-shaped look to it, we can modify the code so that every other vertex is at half the radius. To do this, we recommend using an N of 10. Each point should then be either PolarToXY(0,0,360/N*K,Radius) or PolarToXY(0,0,360/N*K,Radius/2), but how do we alternate between the two? This is where the mod operator is helpful. If we do modular division by 2 on K then the result is 0 when K is even and 1 when K is odd. So we can use K mod 2 = 0 in an if statement to determine when K is even. Implement code that alternates between Radius and Radius/2 using this advice.
  8.   Now we have a star shape. To make the petals of the flower appear as though they are separate, add a second for loop after FillPolygon with MoveTo-LineTo statements that draws a line from the center of the flower to each of the Radius/2 vericies (i.e. when K mod 2 = 1). Then place a small circle at the center.
  9.   We now have a basic flower drawing. Go through the code and add in the properties of Flower (Position, PetalCount, Color) where appropriate so that DrawFlower works for any flower.
  10.   Let's create a function called GenerateRandomFlower that will fill an instance of TFlower with random initialization values. GenerateRandomFlower should take 1 argument (Flower) passed by reference. Remember that we want to modify the values of Flower inside the procedure so we cannot use the const directive to pass it by reference (what should we use?). You can use the Random(UpperBound) procedure which generates a random integer from 0 to UpperBound-1. The position should be somewhere within the screen bounds (i.e., between -14 and 14 on X and -10 and 10 on Y). Remember that to position between two bounds such as -14 and 14 you can do something like Random(28)-14. If you want coordinates such as 12.3 to be included you can do (Random(280)-140)/10. The flowers can have any number of petals that you want as long as it is at least 3. The color should be chosen with HSI2Color where Hue is Random(255). Use full saturation and full intensity.
  11.   Let's generate 50 flowers randomly on the screen. We'll initialize all the flowers in Initialize. First, you should declare a global constant (it will be used by other OnEnterFrame so it must be global) called FlowerCount set to 50. Inside of Initialize, set the length of the dynamic array to FlowerCount. Then simply loop trhough every entry in Flowers (0 to FlowerCount-1) and call GenerateRandomFlower. You will then need to go to OnEnterFrame and again loop through every entry in Flowers and call DrawFlower(Flowers[K],FrameCount/100). Don't forget to call Randomize inside of Initialize in order to reset the random number generator.