public void GrahamScanAlgorithmComputeConvexHullTest() { // convex polygon Coordinate[] shell = new[] { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(10, 10), new Coordinate(0, 10), new Coordinate(0, 0) }; IReadOnlyList <Coordinate> convexHull = GrahamScanAlgorithm.ComputeConvexHull(shell); convexHull.ShouldBe(shell); // concave polygon shell = new[] { new Coordinate(0, 0), new Coordinate(2, 1), new Coordinate(8, 1), new Coordinate(10, 0), new Coordinate(9, 2), new Coordinate(9, 8), new Coordinate(10, 10), new Coordinate(8, 9), new Coordinate(2, 9), new Coordinate(0, 10), new Coordinate(1, 8), new Coordinate(1, 2), new Coordinate(0, 0) }; Coordinate[] expected = new[] { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(10, 10), new Coordinate(0, 10), new Coordinate(0, 0) }; convexHull = GrahamScanAlgorithm.ComputeConvexHull(shell); convexHull.ShouldBe(expected); }
public void GrahamScanAlgorithmComputeConvexHullTest() { // test case 1: convex polygon List <Coordinate> shell = new List <Coordinate> { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(10, 10), new Coordinate(0, 10), new Coordinate(0, 0) }; IList <Coordinate> convexHull = GrahamScanAlgorithm.ComputeConvexHull(shell); Assert.AreEqual(shell.Count, convexHull.Count); for (Int32 i = 0; i < shell.Count; i++) { Assert.AreEqual(shell[i], convexHull[i]); } // test case 2: concave polygon shell = new List <Coordinate> { new Coordinate(0, 0), new Coordinate(2, 1), new Coordinate(8, 1), new Coordinate(10, 0), new Coordinate(9, 2), new Coordinate(9, 8), new Coordinate(10, 10), new Coordinate(8, 9), new Coordinate(2, 9), new Coordinate(0, 10), new Coordinate(1, 8), new Coordinate(1, 2), new Coordinate(0, 0) }; List <Coordinate> expected = new List <Coordinate> { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(10, 10), new Coordinate(0, 10), new Coordinate(0, 0) }; convexHull = GrahamScanAlgorithm.ComputeConvexHull(shell); Assert.AreEqual(expected.Count, convexHull.Count); for (Int32 i = 0; i < expected.Count; i++) { Assert.AreEqual(expected[i], convexHull[i]); } }
/// <summary> /// Computes the convex hull of the specified <see cref="IGeometry" /> instance. /// </summary> /// <param name="geometry">The geometry.</param> /// <returns>The convex hull of the <see cref="IGeometry" /> instance.</returns> /// <exception cref="System.ArgumentNullException">The geometry is null.</exception> /// <exception cref="System.ArgumentException">The operation is not supported with the specified geometry type.</exception> public IGeometry ConvexHull(IGeometry geometry) { if (geometry == null) { throw new ArgumentNullException("geometry", "The geometry is null."); } IGeometryFactory factory = _geometryFactory ?? geometry.Factory; if (geometry is IPoint) { return(factory.CreatePoint((geometry as IPoint).Coordinate)); } if (geometry is ICurve) { return(factory.CreatePolygon(GrahamScanAlgorithm.ComputeConvexHull((geometry as ILineString).Coordinates, geometry.PrecisionModel))); } if (geometry is IPolygon) { return(factory.CreatePolygon(GrahamScanAlgorithm.ComputeConvexHull((geometry as IPolygon).Shell.Coordinates, geometry.PrecisionModel))); } throw new ArgumentException("The operation is not supported with the specified geometry type."); }
public override void Run() { var hullAlg = new GrahamScanAlgorithm(); // 30, 30 // -20, 50 // -30, -20 // 10, -60 // 30, -30 //var list = new List<Vector>(); //list.Add(new Vector { X = 30, Y = 30 }); //list.Add(new Vector { X = -20, Y = 50 }); //list.Add(new Vector { X = -30, Y = -20 }); //list.Add(new Vector { X = 10, Y = -60 }); //list.Add(new Vector { X = 30, Y = -30 }); hullAlg.SetInputPoints(InputPoints); hullAlg.Run(); //Console.WriteLine("poly: " + hullAlg.Hull); hull = new List <Vector>(); foreach (var line in hullAlg.Hull.Lines) { hull.Add(new Vector { X = line.StartPoint.X, Y = line.StartPoint.Y }); } //hull.Add(new Vector { X = hullAlg.Hull.Lines[0].StartPoint.X, Y = hullAlg.Hull.Lines[0].StartPoint.Y }); //hull.Reverse(); Result = FindSmallestBoundingBox(); var layer = History.CreateAndAddNewLayer("Final Result"); // (-20 0 ) ,(14.3396 -9.81132 ), (0 -60 ) ,(-34.3396 -50.1887 ) Result.Corners[0].X = -20; Result.Corners[0].Y = 0; Result.Corners[1].X = 14.3396; Result.Corners[1].Y = -9.81132; Result.Corners[2].X = 0; Result.Corners[2].Y = -60; Result.Corners[3].X = -34.3396; Result.Corners[3].Y = -50.1887; // 0 to 2 // 2 to for (int i = 0; i < 4; i++) { LineModel line = new LineModel { StartPoint = new Vector { X = Result.Corners[i].X, Y = Result.Corners[i].Y }, EndPoint = new Vector { X = Result.Corners[(i + 1) % 4].X, Y = Result.Corners[(i + 1) % 4].Y } }; layer.AddCommand(new AddNonIndexedLineCommand { StartX = line.StartPoint.X, StartY = line.StartPoint.Y, EndX = line.EndPoint.X, EndY = line.EndPoint.Y }); } }