Preserving State Information

When a large number of objects are to be animated or otherwise manipulated in some fashion, some method of preserving their "state" information of time must be employed. For example, if the animation paths of birds in a flock, fish in a school, or particles in a fountain are to be calculated, then the position and velocity of each object must be stored somehow. Below are several methods for doing so in scheme ranging in conceptually crude to elegent.

Simple Lists

In some respects, the simplest method of maintaining state information for an object is to represent its state as a list of values.

For example, if you have a "bird" and need to store its name, current position, color, direction, and speed, you could store them in a list that looks something like this:

 ox --> (define bird (list "Opus" (vec3 10 -12 0) (vec3 .4 0 0) 
                           (vec3 0 0 1) 5))
 bird
 ox --> bird
 ("Opus" #<10 -12 0> #<0.4 0 0> #<0 0 1> 5)
This could represent a bird named opus, positioned at #<10 -12 0>, who was dark red, heading due Z, at five units per frame.

To access any of this information, you would need to know the position in the list of item in question. So to find out Opus's color, you would need to remember that color is the thrid element in the list. You could then say:

 ox --> (list-ref bird 2)
 #<0.4 0 0>
Why "2" instead of "3" to get the third element in the list? Remember, computers count up from zero... so the bird's name is the zeroeth item in the list, making color the "second" item.

Depending on the complexity of what you're doing, you might also consider using vectors instead of lists. They are faster and will take less memory, but use a completely different set of access functions.

Key/Value Pairs

An alternative method is to use "key/value" pairs, which allows you to say something like:
 ox --> (define bird (list (list 'name "Opus") 
                           (list 'position (vec3 10 -12 0))
                           (list 'color (vec3 .4 0 0))
                           (list 'direction (vec3 0 0 1))
                           (list 'speed 5)
			   ))
 bird
In other words, bird is represented by a list of "pairs", with each pair being a list containing a symbol and a value. Given this representation, we can now say:
 ox --> (assq 'color bird)
 (color #<0.4 0 0>)
 ox --> (assq 'direction bird)
 (direction #<0 0 1>)
This gives us the pair, but not the value. To get the value from the two element list, we can either use "cadr" or "list-ref":
 ox --> (cadr (assq 'direction bird))
 #<0 0 1>
 ox --> (list-ref (assq 'direction bird) 1)
 #<0 0 1>

Roll Your Own Simple OOPS Package

Using the "lambda" construct, you can produce your own simple message passing system, and tailor it to your needs. Here is a simple example.

The Built-In Elk OOPS Package

There is an OOPS Package built into Elk (the scheme interpreter upon which ox is built. Documentation for using it can be found here.


Return to Schedule Information
mrl