public bool GetNewRectRightBottom(Balloon generatedBalloon, ref RectangleNormal outRect) { RectangleNormal resRect = new RectangleNormal(); RectangleNormal containRect = new RectangleNormal(); //RectangleNormal firstFound = null; //IEnumerator<RectangleNormal> tempEnum = null; //RectangleNormal tempRect; ////RectangleNormal intersectFound = null; //RectangleNormal maxXRect = null; //RectangleNormal minXRect = null; //RectangleNormal minYRect = null; //bool tmpB = false; // make rect to be at 0,0 position. 0,0 is top, left coordinate in this situation if(outRect == null) { return false; } resRect.left = 0; resRect.top = 0; resRect.right = generatedBalloon.WidthInPixels; resRect.bottom = generatedBalloon.HeightInPixels; containRect.left = 0; containRect.top = 0; containRect.right = this.WidthInPixels; containRect.bottom = this.HeightInPixels; //System.IO.TextWriter writer; // make grid from rectMatrix GeneratorGridCell[,] grid; int rowCount = 0; int colCount = 0; List<float> horizLines = new List<float>(); List<float> vertLines = new List<float>(); vertLines.Add(0.0f); vertLines.Add(containRect.right); horizLines.Add(0.0f); horizLines.Add(containRect.bottom); // Make rect lines foreach(RectangleNormal rect in this.rectMatrix) { // add to horiz lines if (!horizLines.Contains(rect.top)) { horizLines.Add(rect.top); } if (!horizLines.Contains(rect.bottom)) { horizLines.Add(rect.bottom); } // add vertical lines if (!vertLines.Contains(rect.left)) { vertLines.Add(rect.left); } if (!vertLines.Contains(rect.right)) { vertLines.Add(rect.right); } } colCount = vertLines.Count - 1; rowCount = horizLines.Count - 1; vertLines.Sort(); horizLines.Sort(); if (rowCount <= 0 || colCount <= 0) { resRect.MoveTo(0, 0); outRect.left = resRect.left; outRect.right = resRect.right; outRect.bottom = resRect.bottom; outRect.top = resRect.top; return true; } grid = new GeneratorGridCell[rowCount, colCount]; // fill grid foreach (RectangleNormal rect in this.rectMatrix) { int xind1 = vertLines.IndexOf(rect.left); int xind2 = vertLines.IndexOf(rect.right); int yind1 = horizLines.IndexOf(rect.top); int yind2 = horizLines.IndexOf(rect.bottom); for(int i = xind1; i < xind2; i++) { for(int j = yind1; j < yind2; j++) { grid[j, i].allocated = true; } } } // make coordinates for (int i = 0; i < rowCount; i++) { for (int j = 0; j < colCount; j++) { grid[i, j].sx = vertLines[j]; grid[i, j].sy = horizLines[i]; } } // if all rects all allocated then outRect should be set to bottom line bool allAlocated = true; for (int i = 0; i < rowCount; i++) { for (int j = 0; j < colCount; j++) { if (!grid[i, j].allocated) { allAlocated = false; break; } } } if (allAlocated) { // move this to bottom line in case all blocks are allocated resRect.left = 0; resRect.top = containRect.bottom; resRect.right = generatedBalloon.WidthInPixels; resRect.bottom = generatedBalloon.HeightInPixels; } else { // find first empty place for new rect for (int i = 0; i < rowCount; i++) { for (int j = 0; j < colCount; j++) { if (!grid[i, j].allocated) { // check if rect can be fitted here resRect.MoveTo(grid[i, j].sx, grid[i, j].sy); // check for any intersection with any rect bool anyIntersection = false; foreach (RectangleNormal tmpRect in this.rectMatrix) { if (tmpRect.Intersect(resRect)) { anyIntersection = true; break; } } if (!anyIntersection && containRect.Contains(resRect)) { outRect.left = resRect.left; outRect.right = resRect.right; outRect.bottom = resRect.bottom; outRect.top = resRect.top; return true; } } } } } if (Math.Abs(resRect.bottom - containRect.bottom) < Epsilon || resRect.bottom < containRect.bottom) { outRect.left = resRect.left; outRect.top = containRect.bottom; outRect.right = resRect.right; outRect.bottom = containRect.bottom + generatedBalloon.heightInPixels; } else { // make output as we are interested in last free position outRect.left = resRect.left; outRect.right = resRect.right; outRect.bottom = resRect.bottom; outRect.top = resRect.top; } return false; }
public bool GrowBalloon(Balloon generatedBalloon, float growDelta) { RectangleNormal rect1 = new RectangleNormal(); RectangleNormal rect2 = new RectangleNormal(); Debug.Assert(growDelta >= -Epsilon , "Grow Delta Should never be negative"); // check what generate algorithm is used and do logic from that //if (generatedBalloon->generatingAlgorithm == GENERATING_ALGORITHM_RIGHT_BOTTOM) { // this means we can grow only on bottom. growDelta contains info how much we need to grow // 1. Grow Parent if can grow if(this.Parent != null) { // check if parent needs to grow at all // rect of parent rect1.top = 0; rect1.left = 0; rect1.right = this.Parent.WidthInPixels; rect1.bottom = this.Parent.HeightInPixels; //desired rect after growth. Growth to allow generatedBalloon to fall in rect2.left = this.positionRect.left; rect2.top = this.positionRect.top; rect2.bottom = (rect2.top + this.HeightInPixels + growDelta); rect2.right = (rect2.left + this.WidthInPixels); if(rect1.Contains(rect2)) { // check if we intersect some rectangle in rectMatrix and in case we do return false foreach(RectangleNormal rect in this.Parent.rectMatrix) { // if rect.top != rect2.top && rect.left != rect2.left - or if this is not the same rect which already has taken place // and if it does insterest something return false if (!(System.Math.Abs(rect.top - rect2.top) < Epsilon && System.Math.Abs(rect.left - rect2.left) < Epsilon) && rect.Intersect(rect2)) { return false; } } // we don't need to grow parent just increase size of self this.HeightInPixels += growDelta; this.containerRect.bottom += growDelta; } else { // can parent grow at all if(this.CanGrow) { // grow parent if(this.Parent is Balloon) { Balloon parentBallon = (Balloon)this.Parent; if(parentBallon.CanGrow && parentBallon.GrowBalloon(generatedBalloon, growDelta)) { this.HeightInPixels += growDelta; this.containerRect.bottom += growDelta; } else { return false; } } else { return false; } } else { // cannot increase size return FALSE return false; } } } else { // no parent ... grow in height by required size. this.HeightInPixels += growDelta; this.containerRect.bottom += growDelta; } this.positionRect.bottom = rect2.bottom; } //if (generatedBalloon->generatingAlgorithm == GENERATING_ALGORITHM_BOTTOM_RIGHT) //{ // // this means we can grow only on left // // TODO: Not implemented yet //} return true; }