6.10.1

Assignment 9: Plotting functions

This assignment is due on Wednesday, 10/25 at 11:59 PM. Submit it using the Handin server as assignment a9.

Important Note: Whenever we say to design or write a function, we mean that you must follow the design recipe and you will be graded accordingly.

Important Note: Use the Intermediate Student Language with lambda on this and further assignments in this course.

In this assignment, you will develop a program which allows the user to interact with a visual representation of a given function. See Graph of a function.

In this assignment, the word graph will refer to a list of posns obtained from a given function f. The x field of each posn will store an x-value. The y field of each posn will store the value of f evaluated at the number stored in the x field. By drawing or plotting, we mean producing an image from the graph of a function.

The data contained in a graph will be interpreted as points in a Cartesian coordinate system. A big part of this assignment will be to relate lists of posns interpreted in a Cartesian coordinate system to lists of posns interpreted in the coordinate system of a DrRacket image. In this way, we will not just show a fixed image, but let the user move and zoom the view of the function.

Exercise 1 Define constants width and height which will be used to determine the width and height of the scene. Using build-list, define my-points to be a long list of posns of your making.

Exercise 2 Design a function draw-lop which takes a list of posns and returns an image. The purpose of draw-lop is to represent each posn as a dot of some shape and color on a scene. Use foldr. Apply draw-lop to my-points and store the result in a constant my-plot.

Exercise 3 Design a function center-origin which takes a list of posns and returns a list of posns. The input list of posns is interpreted with respect to an origin in the middle of your scene. Furthermore, the positive y-direction is interpreted to point upward. The purpose of center-origin is to produce the corresponding list of posns in the coordinate system of a DrRacket image. For example, if the scene is 400 by 400, then the input
(list (make-posn 0 0) (make-posn -50 200))
should yield to the output
(list (make-posn 200 200) (make-posn 150 0))
For center-origin, use map.

Apply draw-lop to the result of applying center-origin to my-points and store the final image as my-centered-plot.

Exercise 4 Define a struct named plane whose four fields are xscale, yscale, x0 and y0. For the big-bang programs in this assignment, a world will be a (make-plane Number Number Number Number).

Exercise 5 Design a function image-coords which takes a plane and a list of posns and returns a list of posns. The new function image-coords is a more general version of center-origin. Like center-origin, the new function image-coords should produce the corresponding list of posns in the coordinate system of a DrRacket image. Also like center-origin, the new function image-coords should interpret the positive y-direction in its input to point upward. But instead of interpreting the origin of the input list of posns to be the center of scene, interpret it to be given by the fields x0 and y0 of the input plane. So the fields x0 and y0 themselves are in the coordinate system of a DrRacket image. Finally, interpret xscale and yscale to be the number of pixels in an input x-unit and y-unit. For example, if xscale is 100, then an input posn (make-posn -2 0) is 200 pixels to the left of the origin. If yscale is 5, then an input posn (make-posn 0 5) is 25 pixels directly above the origin. Again, use map. Also, feel free to use center-origin.

Exercise 6 Design a function navigate to be used as a big-bang key-event handler. Thus, navigate takes a plane and a key event and returns a plane. navigate enables 9 distinct keyboard-driven behaviors (aside from nothing at all). The arrow keys will allow the user to move in four different directions in the scene: they will change values stored in the x0 and y0 fields of the input plane according to a globally defined move-speed. The keys w, a, s and d will allow the user to zoom in four ways: the w key will zoom in just with respect to the y-axis and the s key will do the opposite; the d key will zoom in just with respect to the x-axis and the a key will do the opposite. The w, a, s and d keys should then (at least) update the xscale and yscale fields by a globally defined zoom-factor. Finally, the r key will reset the world to the globally defined init-plane.

Exercise 7 Define a big-bang program using the functions defined in Exercises 2, 5 and 6 that allows you to navigate a plot of my-points. Define a constant my-interactive-plot that stores the result of this big-bang program.

Exercise 8 Design a function xticks which takes three numbers xscale, x0 and n and produces an increasing list of n numbers starting at (- 0 (/ x0 xscale)). Each number is (/ 1 xscale) larger than its predessor. The output list will be interpreted as x-values in the Cartesian coordinate system.

If n is taken to be (add1 width), the output numbers will range across the visible portion of the plot. For example, if width is set to 400, then
(xticks 100 200 (add1 width))
will produce a list of 401 evenly distributed numbers starting with -2 and ending with 2:
(list -2 -1.99 -1.98 ... 1.98 1.99 2)

You may use build-list or not.

Exercise 9 Design a function graph which takes a function Number -> Number and a list of numbers and produces a list of posns. The output posns contain a number from the input list paired with the value of the input function applied to that number. For example,
(graph sqr (list 0 2))
would give
(list (make-posn 0 0) (make-posn 2 4))

Exercise 10 Design a function draw-graph which takes a plane and a function Number -> Number and produces its plot. draw-graph should be the composite of draw-lop, image-coords, graph and xticks. Pass (add1 width) to xticks as the number of ticks to generate.

Exercise 11 Design a big-bang program with draw-graph and navigate to visualize interactively the sin function. Store the result in a constant named interactive-sin.

Extra fun (Challenging) The zoom behavior we have defined in navigate is simple to define but not exactly what we want. Can you see what is going wrong? Typically when we zoom, we expect the center point of the scene to remain fixed during the zoom. However, in your current implementation, unless the center of the scene is aligned with the origin, the center point of the scene shifts during a zoom. This suggests that x0 and y0 should also be adjusted while zooming in navigate. Can you see how? Hint: Determine the image coordinates of the center of the scene. Use these values and zoom-factor to update x0 and y0 so that the center point remains fixed.