CS 307: 6. The Plot Thickens

Due: Friday, October 12, 2001

For this assignment, we will write Scheme functions that produce graphical plots of mathematical functions. Humans often find it easier to understand the behavior of a function from a plot of its values than from an algebraic expression or a table of values.

  1. We must define a mapping from the math world, in which the function y = f(x) is defined, to the drawing world of our graphics window. Suppose we wanted to plot y = sin(x). Since the value of sin(x) varies from -1 to 1, plotting the y values directly in the drawing window would produce a plot that looks like a straight line because the distance from -1 to 1 on the screen is only one or two pixels. A mapping D --> R transforms an element of the set D (the domain) to an element of the set R (the range). We need to be able to translate between math world and drawing world in both directions. We want our mappings to be linear so that they will preserve proportions.
    1. A linear mapping is defined by a linear equation, r = m * d + b, where d is in the domain and r is in the range. Let us define a data type mblist as a list (m b). Write a function (scale d mblist) to scale the value d to the corresponding value of r using the mblist.
    2. Write a function (invscale r mblist) (inverse scale) to scale a value r from the range to the domain using an mblist. (Hint: solve for d in the equation r = m * d + b.)
    3. Write a function (findmblist dmin dmax rmin rmax) that will produce an mblist that maps dmin to rmin and dmax to rmax. We will assume that dmin < dmax and rmin < rmax.
  2. Define global variables *plotxmin*, *plotxmax*, *plotymin*, and *plotymax* to parameterize the region of the graphics window in which a plot is to be drawn. Write a function (plotregion plotxmin plotxmax plotymin plotymax) to provide a user interface for the user to declare the area of the graphics window to be used for the plot; plotregion should set the global variables from the specified values; these are all values in drawing world.

  3. Write a program (plot f xmin xmax ymin ymax) that plots the value of the function y = f(x). The arguments are all values in math world. Example: (plot sin (- pi) pi -1 1)
    1. First, plot should create mblists to scale from math world to drawing world in both the x and y directions.
    2. Compute a quantity dx that represents a small change in x (math world) that corresponds to an amount 2 in the drawing world.
    3. Using iteration or recursion (your choice), draw the function values in the window. Begin the x value at xmin and increment it by dx each time until it exceeds xmax (or use some equivalent method of counting the number of steps). For each x value, calculate y as (f x). Use the mblists and the function scale to map x and y into drawing coordinates, and draw a line from the last point to the current point. (For the first point, move the pen to that point.)
    4. Define several functions, including f1(x) = cos(x), f2(x) = tan(x), f3(x) = sin(6 * x) * exp(- x), f4(x) = sin(8 * x) - sin(9 * x). Make a plot of each of these functions; choose values for the other parameters that make good plots.
    In order for the plot to be easily readable by humans, the axes of the plot should be labeled. The cross-marks on an axis should be located on easily understood "round" values of numbers in math world. For example, if xmin = - pi and xmax = pi, it would be appropriate to have marks at -3, -2, -1, 0, 1, 2, 3.
    1. Write a function (ordermag v) to find the ``order of magnitude'' of a positive nonzero number v. The order of magnitude n is the power of ten such that 10n <= v < 10(n+1). For example, a number between 1 and 10 would have order of magnitude 0, a number between 10 and 100 would have order of magnitude 1, and a number between 0.1 and 1 would have order of magnitude -1. You can write a recursive function, or find the order of magnitude by finding the floor (greatest whole number less than or equal) of the logarithm to the base 10 of v, log10(v), where log10(x) = log(x) / log(10).
    2. Write a function (steps vmin vmax) to determine where crossing marks should be drawn on an axis. The result of steps should be a list, (firstmark step), where firstmark is the location of the first mark to be drawn and step is the distance between marks. The number 10n, where n is the order of magnitude of the range vmax - vmin, can be used as an initial estimate of the step size.

      Truncating the range divided by the step size gives an approximate number of steps (it will initially be at least 1 and less than 10). Adjust the step size (multiply or divide by 2 or 5) to give between 4 and 8 steps.

      Locate the first cross mark by finding the floor of vmin divided by the step size found above, then multiplying by the step size. If this is less than vmin, add one step to it.

    3. Write a function (xaxis xmin xmax ymin ymax) (and a similar function yaxis) that will draw and label an x axis for the plot. The axis should be a horizontal line with a crossing mark and numeric label at regular intervals. Use the function steps to choose locations for the crossing marks. Each cross-mark should be labeled by its numeric value. A function (numstring num) is provided in the file initdr.scm that you may use to convert numeric values to strings for plotting. If 0 is between ymin and ymax, draw the x axis at the place where y = 0; otherwise, draw it at *plotymin*.
    4. Write a function (plot-with-axes f xmin xmax ymin ymax) that plots and draws axes.