diff --git a/.idea/.idea.Shapes/.idea/contentModel.xml b/.idea/.idea.Shapes/.idea/contentModel.xml
index b826856..c48181e 100644
--- a/.idea/.idea.Shapes/.idea/contentModel.xml
+++ b/.idea/.idea.Shapes/.idea/contentModel.xml
@@ -1,13 +1,17 @@
+
+
+
-
+
+
@@ -15,9 +19,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.Shapes/riderModule.iml b/.idea/.idea.Shapes/riderModule.iml
index 1a4e0d9..a703f0e 100644
--- a/.idea/.idea.Shapes/riderModule.iml
+++ b/.idea/.idea.Shapes/riderModule.iml
@@ -1,6 +1,9 @@
+
+
+
diff --git a/Shapes.sln b/Shapes.sln
index 5352aa8..8b4d161 100644
--- a/Shapes.sln
+++ b/Shapes.sln
@@ -2,6 +2,10 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shapes", "Shapes\Shapes.csproj", "{3DEEB67E-89F4-403E-8210-EEBD5A01C64D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Temp", "Temp\Temp.csproj", "{781AE2D9-ADBF-4AA4-9D9D-78AFBF04A6F5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{E7BB8603-7B34-4C9E-9C1F-916527FD68A5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -12,5 +16,13 @@ Global
{3DEEB67E-89F4-403E-8210-EEBD5A01C64D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3DEEB67E-89F4-403E-8210-EEBD5A01C64D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3DEEB67E-89F4-403E-8210-EEBD5A01C64D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {781AE2D9-ADBF-4AA4-9D9D-78AFBF04A6F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {781AE2D9-ADBF-4AA4-9D9D-78AFBF04A6F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {781AE2D9-ADBF-4AA4-9D9D-78AFBF04A6F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {781AE2D9-ADBF-4AA4-9D9D-78AFBF04A6F5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E7BB8603-7B34-4C9E-9C1F-916527FD68A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E7BB8603-7B34-4C9E-9C1F-916527FD68A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E7BB8603-7B34-4C9E-9C1F-916527FD68A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E7BB8603-7B34-4C9E-9C1F-916527FD68A5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/Shapes/Circle.cs b/Shapes/Circle.cs
new file mode 100644
index 0000000..ffa6c0d
--- /dev/null
+++ b/Shapes/Circle.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Drawing;
+
+namespace Shapes
+{
+ public class Circle : Shape
+ {
+ public Point Center { get; private set; }
+ public double Radius { get; private set; }
+
+ public override Color Fill { get; set; }
+ public override Color Color { get; set; }
+ public override double Height { get; }
+ public override double Width { get; }
+
+ /**
+ * Constructor with x-y Location for center
+ *
+ * @param x The x-location of the center of the circle -- must be a valid double
+ * @param y The y-location of the center of the circle
+ * @param radius The radius of the circle -- must be greater or equal to zero.
+ * @throws ShapeException The exception thrown if the x, y, or z are not valid
+ */
+ public Circle(double x, double y, double radius)
+ {
+ Validator.ValidatePositiveDouble(radius, "Invalid radius");
+ Center = new Point(x, y);
+ Radius = radius;
+ Color = Color.Black;
+ Fill = Color.White;
+ Height = radius * 2;
+ Width = radius * 2;
+ }
+
+ /**
+ * Constructor with a Point for center
+ *
+ * @param center The x-location of the center of the circle -- must be a valid point
+ * @param radius The radius of the circle -- must be greater or equal to zero.
+ * @throws ShapeException The exception thrown if the x, y, or z are not valid
+ */
+ public Circle(Point center, double radius) {
+
+ Validator.ValidatePositiveDouble(radius, "Invalid radius");
+ if (center == null)
+ throw new ShapeException("Invalid center point");
+ Center = center;
+ Radius = radius;
+ Color = Color.Black;
+ Fill = Color.White;
+ Height = radius * 2;
+ Width = radius * 2;
+ }
+
+ /**
+ * Move the circle
+ * @param deltaX a delta change for the x-location of center of the circle
+ * @param deltaY a delta change for the y-location of center of the circle
+ * @throws ShapeException Exception thrown if either the delta x or y are not valid doubles
+ */
+ public void Move(double deltaX, double deltaY)
+ {
+ Center.Move(deltaX, deltaY);
+ }
+
+ /**
+ * Scale the circle
+ *
+ * @param scaleFactor a non-negative double that represents the percentage to scale the circle.
+ * 0>= and <1 to shrink.
+ * >1 to grow.
+ * @throws ShapeException Exception thrown if the scale factor is not valid
+ */
+ public override void Scale(double scaleFactor)
+ {
+ Validator.ValidatePositiveDouble(scaleFactor, "Invalid scale factor");
+ Radius *= scaleFactor;
+ }
+
+ /**
+ * @return The area of the circle.
+ */
+ public override double ComputeArea()
+ {
+ return Math.PI * Math.Pow(Radius, 2);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Shapes/Class1.cs b/Shapes/Class1.cs
deleted file mode 100644
index 1658be6..0000000
--- a/Shapes/Class1.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System;
-
-namespace Shapes
-{
- public class Class1
- {
- }
-}
\ No newline at end of file
diff --git a/Shapes/Line.cs b/Shapes/Line.cs
new file mode 100644
index 0000000..3ccd7d8
--- /dev/null
+++ b/Shapes/Line.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Drawing;
+
+namespace Shapes
+{
+ public class Line
+ {
+ public Point Point1 { get; private set; }
+ public Point Point2 { get; private set; }
+ public Color Color { get; set; }
+
+ /**
+ * Constructor based on x-y Locations
+ * @param x1 The x-location of first point -- must be a valid double.
+ * @param y1 The y-location of first point -- must be a valid double.
+ * @param x2 The x-location of second point -- must be a valid double.
+ * @param y2 The y-location of second point -- must be a valid double.
+ * @throws ShapeException Exception throw if any parameter is invalid
+ */
+ public Line(double x1, double y1, double x2, double y2)
+ {
+ Color = Color.Black;
+ Point1 = new Point(x1, y1);
+ Point2 = new Point(x2, y2);
+ }
+
+ /**
+ *
+ * @param point1 The first point -- must not be null
+ * @param point2 The second point -- must not b e null
+ * @throws ShapeException Exception throw if any parameter is invalid
+ */
+ public Line(Point point1, Point point2)
+ {
+ if (point1==null || point2==null)
+ throw new ShapeException("Invalid point");
+ Color = Color.Black;
+ Point1 = point1;
+ Point2 = point2;
+ }
+
+ /**
+ * Move a line
+ *
+ * @param deltaX The delta x-location by which the line should be moved -- must be a valid double
+ * @param deltaY The delta y-location by which the line should be moved -- must be a valid double
+ * @throws ShapeException Exception throw if any parameter is invalid
+ */
+ public void Move(double deltaX, double deltaY)
+ {
+ Point1.Move(deltaX, deltaY);
+ Point2.Move(deltaX, deltaY);
+ }
+
+ /**
+ * @return The length of the line
+ */
+ public double ComputeLength()
+ {
+ return Math.Sqrt(Math.Pow(Math.Abs(Point2.X - Point1.X), 2) +
+ Math.Pow(Math.Abs(Point2.Y - Point1.Y), 2));
+ }
+
+ /**
+ * @return The slope of the line
+ */
+ public double ComputeSlope()
+ {
+ return (Point2.Y - Point1.Y) / (Point2.X - Point1.X);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Shapes/Point.cs b/Shapes/Point.cs
new file mode 100644
index 0000000..99d2b21
--- /dev/null
+++ b/Shapes/Point.cs
@@ -0,0 +1,66 @@
+using System.Drawing;
+
+namespace Shapes
+{
+ public class Point
+ {
+ public double X { get; internal set; }
+ public double Y { get; internal set; }
+ public Color Color { get; set; }
+
+ public Point(double x, double y)
+ {
+ Validator.ValidateDouble(x, "Invalid x-location point");
+ Validator.ValidateDouble(y, "Invalid y-location point");
+ X = x;
+ Y = y;
+ Color = Color.Black;
+ }
+
+ /**
+ * Move the point in the x direction
+ *
+ * @param deltaX The delta amount to move the point -- must be a valid double
+ * @throws ShapeException Exception thrown if the parameter is invalid
+ */
+ public void MoveX(double deltaX) {
+ Validator.ValidateDouble(deltaX, "Invalid delta-x value");
+ X += deltaX;
+ }
+
+ /**
+ * Move the point in the y direction
+ *
+ * @param deltaY The delta amount to move the point -- must be a valid double
+ * @throws ShapeException Exception thrown if the parameter is invalid
+ */
+ public void MoveY(double deltaY)
+ {
+ Validator.ValidateDouble(deltaY, "Invalid delta-y value");
+ Y += deltaY;
+ }
+
+ /**
+ * Move the point
+ *
+ * @param deltaX The delta amount to move the point in the x direction -- must be a valid double
+ * @param deltaY The delta amount to move the point in the y direction -- must be a valid double
+ * @throws ShapeException Exception throw if any parameter is invalid
+ */
+ public void Move(double deltaX, double deltaY)
+ {
+ MoveX(deltaX);
+ MoveY(deltaY);
+ }
+
+ /**
+ * Copy the point
+ * @return A new point with same x and y locations
+ * @throws ShapeException Should never thrown because the current x and y are valid
+ */
+ public Point Copy()
+ {
+ return new Point(X, Y);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Shapes/Rectangle.cs b/Shapes/Rectangle.cs
new file mode 100644
index 0000000..2551f75
--- /dev/null
+++ b/Shapes/Rectangle.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+
+namespace Shapes
+{
+ public class Rectangle : Shape
+ {
+ public override Color Fill { get; set; }
+ public override Color Color { get; set; }
+ public List Points { get; }
+ public Point CenterPoint { get; }
+ public sealed override double Width { get; }
+ public sealed override double Height { get; }
+
+
+ public Rectangle(Point point1, Point point2, Point point3, Point point4)
+ {
+ Points = new List();
+ Points.Add(point1);
+ Points.Add(point2);
+ Points.Add(point3);
+ Points.Add(point4);
+ Height = new Line(point1, point4).ComputeLength();
+ Width = new Line(point1, point2).ComputeLength();
+ CenterPoint = new Point(point1.X + (Width/2), point1.Y + (Height/2));
+ Validator.ValidateRectangle(point1, point2, point3, point4, $"Attempted to create an invalid shape {this.GetType()}");
+ }
+
+ public Rectangle(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
+ {
+ Points = new List();
+ var point1 = new Point(x1, y1);
+ var point2 = new Point(x2, y2);
+ var point3 = new Point(x3, y3);
+ var point4 = new Point(x4, y4);
+ Points.Add(point1);
+ Points.Add(point2);
+ Points.Add(point3);
+ Points.Add(point4);
+ Height = new Line(point1, point2).ComputeLength();
+ Width = new Line(point1, point4).ComputeLength();
+ CenterPoint = new Point((point1.X + Width)/2, (point1.Y + Height)/2);
+ Validator.ValidateRectangle(point1, point2, point3, point4, $"Attempted to create an invalid shape {this.GetType()}");
+ }
+
+ public Rectangle(Point point, Size size)
+ {
+ Points = new List();
+ var point1 = point;
+ var point2 = new Point(point.X + size.Width, point.Y);
+ var point3 = new Point(point.X + size.Width, point.Y + size.Height);
+ var point4 = new Point(point.X, point.Y + size.Height);
+ Points.Add(point1);
+ Points.Add(point2);
+ Points.Add(point3);
+ Points.Add(point4);
+ Height = new Line(point1, point2).ComputeLength();
+ Width = new Line(point1, point4).ComputeLength();
+ CenterPoint = new Point((point1.X + Width)/2, (point1.Y + Height)/2);
+ Validator.ValidateRectangle(point1, point2, point3, point4, $"Attempted to create an invalid shape {this.GetType()}");
+ }
+
+ public override double ComputeArea()
+ {
+ return Height * Width;
+ }
+
+ public override void Scale(double scaleFactor)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public double CalculateWidth()
+ {
+ return new Line(Points[0], Points[3]).ComputeLength();
+
+ }
+
+ public double CalculateHeight()
+ {
+ return new Line(Points[0], Points[1]).ComputeLength();
+ }
+
+ public void Rotate(double degrees)
+ {
+ double radians = degrees * (Math.PI / 180);
+ double cosTheta = Math.Cos(radians);
+ double sinTheta = Math.Sin(radians);
+ foreach (var point in Points)
+ {
+ var oldPoint = point;
+
+
+ var tempX = oldPoint.X - CenterPoint.X;
+ var tempY = oldPoint.Y - CenterPoint.X;
+
+ var rotatedX = tempX*cosTheta - tempY*sinTheta;
+ var rotatedY = tempX*sinTheta + tempY*cosTheta;
+
+ point.X = rotatedX + CenterPoint.X;
+ point.Y = rotatedY + CenterPoint.Y;
+
+ }
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/Shapes/Shape.cs b/Shapes/Shape.cs
new file mode 100644
index 0000000..aa5de68
--- /dev/null
+++ b/Shapes/Shape.cs
@@ -0,0 +1,20 @@
+using System.ComponentModel;
+using System.Diagnostics.Tracing;
+using System.Drawing;
+using System.Reflection.Metadata.Ecma335;
+
+namespace Shapes
+{
+ public abstract class Shape
+ {
+ public abstract Color Fill { get; set; }
+ public abstract Color Color { get; set; }
+ public abstract double Width { get; }
+ public abstract double Height { get; }
+ public abstract double ComputeArea();
+
+ public abstract void Scale(double scaleFactor);
+
+
+ }
+}
\ No newline at end of file
diff --git a/Shapes/ShapeException.cs b/Shapes/ShapeException.cs
new file mode 100644
index 0000000..2f3459e
--- /dev/null
+++ b/Shapes/ShapeException.cs
@@ -0,0 +1,11 @@
+namespace Shapes
+{
+
+ public class ShapeException : System.Exception
+ {
+ public ShapeException(string message) : base(message)
+ {
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Shapes/Triangle.cs b/Shapes/Triangle.cs
new file mode 100644
index 0000000..db3c71e
--- /dev/null
+++ b/Shapes/Triangle.cs
@@ -0,0 +1,10 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.Drawing;
+
+namespace Shapes
+{
+ public class Triangle
+ {
+ }
+}
\ No newline at end of file
diff --git a/Shapes/Validator.cs b/Shapes/Validator.cs
new file mode 100644
index 0000000..0716060
--- /dev/null
+++ b/Shapes/Validator.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+
+namespace Shapes
+{
+ public class Validator
+ {
+
+ public static void ValidateDouble(double value, string errorMessage)
+ {
+ if (double.IsInfinity(value) || double.IsNaN(value))
+ throw new ShapeException(errorMessage);
+ }
+
+ public static void ValidatePositiveDouble(double value, String errorMessage)
+ {
+ ValidateDouble(value, errorMessage);
+ if (value < 0)
+ throw new ShapeException(errorMessage);
+ }
+
+ public static void ValidateRectangle(Point point1, Point point2, Point point3, Point point4, String errorMessage)
+ {
+ var TOLERANCE = Double.Epsilon + Double.Epsilon;
+ var plumLine1 = new Line(point1, point3);
+ var plumLine2 = new Line(point2, point4);
+ var heightLine1 = new Line(point1, point4);
+ var heightLine2 = new Line( point2, point3);
+ var lengthLine1 = new Line(point1, point2);
+ var lengthLine2 = new Line(point4, point3);
+ if (Math.Abs(plumLine1.ComputeLength() - plumLine2.ComputeLength()) > TOLERANCE
+ || Math.Abs(heightLine1.ComputeLength() - heightLine2.ComputeLength()) > TOLERANCE
+ || Math.Abs(lengthLine1.ComputeLength() - lengthLine2.ComputeLength()) > TOLERANCE )
+ {
+ throw new ShapeException(errorMessage);
+ }
+
+ }
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/Temp/Program.cs b/Temp/Program.cs
new file mode 100644
index 0000000..70cf78e
--- /dev/null
+++ b/Temp/Program.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Drawing;
+using Shapes;
+using Point = Shapes.Point;
+using Rectangle = Shapes.Rectangle;
+
+namespace Temp
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ var circle = new Circle(new Point(20, 20), 4);
+ Console.WriteLine("Hello World!");
+ var line = new Line(3, 4, 4, 5);
+ var tmp = line.ComputeLength();
+ var point = new Point(3, 3);
+ point.Color = Color.Aqua;
+ var rectangle = new Rectangle(new Point(3,3), new Point(6,3), new Point(6,6), new Point(3,6));
+ //var rectangle2 = new Rectangle(new Point(3,0), new Point(3,0), new Point(3,2), new Point(0,3));
+ Console.WriteLine($"({rectangle.Points[0].X}, {rectangle.Points[0].Y}), ({rectangle.Points[1].X}, {rectangle.Points[1].Y}), ({rectangle.Points[2].X}, {rectangle.Points[2].Y}), ({rectangle.Points[3].X}, {rectangle.Points[3].Y}) Height:{rectangle.CalculateHeight()} Width:{rectangle.CalculateWidth()} Center: {rectangle.CenterPoint.X}, {rectangle.CenterPoint.Y}");
+ rectangle.Rotate(180);
+ Console.WriteLine($"({rectangle.Points[0].X}, {rectangle.Points[0].Y}), ({rectangle.Points[1].X}, {rectangle.Points[1].Y}), ({rectangle.Points[2].X}, {rectangle.Points[2].Y}), ({rectangle.Points[3].X}, {rectangle.Points[3].Y}) Height:{rectangle.CalculateHeight()} Width:{rectangle.CalculateWidth()} Center: {rectangle.CenterPoint.X}, {rectangle.CenterPoint.Y}");
+ rectangle.Rotate(90);
+ Console.WriteLine($"({rectangle.Points[0].X}, {rectangle.Points[0].Y}), ({rectangle.Points[1].X}, {rectangle.Points[1].Y}), ({rectangle.Points[2].X}, {rectangle.Points[2].Y}), ({rectangle.Points[3].X}, {rectangle.Points[3].Y}) Height:{rectangle.CalculateHeight()} Width:{rectangle.CalculateWidth()} Center: {rectangle.CenterPoint.X}, {rectangle.CenterPoint.Y}");
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Temp/Temp.csproj b/Temp/Temp.csproj
new file mode 100644
index 0000000..1d148c8
--- /dev/null
+++ b/Temp/Temp.csproj
@@ -0,0 +1,12 @@
+
+
+
+ Exe
+ netcoreapp2.2
+
+
+
+
+
+
+
diff --git a/TestProject1/TestProject1.csproj b/TestProject1/TestProject1.csproj
new file mode 100644
index 0000000..89b9b0d
--- /dev/null
+++ b/TestProject1/TestProject1.csproj
@@ -0,0 +1,15 @@
+
+
+
+ netcoreapp2.2
+
+ false
+
+
+
+
+
+
+
+
+
diff --git a/TestProject1/UnitTest1.cs b/TestProject1/UnitTest1.cs
new file mode 100644
index 0000000..dfbb241
--- /dev/null
+++ b/TestProject1/UnitTest1.cs
@@ -0,0 +1,18 @@
+using NUnit.Framework;
+using Shapes;
+namespace Tests
+{
+ public class Tests
+ {
+ [SetUp]
+ public void Setup()
+ {
+ }
+
+ [Test]
+ public void Test1()
+ {
+ Assert.Pass();
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnitTests/UnitTest1.cs b/UnitTests/UnitTest1.cs
new file mode 100644
index 0000000..794c408
--- /dev/null
+++ b/UnitTests/UnitTest1.cs
@@ -0,0 +1,18 @@
+using NUnit.Framework;
+
+namespace Tests
+{
+ public class Tests
+ {
+ [SetUp]
+ public void Setup()
+ {
+ }
+
+ [Test]
+ public void Test1()
+ {
+ Assert.Pass();
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj
new file mode 100644
index 0000000..5005a03
--- /dev/null
+++ b/UnitTests/UnitTests.csproj
@@ -0,0 +1,19 @@
+
+
+
+ netcoreapp2.2
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+