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);
}
}