Did a lot of work just unit testing left

This commit is contained in:
2019-10-25 02:30:49 -06:00
parent 8d6ba5df72
commit 6901925c69
15 changed files with 508 additions and 74 deletions

View File

@@ -11,6 +11,11 @@
<e p="Shapes" t="IncludeRecursive">
<e p="bin" t="ExcludeRecursive" />
<e p="Circle.cs" t="Include" />
<e p="CompositeShape.cs" t="Include" />
<e p="FileIO.cs" t="Include" />
<e p="GeometricShape.cs" t="Include" />
<e p="Image.cs" t="Include" />
<e p="ImageManager.cs" t="Include" />
<e p="Line.cs" t="Include" />
<e p="obj" t="ExcludeRecursive">
<e p="Debug" t="Include">
@@ -21,8 +26,10 @@
</e>
<e p="Point.cs" t="Include" />
<e p="Rectangle.cs" t="Include" />
<e p="rose-blue-flower-rose-blooms-67636.jpg" t="Include" />
<e p="Shape.cs" t="Include" />
<e p="ShapeException.cs" t="Include" />
<e p="ShapeFactory.cs" t="Include" />
<e p="Shapes.csproj" t="IncludeRecursive" />
<e p="Triangle.cs" t="Include" />
<e p="Validator.cs" t="Include" />

View File

