Teachpacks for How to Design Programs

Animated Images, Simulating Worlds


world.ss

The teachpack provides the tools to write simple animations and interactive games. The first and simplest approach is to set up a simulation:

run-simulation : Nat Nat Number [Nat -> Scene] -> true
(run-simulation width height r create-image) creates and shows a width x height canvas, starts a clock, ticking every r (usually fractional) seconds, and, every time the clock ticks, it applies create-image to the number of ticks passed since this function call.

In addition, the function pops up a frame and displays the pictures that create-image generates. The result is a simple animation.

Optional: the function consumes an optional fifth argument, a boolean. If this argument is false or missing, run-simulation acts as described; if it is present and true, the function can create an animated GIF of the simulation after you stop it.

Example:


(define (create-UFO-scene height)
  (place-image UFO 50 height (empty-scene 100 100)))

(define UFO (overlay (circle 10 'solid 'green) (rectangle 40 4 'solid 'green)))

(run-simulation 100 100 (/ 1 28) create-UFO-scene)

For animated worlds and games, using the teachpack requires that you provide a data definition for World. In principle, there are no constraints on this data definition.

The teachpack works with two basic forms of data for visualizing the world:

Given a data definition for worlds, the following functions create worlds, visualize it, make the clock tick, and provide feedback about the mouse and keyboard actions that the program's users perform:
  1. big-bang : Nat Nat Number World -> true
    (big-bang width height n w) creates and shows a width x height canvas, starts the clock, makes it tick every n seconds, and makes w the first world
  2. big-bang : Nat Nat Number World Boolean -> true
    big-bang takes an optional fifth argument. If it is true, the world allows the generation of images from the animation, including an animated GIF image
  3. on-tick-event : (World -> World) -> true
    (on-tick-event tock) means that DrScheme must call tock on the current world every time the clock ticks; it uses the result as the next world
  4. on-key-event : (World KeyEvent -> World) -> true
    (on-key-event change) means that DrScheme must call change on the current world and a (representation of the) keyevent for every keystroke the programmer (user of the computer) makes; it uses the result as the next world
    
       ;; A KeyEvent is one of: 
       ;; -- Char (char?)
       ;; -- Symbol (symbol?)
    
       When the Keyevent is a char, the programmer (user of the computer) has hit an
       alphanumeric key. Symbols such as 'left, 'right,
       'up, 'down, 'release denote arrow keys
       or the events of releasing a key on the keypad. 
    
  5. on-mouse-event : (World Nat Nat MouseEvent -> World) -> true
    (on-mouse-event clack) means that DrScheme must call clack on the current world, the current x and y coordinates of the mouse, and and a (representation of the) mouse event for every action of the mouse the programmer (user of the computer) makes; it uses the result as the next world
    
      ;; A MouseEvent is one of:
      ;; - 'button-down
      ;; - 'button-up
      ;; - 'drag
      ;; - 'move
      ;; - 'enter
      ;; - 'leave
    
       The symbols denote the appropriate action with the mouse and (any of)
       its button(s).
    
  6. on-redraw : (World -> Scene) -> true
    (on-redraw world->scene) means that DrScheme calls world->image whenever the canvas must be redrawn (usually after a tick event/a keyboard event/a mouse event has occurred); the function consumes the current world and produces a scene, which is then displayed in the teachpack's canvas
  7. end-of-time : String u Symbol -> World
    When DrScheme evaluates (end-of-time "the end"), it stops the clock and displays the given string or symbol; no further tick events, key events, or redraw events take place until the world is created again.

For the creation of scenes from the world, use the following functions plus the functions on images below:

  1. nw:rectangle : Nat Nat Mode Color -> Image
    (nw:rectangle width height mode color) creates a width x height rectangle, solid or outlined, with its anchor in the NW corner
  2. empty-scene : Nat Nat -> Scene
    (empty-scene width height) creates a width x height "scene" (frame with origin in NW)
  3. place-image : Image Number Number Scene -> Scene
    (place-image image x y scene) places image at (x,y) into scene; (x,y) are comp. graph. coordinates
  4. scene+line : Scene Number Number Number Number Color -> Scene
    (scene+line scene x0 y0 x1 y1 c) places a line of color c from (x0,y0) to (x1,y1) into scene; (x,y) are comp. graph. coordinates; in contrast to the image.ss add-line function, this one cuts off those portions of the line that go beyond the boundaries of the given Scene.
  5. run-movie : (Listof Image) -> true
    (run-movie loi) shows the list of images in loi in a time-delayed manner; assume: all images are of the same size


Image Manipulation

Finally, the teachpack provides all the functions that image.ss provides. For completeness, the documentation of this teackpack is included here:
Data definition:


;; Mode is one of the following two symbols or strings: 
;; -- 'solid 
;; -- 'outline 
;; -- "solid"
;; -- "outline"

;; Interpretation: 'solid is used for creating solid basic
;; shapes; 'outline is used for creating outlines of basic
;; shapes. Strings are used in an analogous manner. 
Data definition:

(define-struct color (red green blue))
;; A CS is a structure: (make-color N N N)
;; where N is between 0 and 255 (inclusive).

;; Color is one of:
;; -- a color symbol, e.g., 'blue
;; -- a color string, e.g., "blue"
;; -- a CS, e.g., (make-color 0 0 255), which also denotes blue. 

;; Interpretation: Color arguments are used to paint the shapes
;; or their outlines. See below for more information about color structs.

