ActionScript Graphing Cookbook
上QQ阅读APP看书,第一时间看更新

Drawing in two dimensions

This recipe goes into the very basics of what it takes to draw in two dimensions. There's a little math in there to explain the coordinate system and transformations. It's not the most interesting read, but it is very important that you understand this for all the following recipes.

We also extensively use the ActionScript 3.0 display list concept. We will explain the principles, but if you've never heard of it, you may want to read up on it in other ActionScript tutorials or books. A few of these are mentioned in the See also section of this recipe.

Getting ready

All recipes in this book are completely editor-agnostic; you can use them in any ActionScript editor you like. The samples are provided for the free FlashDevelop IDE available at http://www.flashdevelop.org/ , because it is completely free and of a very high quality.

If you want to follow along with FlashDevelop, now is the time to download and install it. Make sure you also configure the Flex SDK, if FlashDevelop does not do this for you. The Flex SDK is the part that will be responsible for compiling and executing your programs. More information can be found on the FlashDevelop wiki found at http://www.flashdevelop.org/wikidocs/index.php?title=Configuration#Configuring_the_Flex_SDK.

In FlashDevelop, create a new AS3 project. You can create one for each chapter, or re-use the same one for most of the recipes. Most recipes will require you to set the document class. This is done by right-clicking on the class in the project view and picking set document class from the options.

If you are using Flash Professional, we will not use the timeline that you may be used to. Information on setting up the document class can be found in the following blog article: http://active.tutsplus.com/tutorials/actionscript/quick-tip-how-to-use-a-document-class-in-flash/.

How to do it...