@@ -1,15 +1,32 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.Serialization;
namespace Shapes
{
public class Circle : Shape
[DataContract]
public class Circle : GeometricShape
{
public override Point CenterPoint { get; }
internal override void ComputeCenter()
{
//Does nothing to a circle
}
[DataMember]
public override Color Fill { get; set; }
[DataMember]
public override Color Stroke { get; set; }
[DataMember]
public override Point CenterPoint { get; protected set; }
[DataMember]
public double Radius { get; private set; }
public override double Height { get; }
public override double Width { get; }
[DataMember]
public override double Height { get; internal set; }
[DataMember]
public override double Width { get; internal set; }
/**
* Constructor with x-y Location for center
@@ -21,6 +38,7 @@ namespace Shapes
*/
public Circle(double x, double y, double radius)
{
Stroke = Color.Black;
Validator.ValidatePositiveDouble(radius, "Invalid radius");
CenterPoint = new Point(x, y);
Radius = radius;
@@ -36,7 +54,7 @@ namespace Shapes
* @throws ShapeException The exception thrown if the x, y, or z are not valid
*/
public Circle(Point center, double radius) {
Stroke = Color.Black;
Validator.ValidatePositiveDouble(radius, "Invalid radius");
if (center == null)
throw new ShapeException("Invalid center point");
@@ -46,16 +64,7 @@ namespace Shapes
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)
{
CenterPoint.Move(deltaX, deltaY);
}
/**
* Scale the circle
@@ -71,6 +80,27 @@ namespace Shapes
Radius *= scaleFactor;
}
public override void Save(Stream stream)
{
var fileWriter = new FileIO();
fileWriter.SaveShape(stream, this);
}
public override void Draw(Stream stream)
{
var tmp = new Bitmap((int) Radius * 4, (int) Radius * 4);
Pen blackPen = new Pen(Color.Bisque, 3);
// Draw line to screen.
using (var graphics = Graphics.FromImage(tmp))
{
graphics.DrawEllipse(blackPen, (float) CenterPoint.X, (float) CenterPoint.Y, (float) Radius * 2,
(float) Radius * 2);
}
tmp.Save(stream, ImageFormat.Jpeg);
}
/**
* @return The area of the circle.
*/
@@ -78,5 +108,6 @@ namespace Shapes
{
return Math.PI * Math.Pow(Radius, 2);
}
}
}

87
Shapes/CompositeShape.cs Normal file
View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
namespace Shapes
{
public class CompositeShape : Shape
{
private List<Shape> thisShapesList = new List<Shape>();
public override Color Fill { get; set; }
public override Color Stroke { get; set; }
public void Add(Shape shape)
{
if(shape.CompositeShape)
throw new ShapeException($"This shape has already been added to a composite");
if(shape == this)
throw new ShapeException($"You cant add a shape to itself");
thisShapesList.Add(shape);
shape.CompositeShape = true;
}
public override double ComputeArea()
{
return thisShapesList.Sum(d => d.ComputeArea());
}
public override void Scale(double scaleFactor)
{
foreach (var shape in thisShapesList)
{
shape.Scale(scaleFactor);
}
}
public override void Save(Stream stream)
{
var fileWriter = new FileIO();
fileWriter.SaveShape(stream, this);
}
public override void Draw(Stream stream)
{
var tmp = new Bitmap(1000, 1000);
Pen blackPen = new Pen(Stroke, 3);
// Draw line to screen.
using (var graphics = Graphics.FromImage(tmp))
{
foreach (var shape in thisShapesList)
{
for (int i = 1; i < shape.Points.Count; i++)
graphics.DrawLine(blackPen, (float) shape.Points[i - 1].X, (float) shape.Points[i - 1].Y, (float) shape.Points[i].X,
(float) shape.Points[i].Y);
}
}
tmp.Save(stream, ImageFormat.Jpeg);
}
public void RemoveShape(Shape shape)
{
if(!thisShapesList.Contains(shape))
throw new ShapeException($"{shape.GetType().Name} is not part of the composite shape.");
thisShapesList.Remove(shape);
shape.CompositeShape = false;
}
public void RemoveAllShapes()
{
while (thisShapesList.Count > 0)
{
thisShapesList[0].CompositeShape = false;
thisShapesList.Remove(thisShapesList[0]);
}
}
}
}

27
Shapes/FileIO.cs Normal file
View File

@@ -0,0 +1,27 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Json;
using System.Xml.Serialization;
using static System.Runtime.Serialization.Json.JsonReaderWriterFactory;
namespace Shapes
{
public class FileIO
{
public void SaveShape(Stream stream, Shape shape)
{
DataContractJsonSerializer a = new DataContractJsonSerializer(typeof(Shape));
a.WriteObject(stream, shape);
// DataContractJsonSerializer j = new DataContractJsonSerializer(typeof(Shape));
// j.WriteObject(stream, shape);
}
public T GetShapeFromFile<T>(Stream stream)
{
var a = new DataContractJsonSerializer(typeof(T));
return (T) a.ReadObject(stream);
}
}
}

67
Shapes/GeometricShape.cs Normal file
View File

@@ -0,0 +1,67 @@
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
namespace Shapes
{
[DataContract]
[KnownType(typeof(Circle))]
[KnownType(typeof(Rectangle))]
[KnownType(typeof(Triangle))]
public abstract class GeometricShape : Shape
{
[DataMember]
public abstract double Width { get; internal set; }
[DataMember]
public abstract double Height { get; internal set; }
[DataMember]
public abstract Point CenterPoint { get; protected set; }
internal abstract void ComputeCenter();
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;
}
}
public void Move(double deltaX, double deltaY)
{
var tmpCenter = CenterPoint;
var property = GetType().GetProperties().Equals(nameof(Points));
Console.WriteLine(property.GetType());
if(property)
{
Console.WriteLine(property.GetType());
foreach (var point in Points)
{
var tmpPoint = point - tmpCenter;
Console.WriteLine($"({tmpPoint.X}, {tmpPoint.Y})");
point.X = deltaX + tmpPoint.X;
point.Y = deltaY + tmpPoint.Y;
}
}
CenterPoint = new Point(deltaX, deltaY);
}
}
}

25
Shapes/Image.cs Normal file
View File

@@ -0,0 +1,25 @@
using System.Drawing;
using System.IO;
using static Shapes.ImageManager;
namespace Shapes
{
public class Image : Rectangle
{
public Bitmap Picture { get; private set; }
public Image(Point point1, Point point2, Point point3, Point point4, Stream stream) : base(point1, point2, point3, point4)
{
Picture = GetImage(stream);
}
public Image(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, Stream stream) : base(x1, y1, x2, y2, x3, y3, x4, y4)
{
Picture = GetImage(stream);
}
public Image(Point point, Size size, Stream stream) : base(point, size)
{
Picture = GetImage(stream);
}
}
}

