/// <summary> /// Somewhat optimized rectangle puller /// Courtesy http://www.drdobbs.com/database/the-maximal-rectangle-problem/184410529 /// </summary> /// <returns></returns> public HashSet<BoundingBox> GetAllRectangles(HashSet<Location> locations, BoundingBox boundingBox) { //Console.WriteLine("Entering GetAllRectangles"); DateTime start = DateTime.Now; HashSet<BoundingBox> result = new HashSet<BoundingBox>(); while (locations.Count > 0) { bool[,] boolArray = new bool[boundingBox.LowerRight.X + 1, boundingBox.LowerRight.Y + 1]; foreach (Location location in locations) { boolArray[location.Point.X, location.Point.Y] = true; } BoundingBox best = new BoundingBox(); for (int upperLeftX = BoundingBox.UpperLeft.X; upperLeftX < boundingBox.LowerRight.X + 1; upperLeftX++) { for (int upperLeftY = BoundingBox.UpperLeft.Y; upperLeftY < boundingBox.LowerRight.Y + 1; upperLeftY++) { if (!boolArray[upperLeftX, upperLeftY]) { continue; } BoundingBox candidate = GrowOnes(new SxzPoint(upperLeftX, upperLeftY), boundingBox, boolArray); if (candidate.Area() > best.Area()) { best = candidate; } } } if (best.UpperLeft.X == -1) { break; } result.Add(best); //Console.WriteLine("Have total rectangles " + result.Count); //Console.WriteLine("Have remaining locations " + locations.Count); foreach (Location location in new HashSet<Location>(locations)) { if (best.Contains(location.Point.X, location.Point.Y)) { locations.Remove(location); } } } //Console.WriteLine("Leaving GetAllRectangles with time " + (DateTime.Now - start).Milliseconds + " ms"); return result; }
public HashSet<Location> GetUnmarkedByBoundingBox(BoundingBox boundingBox) { HashSet<Location> result = new HashSet<Location>(); foreach (Location location in Unmarked) { if (boundingBox.Contains(location.Point.X, location.Point.Y)) { result.Add(location); } } return result; }
public bool IsRectangle(HashSet<Location> locations, BoundingBox boundingBox) { bool[,] boolArray = new bool[boundingBox.Width(), boundingBox.Height()]; foreach (Location location in locations) { if (boundingBox.Contains(location.Point.X, location.Point.Y)) { boolArray[location.Point.X - boundingBox.UpperLeft.X, location.Point.Y - boundingBox.UpperLeft.Y] = true; } } for (int x = 0; x < boolArray.GetLength(0); x++) { for (int y = 0; y < boolArray.GetLength(1); y++) { if (!boolArray[x, y]) { return false; } } } return true; }