The first three steps will need to be performed for virtually all the recipes in this book, so we won't repeat them, unless they differ:

  1. Create a new class (in this case it's called Recipe1).
  2. Have it extend flash.display.Sprite.
  3. Set it as the Document Class.

    You should have the following piece of code:

    package  
    {
      import flash.display.Sprite;
      public class Recipe1 extends Sprite
      {
        public function Recipe1()
        {
        }
      }
    }

    Tip

    Downloading the example code

    You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

  4. Now run the code. You should get a blank screen with no warnings or errors.
  5. In order to draw a nice looking point, we will actually draw a small circle. The following piece of code creates a shape, draws a circle, moves the center point, and displays it:
    package  
    {
      import flash.display.Shape;
      import flash.display.Sprite;
    
      public class Recipe1 extends Sprite 
      {
        public function Recipe1() 
        {
                var point:Shape = new Shape( ); 
                point.graphics.beginFill( 0xff9933 , 1 );
                point.graphics.drawCircle( 0 , 0 , 3 );
                point.x = 20;                                 
                point.y = 20;
                addChild( point ); 
        }
      }
    }
  6. To more easily draw points inside graph coordinates of our choosing, we can introduce graph:Sprite, which will perform a transformation on all points we draw inside it:
    package  
    {
      import flash.display.Shape;
      import flash.display.Sprite;
      import flash.geom.Matrix;
    
      public class Recipe1 extends Sprite 
      {
        public function Recipe1() 
        {
          var graph:Sprite = new Sprite();
          graph.x = 20;
          graph.y = 20;
          addChild(graph);
    
          var point:Shape = new Shape(); 
          point.graphics.beginFill( 0xff9933 , 1 );
          point.graphics.drawCircle( 0 , 0 , 3 );
          point.x = 0;
          point.y = 0;
          graph.addChild(point);
        }
      }
    }

    The visual result is exactly the same as the previous piece of code, but now the point is at the coordinates (0,0).

  7. To obtain the transformation presented in the How it works... section of this recipe, we just need to apply the right transformation to the graph sprite:
    package  
    {
      import flash.display.Shape;
      import flash.display.Sprite;
      import flash.geom.Matrix;
    
      public class Recipe1 extends Sprite 
      {
        public function Recipe1() 
        {
          var graph:Sprite = new Sprite();
          graph.x = 400;
          graph.y = 300;
          graph.scaleY = -1;
          addChild(graph);
    
          var point:Shape = new Shape(); 
          point.graphics.beginFill( 0xff9933 , 1 );
          point.graphics.drawCircle( 0 , 0 , 3 );
          point.x = 0;
          point.y = 0;
          graph.addChild(point);
        }
      }
    }

How it works...

ActionScript 3.0 uses a concept called a display list. A display list is a collection of visual elements. The most important display list is your main class. This is the list that will be displayed (that is the reason why it extends Sprite).

This list is organized as a tree. It has a root node, to which various display objects are attached. Some of these display objects can also contain more display objects, hence the tree structure.

For instance, if you add a Sprite child to your main class, it will be displayed. If you add yet another Sprite child to that child, it too will be drawn on the screen.

However this isn't the end of the story. You can apply transformations to objects in the display list. A transformation can be scaling, rotating, and moving, or all at once. If you apply a transformation to one object, this transformation will also apply to all its children. This is how we displayed a point at (0,0) that was in the center of the screen.

When drawing a point, we do this by adding a shape to the display list:

  1. First a shape is created, which will hold all data related to our point (location, color, size).
  2. The ActionScript Graphics class is used to draw a solid circle into the shape.
  3. Next we change the location of the shape.

    Note

    We could also draw the circle at the position, but because the (0,0) coordinates of the circle sprite are at the top-left corner, this would not place the point in the center of the shape. This will complicate any transformation on the shape as we'll see later on. That's because the pivot point for scaling and rotating is the (0,0) coordinate.

  4. Finally we add the point object to the display list. Without this last line, the point would not be visible.

To understand the transformation that takes place, you should take note of two different coordinate systems that are used:

  1. Screen coordinates: If you used the default FlashDevelop settings, you will have a screen that goes from x = 0, y = 0 in the upper-left corner to x = 800, y = 600 in the bottom-right corner.

    This means that the X-axis of the coordinate system goes from the left of the screen to the right. The Y-axis goes from the top, down to the bottom.

    Usually the coordinates are given as a pair, so x = 0, y = 0 is written as (0,0). The following diagram demonstrates the screen coordinates:

    How it works...
  2. Most graphs however are not drawn in screen coordinates. For instance, if you want to plot a function, you may want to put the (0,0) coordinates in the center of the screen. This might look something like the following screenshot. The graph coordinates are in blue; we show only the direction and origin for the graph axes:
    How it works...

    So if you want to draw a graph point at (0,0), you would in effect have to draw it on the screen coordinates (400,300).

    To create such a transformation, we first translate the (0,0) point to the center of the screen. And second, the Y-axis is scaled by -1. This inverts the Y direction (up is down, and down is up).

In the next recipe, we will see a transformation matrix. This matrix is a mathematical shorthand notation for a coordinate transformation.

There's more...

Although this recipe seems simple; there's much you can learn from it. Let's look at some more features.

Graphics drawing

We've only covered the very basics of drawing with the Graphics class. Further recipes will show more details. But if you can't wait, try experimenting with the color and the size. The ActionScript 3.0 reference pages have the information you need: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Graphics.html.

Coordinate systems and transformations

A great exercise is to experiment with the transformations. Try to obtain various results. If you modify the scaleX and scaleY variables, you can zoom in or out of the graph. You can even rotate your system.

Or if you're into maths, you can directly manipulate the transformation matrix of the graph sprite. Again, the ActionScript 3.0 reference guide will help you out: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html.

See also

If you want to read up on the display list, most of the ActionScript 3.0 fundamental books have a dedicated chapter about it. For instance, Learning ActionScript 3 or Essential ActionScript 3 (both published by O'Reilly) are good references.

If you want to read up on coordinate systems and transformations, you can find the best coverage in any vector maths book. Wikipedia is also a very informative source: http://en.wikipedia.org/wiki/Coordinate_system .