33
Shapes/ImageManager.cs Normal file
View File

@@ -0,0 +1,33 @@
using System.Collections;
using System.Drawing;
using System.IO;
namespace Shapes
{
public static class ImageManager
{
private static Hashtable _images;
static ImageManager()
{
_images = new Hashtable();
}
internal static Bitmap GetImage(Stream stream)
{
if (_images.ContainsKey(stream))
{
return (Bitmap) _images[stream];
}
else
{
Bitmap bitmap = new Bitmap(stream);
_images.Add(stream, bitmap);
return bitmap;
}
}
}
}

View File

@@ -1,11 +1,15 @@
using System;
using System.Drawing;
using System.Runtime.Serialization;
namespace Shapes
{
public class Line
[DataContract(Name = "Line", Namespace = "Shapes")]
public class Line
{
[DataMember]
public Point Point1 { get; private set; }
[DataMember]
public Point Point2 { get; private set; }
/**

View File

@@ -1,11 +1,16 @@
using System.Drawing;
using System.Runtime.Serialization;
namespace Shapes
{
[DataContract(Name = "Points", Namespace = "Shapes")]
public class Point
{
[DataMember]
public double X { get; internal set; }
[DataMember]
public double Y { get; internal set; }
[DataMember]
public Color Color { get; set; }
public Point(double x, double y)

View File

@@ -1,21 +1,34 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.Serialization;
namespace Shapes
{
public class Rectangle : Shape
[DataContract]
public class Rectangle : GeometricShape
{
public override List<Point> Points { get; }
[DataMember]
public override List<Point> Points { get; internal set; }
[DataMember]
public override Color Fill { get; set; }
[DataMember]
public override Color Stroke { get; set; }
[DataMember]
public List<Line> Lines { get; }
public override Point CenterPoint { get; }
public sealed override double Width { get; }
public sealed override double Height { get; }
[DataMember]
public override Point CenterPoint { get; protected set; }
[DataMember]
public sealed override double Width { get; internal set; }
[DataMember]
public sealed override double Height { get; internal set; }
public Rectangle(Point point1, Point point2, Point point3, Point point4)
{
Stroke = Color.Black;
Points = new List<Point>();
Lines = new List<Line>();
@@ -38,6 +51,7 @@ namespace Shapes
public Rectangle(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
{
Stroke = Color.Black;
Points = new List<Point>();
var point1 = new Point(x1, y1);
var point2 = new Point(x2, y2);
@@ -49,12 +63,13 @@ namespace Shapes
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);
ComputeCenter();
Validator.ValidateRectangle(Points, $"Attempted to create an invalid shape {this.GetType()}");
}
public Rectangle(Point point, Size size)
{
Stroke = Color.Black;
Points = new List<Point>();
var point1 = point;
var point2 = new Point(point.X + size.Width, point.Y);
@@ -66,7 +81,7 @@ namespace Shapes
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);
ComputeCenter();
Validator.ValidateRectangle(Points, $"Attempted to create an invalid shape {this.GetType()}");
}
@@ -77,7 +92,42 @@ namespace Shapes
public override void Scale(double scaleFactor)
{
throw new System.NotImplementedException();
foreach (var point in Points)
{
point.X *= scaleFactor;
point.Y *= scaleFactor;
}
foreach (var line in Lines)
{
line.Point1.X *= scaleFactor;
line.Point1.Y *= scaleFactor;
line.Point2.X *= scaleFactor;
line.Point2.Y *= scaleFactor;
}
}
public override void Save(Stream stream)
{
var fileWriter = new FileIO();
fileWriter.SaveShape(stream, this);
}
public override void Draw(Stream stream)
{
var tmp = new Bitmap(1000, 1000);
Pen blackPen = new Pen(Stroke, 3);
// Draw line to screen.
using (var graphics = Graphics.FromImage(tmp))
{
for (int i = 1; i < Points.Count; i++)
graphics.DrawLine(blackPen,
(float) Points[i - 1].X,
(float) Points[i - 1].Y,
(float) Points[i].X,
(float) Points[i].Y);
}
tmp.Save(stream, ImageFormat.Jpeg);
}
public double CalculateWidth()
@@ -91,6 +141,10 @@ namespace Shapes
return new Line(Points[0], Points[1]).ComputeLength();
}
internal override void ComputeCenter()
{
CenterPoint = new Point((Points[0].X + Width)/2, (Points[0].Y + Height)/2);
}

View File

@@ -1,46 +1,38 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
namespace Shapes
{
[DataContract]
[KnownType(typeof(CompositeShape))]
public abstract class Shape
{
public abstract double Width { get; }
public abstract double Height { get; }
[DataMember]
public virtual List<Point> Points { get; internal set; }
[DataMember]
public abstract Color Fill { get; set; }
[DataMember]
public abstract Color Stroke { get; set; }
[DataMember]
protected internal bool CompositeShape { get; set; }
public Shape()
{
CompositeShape = false;
}
public abstract double ComputeArea();
public abstract Point CenterPoint { get; }
public virtual List<Point> Points { get; }
public abstract void Scale(double scaleFactor);
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;
}
}
public abstract void Save(Stream stream);
public abstract void Draw(Stream stream);
}
}

14
Shapes/ShapeFactory.cs Normal file
View File

@@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations;
using System.IO;
namespace Shapes
{
public class ShapeFactory
{
public T GetShapeFromFile<T>(FileStream fileStream)
{
FileIO fi = new FileIO();
return fi.GetShapeFromFile<T>(fileStream);
}
}
}

View File

@@ -4,4 +4,8 @@
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="4.7.0-preview1.19504.10" />
</ItemGroup>
</Project>

View File

@@ -2,23 +2,35 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
namespace Shapes
{
public class Triangle : Shape
[DataContract(Name = "Triangle", Namespace = "Shapes")]
public class Triangle : GeometricShape
{
public sealed override List<Point> Points { get; }
public override double Height { get; }
public override double Width { get; }
public sealed override Point CenterPoint { get; }
public List<Line> Lines { get; }
[DataMember]
public sealed override List<Point> Points { get; internal set; }
[DataMember]
public override Color Fill { get; set; }
[DataMember]
public override Color Stroke { get; set; }
[DataMember]
public override double Height { get; internal set; }
[DataMember]
public override double Width { get; internal set; }
[DataMember]
public sealed override Point CenterPoint { get; protected set; }
[DataMember]
public List<Line> Lines { get; internal set; }
public Triangle(Point point1, Point point2, Point point3)
{
Stroke = Color.Black;
Points = new List<Point>();
Lines = new List<Line>();
@@ -44,6 +56,8 @@ namespace Shapes
public Triangle(double x1, double y1, double x2, double y2, double x3, double y3)
{
Stroke = Color.Black;
var point1 = new Point(x1, y1);
var point2 = new Point(x2, y2);
var point3 = new Point(x3, y3);
@@ -85,6 +99,44 @@ namespace Shapes
point.X *= scaleFactor;
point.Y *= scaleFactor;
}
foreach (var line in Lines)
{
line.Point1.X *= scaleFactor;
line.Point1.Y *= scaleFactor;
line.Point2.X *= scaleFactor;
line.Point2.Y *= scaleFactor;
}
}
public override void Save(Stream stream)
{
var fileWriter = new FileIO();
fileWriter.SaveShape(stream, this);
}
public override void Draw(Stream stream)
{
var tmp = new Bitmap(1000, 1000);
Pen blackPen = new Pen(Stroke, 3);
// Draw line to screen.
using (var graphics = Graphics.FromImage(tmp))
{
for (int i = 1; i < Points.Count; i++)
graphics.DrawLine(blackPen,
(float) Points[i - 1].X,
(float) Points[i - 1].Y,
(float) Points[i].X,
(float) Points[i].Y);
}
tmp.Save(stream, ImageFormat.Jpeg); }
internal override void ComputeCenter()
{
Point centerOfLine3 = ((Points[0] - Points[2]) / 2) + Points[0];
var centerTriangle = ((Points[0] - centerOfLine3) / 2) + Points[0];
CenterPoint = centerTriangle;
}
}
}

View File

@@ -1,6 +1,9 @@
using System;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using Shapes;
using Image = Shapes.Image;
using Point = Shapes.Point;
using Rectangle = Shapes.Rectangle;
@@ -11,26 +14,55 @@ namespace Temp
static void Main(string[] args)
{
var circle = new Circle(new Point(20, 20), 4);
Console.WriteLine("Hello World!");
Console.WriteLine($"({circle.CenterPoint.X}, {circle.CenterPoint.Y})");
circle.Move(5,5);
Console.WriteLine($"({circle.CenterPoint.X}, {circle.CenterPoint.Y})");
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(7,3), new Point(7,6), new Point(3,6));
var rectangle = new Rectangle(new Point(3,3), new Point(5,3), new Point(5,5), new Point(3,5));
//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(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(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(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.Move(15,10);
// Console.WriteLine($"({rectangle.Points[50].X}, {rectangle.Points[50].Y}), ({rectangle.Points[100].X}, {rectangle.Points[50].Y}), ({rectangle.Points[100].X}, {rectangle.Points[100].Y}), ({rectangle.Points[50].X}, {rectangle.Points[100].Y}) Height:{rectangle.CalculateHeight()} Width:{rectangle.CalculateWidth()} Center: {rectangle.CenterPoint.X}, {rectangle.CenterPoint.Y}");
var triangle = new Triangle(new Point(3,3), new Point(7,3), new Point(7,6));
Console.WriteLine($"({triangle.Points[0].X}, {triangle.Points[0].Y}) ({triangle.Points[1].X}, {triangle.Points[1].Y}) ({triangle.Points[2].X}, {triangle.Points[2].Y}) Center: ({triangle.CenterPoint.X}, {triangle.CenterPoint.Y}) Area = {triangle.ComputeArea()} Height: {triangle.Height}");
Console.WriteLine($"\n \n ({triangle.Points[0].X}, {triangle.Points[0].Y}) ({triangle.Points[1].X}, {triangle.Points[1].Y}) ({triangle.Points[2].X}, {triangle.Points[2].Y}) Center: ({triangle.CenterPoint.X}, {triangle.CenterPoint.Y}) Area = {triangle.ComputeArea()} Height: {triangle.Height}");
triangle.Rotate(30);
Console.WriteLine($"({triangle.Points[0].X}, {triangle.Points[0].Y}) ({triangle.Points[1].X}, {triangle.Points[1].Y}) ({triangle.Points[2].X}, {triangle.Points[2].Y}) Center: ({triangle.CenterPoint.X}, {triangle.CenterPoint.Y}) Area = {triangle.ComputeArea()} Height: {triangle.Height}");
var composite = new CompositeShape();
composite.Add(new Rectangle(new Point(500, 500), new Size(100, 100) ));
// composite.Add(triangle);
var composite2 = new CompositeShape();
composite2.Add(composite);
FileStream save = new FileStream(@"/Users/bradybodily/Documents/testing/testing.jpg", FileMode.Create);
composite.Draw(save);
composite2.RemoveShape(composite);
composite.RemoveAllShapes();
FileStream wf = new FileStream(@"/Users/bradybodily/Documents/testing/test.txt", FileMode.Create);
triangle.Save(wf);
FileStream fs = new FileStream(@"/Users/bradybodily/Documents/testing/test.txt", FileMode.Open);
var triangle2 = new ShapeFactory().GetShapeFromFile<Triangle>(fs);
Console.WriteLine($"({triangle2.Points[0].X}, {triangle2.Points[0].Y}) ({triangle2.Points[1].X}, {triangle2.Points[1].Y}) ({triangle2.Points[2].X}, {triangle2.Points[2].Y}) Center: ({triangle2.CenterPoint.X}, {triangle2.CenterPoint.Y}) Area = {triangle2.ComputeArea()} Height: {triangle2.Height}");
FileStream imf = new FileStream(@"/Users/bradybodily/Documents/testing/visual-reverse-image-search-v2_intro.jpg", FileMode.Create);
Image i = new Image(new Point(20,20), new Size(20, 20), imf );
}
}
}