Graphing expressions

Assignment Overview

In this assignment, you will create a program for graphing simple functions. You will make heavy use of interfaces, both your own interfaces and ones provided by the Go standard library. There are two main components:

  1. An Expr (or expression) type, which represents a mathematical function of one variable, for example, x + 2, or 3 * x * (x + 7). An expression can Eval itself on a particular value of x, returning a number, and it can String itself (producing a string like “x + 2”).

  2. A Graph struct that implements the image.Image interface. A Graph holds an Expr and some settings, like how big the graph should be and how its axes are arranged.

Instructions

1The expression interface

Declare an interface for expressions, Expr. An expression should be able to String() string itself, and Eval(x float64) float64 its value at a certain float64 value of x.

2The concrete expression types

Implement each of the following expression types as you please:

3The Graph type

Write a struct type, Graph, that stores an expression, and some settings: a height and width in pixels, as well as a MinX, MaxX, MinY, and MaxY for the “axes” of the graph. Implement the three methods required for the Image interface:

  1. ColorModel() color.Model–you can just return color.GrayModel.

  2. Bounds() Rectangel–use image.Rect(0, 0, w, h) to return the width and height of your image in pixels.

  3. At(x, y int) color.Color–the hard one. Given an (x, y) coordinate, decide what color to paint that pixel of the image. To do this, you need to first figure out what “real value” x corresponds to. If x is the 5th pixel in a 100-pixel image, and the axis goes from MinX = 0 to MaxX = 20, then x = 5 really corresponds to x = 1, 1/20th of the way across the axis. Once you have this, you need to evaluate your Expr at this point. This will give you a y value. Calculate what pixel that y value would land on, based on the y axis’s scale. If that pixel number is the y value passed in to you, return black (color.Gray{0}). Otherwise, return white (color.Gray{255}).

4Main function

In your main function, create a few expressions, and save them to files using code like the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
func main() {
  var e1 Expr = ...
  var e2 Expr = ...

  var graph1 = Graph{e1, 100, 100, ..., ..., ..., ...}
  var graph2 = Graph{e2, 100, 100, ..., ..., ..., ...}

  f1, err := os.Create("graph1.png")
  if err != nil {
    panic("Error opening graph1.png")
  }
  png.Encode(f1, graph1)
  f1.Close()

  f2, err := os.Create("graph2.png")
  if err != nil {
    panic("Error opening graph2.png")
  }
  png.Encode(f2, graph2)
  f2.Close()
}