public Rectangle PutNextRectangle(Size rectangleSize) { if (isFirstRectangle) { isFirstRectangle = false; InitializeFirstRectangle(rectangleSize); var firstRect = new Rectangle(new Point(CloudCenter.X - (int)Math.Floor(rectangleSize.Width / (double)2), CloudCenter.Y - (int)Math.Floor(rectangleSize.Height / (double)2)), rectangleSize); return(firstRect); } var searchResult = new PositionSearchResult(double.MaxValue, null, new Point()); foreach (var segment in BorderSegments.Except(ProbablyBuggedSegments)) { if (segment.Horizontal()) { var leftBorderX = FindBorder(segment, rectangleSize, Segment.Type.Left); var rightBorderX = FindBorder(segment, rectangleSize, Segment.Type.Right); var extendedSegment = new Segment(leftBorderX, segment.Start.Y, rightBorderX, segment.End.Y, segment.SegmentType); searchResult = SearchMinDistance(searchResult, segment, rectangleSize, extendedSegment); } else { var topBorderY = FindBorder(segment, rectangleSize, Segment.Type.Top); var bottomBorderY = FindBorder(segment, rectangleSize, Segment.Type.Bottom); var extendedSegment = new Segment(segment.Start.X, topBorderY, segment.End.X, bottomBorderY, segment.SegmentType); searchResult = SearchMinDistance(searchResult, segment, rectangleSize, extendedSegment); } } var outRectangle = new Rectangle(searchResult.ClosestRectCoordinates, rectangleSize); SegmentStacker.StackSegments(Segment.GetSegmentsFromRectangle(outRectangle), BorderSegments); AddedRectangles.Add(outRectangle); return(outRectangle); }
private PositionSearchResult CheckDistance(PositionSearchResult currentSearchRes, Segment segment, Point rectangleCoord, Size rectangleSize) { var rectangle = new Rectangle(rectangleCoord, rectangleSize); var dist = rectangle.GetRectangleCenter().Distance(CloudCenter); if (dist < currentSearchRes.MinDistance) { return(currentSearchRes.Update(dist, segment, rectangleCoord)); } return(currentSearchRes); }
private PositionSearchResult SearchMinDistance(PositionSearchResult searchResult, Segment segment, Size rectangleSize, Segment extendedSegment) { if (segment.Horizontal()) { if (extendedSegment.Length < rectangleSize.Width) { return(searchResult); } if (extendedSegment.Start.X < CloudCenter.X && extendedSegment.End.X > CloudCenter.X && CloudCenter.X + (int)Math.Truncate(rectangleSize.Width / (double)2) + 1 <= extendedSegment.End.X && CloudCenter.X - (int)Math.Truncate(rectangleSize.Width / (double)2) - 1 >= extendedSegment.Start.X) { Point midRectCoordinates; if (segment.SegmentType == Segment.Type.Top) { midRectCoordinates = new Point(CloudCenter.X - (int)Math.Truncate(rectangleSize.Width / (double)2), extendedSegment.Start.Y - rectangleSize.Height); } else { midRectCoordinates = new Point(CloudCenter.X - (int)Math.Truncate(rectangleSize.Width / (double)2), extendedSegment.Start.Y); } if (CheckOppositeBorder(midRectCoordinates, rectangleSize, segment.SegmentType)) { searchResult = CheckDistance(searchResult, segment, midRectCoordinates, rectangleSize); } } Point leftMostRectCoordinates; Point rightMostRectCoordinates; if (segment.SegmentType == Segment.Type.Top) { leftMostRectCoordinates = new Point(extendedSegment.Start.X, extendedSegment.Start.Y - rectangleSize.Height); rightMostRectCoordinates = new Point(extendedSegment.End.X - rectangleSize.Width, extendedSegment.Start.Y - rectangleSize.Height); } else { leftMostRectCoordinates = new Point(extendedSegment.Start.X, extendedSegment.Start.Y); rightMostRectCoordinates = new Point(extendedSegment.End.X - rectangleSize.Width, extendedSegment.Start.Y); } if (CheckOppositeBorder(leftMostRectCoordinates, rectangleSize, segment.SegmentType)) { searchResult = CheckDistance(searchResult, segment, leftMostRectCoordinates, rectangleSize); } if (CheckOppositeBorder(rightMostRectCoordinates, rectangleSize, segment.SegmentType)) { searchResult = CheckDistance(searchResult, segment, rightMostRectCoordinates, rectangleSize); } } else { if (extendedSegment.Length < rectangleSize.Height) { return(searchResult); } if (extendedSegment.Start.Y < CloudCenter.Y && extendedSegment.End.Y > CloudCenter.Y && CloudCenter.Y + (int)Math.Truncate(rectangleSize.Height / (double)2) + 1 <= extendedSegment.End.Y && CloudCenter.Y - (int)Math.Truncate(rectangleSize.Height / (double)2) - 1 >= extendedSegment.Start.Y) { Point midRectCoordinates; if (segment.SegmentType == Segment.Type.Left) { midRectCoordinates = new Point(extendedSegment.Start.X - rectangleSize.Width, CloudCenter.Y - (int)Math.Truncate(rectangleSize.Height / (double)2)); } else { midRectCoordinates = new Point(extendedSegment.Start.X, CloudCenter.Y - (int)Math.Truncate(rectangleSize.Height / (double)2)); } if (CheckOppositeBorder(midRectCoordinates, rectangleSize, segment.SegmentType)) { searchResult = CheckDistance(searchResult, segment, midRectCoordinates, rectangleSize); } } Point topMostRectCoordinates; Point botMostRectcoordinates; if (segment.SegmentType == Segment.Type.Left) { topMostRectCoordinates = new Point(extendedSegment.Start.X - rectangleSize.Width, extendedSegment.Start.Y); botMostRectcoordinates = new Point(extendedSegment.End.X - rectangleSize.Width, extendedSegment.End.Y - rectangleSize.Height); } else { topMostRectCoordinates = new Point(extendedSegment.Start.X, extendedSegment.Start.Y); botMostRectcoordinates = new Point(extendedSegment.End.X, extendedSegment.End.Y - rectangleSize.Height); } if (CheckOppositeBorder(topMostRectCoordinates, rectangleSize, segment.SegmentType)) { searchResult = CheckDistance(searchResult, segment, topMostRectCoordinates, rectangleSize); } if (CheckOppositeBorder(botMostRectcoordinates, rectangleSize, segment.SegmentType)) { searchResult = CheckDistance(searchResult, segment, botMostRectcoordinates, rectangleSize); } } return(searchResult); }