CMSC 15100: Lab 3

Due Friday, Oct 16, 10pm

In this lab, you’ll create an animation to visualize the equations that produce the Lorenz attractor, a complex 3D object.

Don’t worry; you need to understand very little about the equations to complete the lab.

1 Lorenz Equations

The Lorenz attractor is the path through 3D space defined by the equations

which describe the current velocity vector in terms of the current position. When σ = 10, β = 8/3, and ρ = 28, the path appears random. In this exercise, we’ll create a discrete approximation of this path by assuming that velocity is constant over a small time interval (dt = .02).

First define a structure 3d-posn to represent a point in 3D space. Next, write the function next-step that, given a 3d-posn, produces the next 3d-posn along the path, using the following technique:

So overall, the coordinates of the new point can be obtained as: (x2, y2, z2)=(x1+.02*vx, y1+.02*vy, z1+.02*vz)

Here are some test cases to get you started:

  (check-expect (next-step (make-3d-posn 0 0 0))

                (make-3d-posn 0 0 0))

  (check-expect (next-step (make-3d-posn 1 1 1))

                (make-3d-posn 1 38/25 29/30))

  (check-expect (next-step (make-3d-posn 1 38/25 29/30))

                (make-3d-posn 138/125 15227/7500 10637/11250))

2 2D animation

In our first animation, we’ll represent the world as a 3d-posn, and we’ll register our function next-step with (on-tick-event next-step) to produce the sequence of positions along the trajectory of the Lorenz equations.

To draw these points, we’ll need the following data definition

  ; An interval is a structure:

  ; (make-interval x y), where x and y are numbers.

  ;

  ; ex. (make-interval 0 15)

  (define-struct interval (min max))

and to write the helper function scale, which given a number n and two intervals, i and i, produces the number n with the following property: if p percent of the numbers in i are less than n, then p percent of the numbers in i are less than n. To clarify, here is a test case:

  (check-expect (scale 0 (make-interval -2 2) (make-interval 0 7)) 3.5)

Next, write a function draw-world-2D: 3d-posn -> scene which draws the world by placing a black dot at the x-y position of the given 3d-posn, completely ignoring its z-coordinate. Assume that the x-coordinate and y-coordinate are always in the intervals [-25, 25] and [-35, 35], respectively, and use your scale function to map these points into the area viewable in your scene. Make the center of your scene represent (0, 0), but remember that the pinhole of the image produced by empty-scene is not in its center. Here’s a test case, which makes some assumptions about the sizes of the scene and the dot:

  (check-expect (draw-world-2d (make-3d-posn 20 0 3))

                (place-image (circle 3 'solid 'black)

                             27 15

                             (empty-scene 30 30)))

Finally, use big-bang, on-tick-event, and on-redraw to configure your animation. Your animation should begin at the point (1, 1, 1); i.e., make the initial world be (make-3d-posn 1 1 1) by passing that as the fourth argument to big-bang.

Warning: replace the expression 0.02 with the expression (exact->inexact 0.02) at the place in your code that defines the time interval. This informs DrScheme that it’s OK to round results deriving from the time interval; without this hint, your animation will run very slowly, because exact computations take much longer than inexact ones. Unfortunately, this change invalidates your next-step test cases, so for now, you may commment them out.

For reference, is roughly what you should expect at this stage (reload this page to restart the animation):

3 3D animation

Next, we’ll reflect the path’s z-dimension in the animation by varying the color we use to draw the dot: points with large z-coordinates will be reddish, points with small z-coordinates will be yellowish, and points with z-coordinates in between will be shades of orange.

DrScheme uses the following data definition for colors:

  ; A color is a structure:

  ; (make-color r g b), where r, g, and b are integers in [0, 255].

  ;

  ; ex. (make-color 0 0 255) is blue

  ; ex. (make-color 255 0 0) is red

  ; ex. (make-color 255 255 0) is yellow

  ; ex. (make-color 255 165 0) is orange

  (define-struct color (red green blue))

Write the function z-color that, given a number, produces a color between yellow and red, using the scale function to calculate the color’s green content. You may assume that z-coordinates are always in the interval [0, 70].

Note: since the point’s z-coordinate ultimately derives from (exact->inexact 0.2), z-color’s argument will be inexact too, but the make-color function expects exact integers as arguments. To resolve this, use the functions round and inexact->exact to convert the point’s green content to an exact integer.

Write a function draw-world-3d that does nearly the same thing as draw-world-2D but uses z-color to choose the dot’s color, and hook this function into your animation. For reference, here’s roughly what you should expect:

4 Submission

Please submit your work under the lab3 tag of the drop-down menu of DrScheme's handin inteface.


This lab was adapated from previous assignments designed by Casey Klein and Robby Findler.