OOP: Classes for Geometric Shapes

In these notes you will learn:

  • How to write classes for a circle, line segment, and triangle.

A Circle Class

In the previous notes we created a class called Point that represents 2D positions:

class Point {
  float x;
  float y;

  Point(float x_init, float y_init) {
    x = x_init;
    y = y_init;
  }

  void display() {
    println("(" + x + ", " + y + ")");
  }
}

Lets use this to create some other classes. First, lets create a Circle class that represents a circle:

class Circle {
  Point center;
  float radius;

  // constructor
  Circle(float x, float y, float r) {
    center = new Point(x, y);
    radius = r;
  }
}

A Circle is an object with a center Point and a radius. It has a constructor that requires all the information needed to create the circle. We can use it like this:

Circle pan = new Circle(15, 20, 50.4);
println(pan.center.x + ", " + pan.center.y + ", " + pan.radius);

Again, we use dot-notation to access things inside the object. The expression pan.center.x is interesting: it refers to the value of x inside the center object inside the pan object.

As with Point, it is convenient to create a display() function for Circle that prints the contents of its variables in a readable way:

class Circle {
  Point center;
  float radius;

  Circle(float x, float y, float r) {
    center = new Point(x, y);
    radius = r;
  }

  void display() {
    println("Circle((" + center.x + ", " + center.y
            + "), " + radius + ")");
  }
}

Another useful function to add to Circle is area(), which calculates the area of the circle:

class Circle {
  Point center;
  float radius;

  Circle(float x, float y, float r) {
    center = new Point(x, y);
    radius = r;
  }

  void display() {
    println("Circle((" + center.x + ", " + center.y
            + "), " + radius + ")");
  }

  float area() {
    return 3.14 * radius * radius;
  }
}

For example:

Circle c = new Circle(0, 0, 5);
println(c.area()); // 78.5

Finally, lets add a rendering function to draw the circle:

class Circle {
  Point center;
  float radius;

  Circle(float x, float y, float r) {
    center = new Point(x, y);
    radius = r;
  }

  void display() {
    println("Circle((" + center.x + ", " + center.y
      + "), " + radius + ")");
  }

  float area() {
    return 3.14 * radius * radius;
  }

  void render() {
    center.render();  // draw point at center
    noFill();
    stroke(0);
    ellipse(center.x, center.y, 2*radius, 2*radius);
  }
}

Here’s a simple example program that draws a circle centered at the mouse pointer:

Circle pointer;

void setup() {
  size(500, 500);
  smooth();
  noCursor(); // turn off regular pointer
  pointer = new Circle(-100, -100, 80);  // start off screen
}

void draw() {
  background(255);
  pointer.render();
  pointer.center.x = mouseX;
  pointer.center.y = mouseY;
}

A Line Segment

Lets move on from circles and make a class called Segment that lets us make objects representing line segments:

class Segment {
  Point begin;
  Point end;

  Segment(float begin_x, float begin_y, float end_x, float end_y) {
    begin = new Point(begin_x, begin_y);
    end = new Point(end_x, end_y);
  }

  float length() {
    return dist(begin.x, begin.y, end.x, end.y);
  }

  void display() {
    println("Segment(begin=(" + begin.x + ", " + begin.y
            + "), end=(" + end.x + ", " + end.y + "))");
  }
}

A Segment object consists of a begin point and end point. The length() function returns the distance between begin and end, and display() prints the segment to the console.

You can use it like this:

Segment line = new Segment(0, 0, 51, 3);
println(line.length());  // 51.088158
line.display(); // Segment(begin=(0.0, 0.0), end=(51.0, 3.0))

As with we’ve done for the other classes, lets add a render function to draw a segment:

class Segment {
  Point begin;
  Point end;

  Segment(float begin_x, float begin_y, float end_x, float end_y) {
    begin = new Point(begin_x, begin_y);
    end = new Point(end_x, end_y);
  }

  float length() {
    return dist(begin.x, begin.y, end.x, end.y);
  }

  void display() {
    println("Segment(begin=(" + begin.x + ", " + begin.y
      + "), end=(" + end.x + ", " + end.y + "))");
  }

  void render() {
    stroke(0);
    line(begin.x, begin.y, end.x, end.y);
    noStroke();
    begin.render();
    end.render();
  }
}

This sample program draws a segment from the mouse location to the center of the screen:

Segment seg;

void setup() {
  size(500, 500);
  smooth();
  noCursor(); // turn off regular pointer
  seg = new Segment(-100, -100, 250, 250);
}

void draw() {
  background(255);
  seg.render();
  seg.begin.x = mouseX;
  seg.begin.y = mouseY;
}

A Triangle

A natural way to represent a triangle is as its three corner points:

class Triangle {
  Point a;
  Point b;
  Point c;

  Triangle(float ax, float ay, float bx, float by,
           float cx, float cy)
  {
    a = new Point(ax, ay);
    b = new Point(bx, by);
    c = new Point(cx, cy);
  }

  void display() {
    println("Triangle((" + a.x + ", " + a.y + "), ("
           + b.x + ", " + b.y + "), (" + c.x + ", " + c.y + "))");
  }

  void render() {
    stroke(0);
    line(a.x, a.y, b.x, b.y);
    line(a.x, a.y, c.x, c.y);
    line(b.x, b.y, c.x, c.y);
    noStroke();
    a.render();
    b.render();
    c.render();
  }

  // Heron's formula for the area of a triangle
  float area() {
    float ab = dist(a.x, a.y, b.x, b.y);
    float ac = dist(a.x, a.y, c.x, c.y);
    float bc = dist(b.x, b.y, c.x, c.y);
    float s = (ab + ac + bc) / 2;  // semi-perimeter
    return sqrt(s * (s - ab) * (s - ac) * (s - bc));
  }

}

Notice the area() function uses Heron’s formula to calculate the triangle’s area. This is a convenient way to calculate the area because all it requires is the length of the triangle’s sides.

Here’s a sample program that shows how you can use a Triangle:

Triangle t;

void setup() {
  size(500, 500);

  t = new Triangle(0, 0, 100, 100, 200, 150);
}

void draw() {
  background(255);
  t.render();
  println(t.area());
  t.a.x = mouseX;
  t.a.y = mouseY;
}

Questions

  1. Modify the display() function in the Circle class so that it prints the circle in the format below:

    Circle c = new Circle(3, 2, 5);
    c.display();
    // prints: Circle(center=(3, 2), radius=5)
    
  2. Add a function called circumference() to the Circle class the calculates and returns the circumference of the circle. The circumference of a circle of radius \(r\) is \(2\pi r\).

  3. Add a function called getDiameter() to the Circle class that calculates and returns the diameter of the circle.

  4. Write and test a class called Square that creates objects that represent squares. Store the squares as their upper-left corner and side length. Include a display function, a render function, and an area function.