The following predicate precisely specifies what a valid image color is:
  • image-color? : anything -> boolean
    to determine if the input is a valid image color
  • The first group of functions creates basic shapes (Image):
  • rectangle : Number Number Mode Color -> Image
    to create a rectangle using the given width, height, mode, and color
  • circle : Number Mode Color -> Image
    to create a circle using the given radius, mode, and color
  • ellipse : Number Number Mode Color -> Image
    to create an ellipse using the given width, height, and color
  • triangle : Number Mode Color -> Image
    to create an upward pointing equilateral triangle using the given edge size and color
  • star : Number[>=2] Number[>=1] Number[>=1] Mode Color -> Image
    to create a multi-pointed star; the first number specifies the number of points, the second specifies the radius where the points begin and the third specifies the radius where they end.
  • line : Number Number Color -> Image
    to create an image with a colored line from (0,0) to the point with the given coordinates
  • add-line : Image Int Int Int Int Color -> Image
    to add a line to an existing image, drawn between the two given points
  • text : String Size Color -> Image
    to create an image of the text in the given string, with the point size, and color specified by the last two arguments
  • Images have many properties. To understand how functions manipulate and create images, we need to understand one of these properties immediately: pinholes. Each image, including primitive shapes, come with a pinhole. Usually the pinhole is in the center of the shape except for those created from line and text, which have pinholes at the top left. When in doubt you can always find out where the pinhole is and even place it somewhere else:
  • pinhole-x : Image -> Int
    to determine the x coordinate of the pinhole, measuring from the left of the image
  • pinhole-y : Image -> Int
    to determine the y coordinate of the pinhole, measuring down from the top of the image
  • put-pinhole : Image Int Int -> Image
    to put the pinhole in the location specified by the arguments, counting from the left and down from the top, respectively.
  • move-pinhole : Image Int Int -> Image
    to move the pinhole down and to the right (by the specified amounts) of its current location. Use negative numbers to move it up or to the left.
  • The next group of functions build images from images:
  • overlay : Image Image Image ... -> Image
    to add the pixels of the second Image onto the first image. The operation lines up the images via their pinholes.
  • overlay/xy : Image Int Int Image -> Image
    to add the pixels of the second image onto the first image. Instead of lining up on the pinhole, the second image's pinhole is lined up with an offset from the first image's pinhole. The two coordinates specify how far down and to the right the offset should be. The pinhole of the resulting image is the same place as the pinhole in the first image.
  • For composite images, it is always possible to determine whether one occurs in the other and where:
  • image-inside? : Image Image -> Boolean
    to determine whether the pixels of the second image appear in the first.

    Be careful when using this function with jpeg images. If you use an image-editing program to crop a jpeg image and then save it, image-inside? will not recognize the cropped image, due to standard compression applied to JPEG images.

    Use PNG images instead whenever possible.

  • find-image : Image Image -> Posn
    to determine where the pixels of the second image appear in the first, with respect to the pinhole of the first image.
  • Two more properties of images are useful for image manipulations: their width and height. The two functions for extracting these properties are:
  • image-width : Image -> Int
    to obtain an Image's width in pixels
  • image-height : Image -> Int
    to obtain an image's height in pixels
  • Data definition:
    
    ;; List-of-color is one of:
    ;; -- empty
    ;; -- (cons Color List-of-color)
    
    
    Interpretation: represents a sequence of colors It is possible to extract an image's colors and pixels and to create images from a list of colors:
  • image->color-list : Image -> List-of-color
    to convert an image to a list of colors
  • color-list->image : List-of-color Nat Nat Nat Nat -> Image
    to convert a list of colors to an image with the given width and height, and pinhole coordinates (the pinhole coordinates are with respect to the top-left of the image).
  • The shrink functions trim an image by eliminating extraneous pixels.
  • shrink-tl : Image Number Number -> Image
    to shrink the image, starting from the top-left corner. The two numbers indicate how many pixels to save. The pinhole of the resulting image is in the middle of the image.
  • shrink-tr : Image Number Number -> Image
    to shrink the image, starting from the top-right corner. The two numbers indicate how many pixels to save. The pinhole of the resulting image is in the middle of the image.
  • shrink-bl : Image Number Number -> Image
    to shrink the image, starting from the bottom-left corner. The two numbers indicate how many pixels to save. The pinhole of the resulting image is in the middle of the image.
  • shrink-br : Image Number Number -> Image
    to shrink the image, starting from the bottom-right corner. The two numbers indicate how many pixels to save. The pinhole of the resulting image is in the middle of the image.
  • shrink : Image Number Number Number Number -> Image
    to shrink an image around its pinhole. The numbers are the pixels to save to left, above, to the right, and below the pinhole, respectively. The pixel directly on the pinhole is always saved.
  • The last group of functions extracts the consitiuent colors from an image and combine colors into an image, but the functions provide alpha-channel information as well. Alpha channels are a measure of transparency; 0 indicates fully opaque and 255 indicates fully transparent.
  • image->alpha-color-list : image -> list-of-alpha-color
    to convert an image to a list of alpha colors
  • alpha-color-list->image : list-of-alpha-color int int int int -> image
    to convert a list of alpha colors to an image with the given width and height, and pinhole coordinates (the pinhole coordinates are with respect to the top-left of the image).
  • make-alpha-color : int int int int -> color
    to construct an alpha color
  • alpha-color? : anything -> boolean
    to determine if its input is a color
  • alpha-color-alpha : color -> int
    to extract the alpha value of a color
  • alpha-color-red : color -> int
    to extract the red component of a color
  • alpha-color-green : color -> int
    to extract the green component of a color
  • alpha-color-blue : color -> int
    to extract the blue component of a color"