Exercises in this lecture   Go to the notes, in which this exercise belongs -- Keyboard shortcut: 'u'   Alphabetic index   Course home   

Exercise solution:
Polygons, Quadrangles and Squares


My solution can be seen below. Square is implemented in a general way.

My solution contains two versions of Square. The last, SimpleSquare, has its own minimalistic representation of a Square. It worth noticing that the constructor of SimpleSquare calls a constructor in Polygon which allocates only minimal space to the general polygon. My solution starts with class Polygon and class Line.

using System;

public class Polygon {

  private Point[] corners;
  
  public Polygon(params Point[] corners){
    this.corners = new Point[corners.Length];

    // Copy corners into instance variable:
    for(int i = 0; i < corners.Length; i++)
      this.corners[i] = new Point(corners[i]);
  }

  // Used by specializations that take over the
  // representation of specialized polygons
  protected Polygon(){
    this.corners = new Point[0];         
  }

  private Line[] Edges(){
    Line[] res = new Line[corners.Length];
    int Lgt = corners.Length;
    for (int i = 0; i < Lgt - 1; i++)
       res[i] = new Line(corners[i], corners[i+1]);
    res[Lgt-1] = new Line(corners[Lgt-1], corners[0]);
    return res;
  }

  public virtual double Circumference(){
    double res = 0;
    foreach(Line ln in this.Edges())
      res += ln.Length();
    return res; 
  }

  public virtual int Rank{
    get {
      return corners.Length;}
  }

}

internal class Line{

 private Point p1, p2;
 
 public Line(Point p1, Point p2){
   this.p1 = new Point(p1);
   this.p2 = new Point(p2);
 }

 public double Length(){
   return Math.Sqrt(
            Square(p1.X - p2.X) + 
            Square(p1.Y - p2.Y));
 }

 private static double Square(double a){
   return a * a;
 }
}    



public class Quadrangle: Polygon {
 
  // Used by specializations that take over the
  // representation of specialized polygons
  protected Quadrangle():base(){
  }

  public Quadrangle(Point p1, Point p2, Point p3, Point p4):
    base(p1, p2, p3, p4){
  }

}

public class Square: Quadrangle {

  // Construct a square with the two opposing corners (points on the diagonal).
  public Square(Point p1, Point p2):
    base(p1, p1.RotateAroundPoint(p1.MidPoint(p2), Math.PI/2),
         p2, p2.RotateAroundPoint(p1.MidPoint(p2), Math.PI/2)){
  }
}

public class SimpleSquare: Quadrangle {

  // A simple and specific square representation
  Point p1, p2;

  public SimpleSquare(Point p1, Point p2): 
    base(){
    this.p1 = new Point(p1);
    this.p2 = new Point(p2);
  }

  public override int Rank{
    get {
      return 4;}
  }
    
  public override double Circumference(){
   double diagLength =
       Math.Sqrt( 
        (p1.X - p2.X) * (p1.X - p2.X) +
        (p1.Y - p2.Y) * (p1.Y - p2.Y));

      return (diagLength / Math.Sqrt(2)) * 4;
  }

}



public class App {

  public static void Main(){
    Polygon pol = new Polygon(Point.MakeRectangularPoint(0,0), Point.MakeRectangularPoint(5,0),
                              Point.MakeRectangularPoint(5,5), Point.MakeRectangularPoint(0,5));

    Quadrangle quad = new Quadrangle(Point.MakeRectangularPoint(0,0), Point.MakeRectangularPoint(5,0),
                              Point.MakeRectangularPoint(5,5), Point.MakeRectangularPoint(0,5));

    Square sq = new Square(Point.MakeRectangularPoint(0,0), Point.MakeRectangularPoint(1,0));
    SimpleSquare sr = new SimpleSquare(Point.MakeRectangularPoint(0,0), Point.MakeRectangularPoint(1,0));

    Console.WriteLine("{0}", pol.Circumference());
    Console.WriteLine("{0}", quad.Circumference());
    Console.WriteLine("Circumference: {0}. Rank: {1}", sq.Circumference(), sq.Rank);
    Console.WriteLine("Circumference: {0}. Rank: {1}", sr.Circumference(), sr.Rank);
  }
}