Steer Separation to avoid overlapping rects

Created this Script for procedural dungeon generation, but wasn’t useful since separating rooms using this technique creates lot of issues while creating path between rooms. But hopefully this will help some one who wants to avoid overlapping rects.

 bool SteerSeparation()  
 {  
      bool noOverlap = true;  
      //_packs is a list of pack(object which contains rect object)
      // all the rects are at same position (0, 0)
      foreach (var pack in _packs)  
      {  
           foreach (var item in _packs)  
           {  
                if (pack.GetHashCode() != item.GetHashCode())  
                {  
                     while (pack.rect.Overlaps(item.rect))  
                     {  
                          Rect rect1 = pack.rect;  
                          Rect rect2 = item.rect;  
                          //create a geometric center between two rects
                          Rect geometricCenter = GetGeometricCenter(rect1, rect2);  
                          pack.rect = Steer(rect1, geometricCenter);  
                          item.rect = Steer(rect2, geometricCenter);  
                          noOverlap = false;  
                     }  
                }  
           }  
      }  
      return noOverlap;  
 }  
 Rect Steer(Rect rect, Rect geometricCenter)  
 {  
      Vector2 dir = new Vector2(rect.center.x - geometricCenter.center.x, rect.center.y - geometricCenter.center.y);  
      rect.center += dir * Time.deltaTime * 0.1f;  
      return rect;  
 }  
 private Rect GetGeometricCenter(Rect rect1, Rect rect2)  
 {  
      Rect rect = new Rect();  
      rect.x = Mathf.Min(rect1.x, rect2.x);  
      rect.y = Mathf.Min(rect1.y, rect2.y);  
      //calculate width  
      if (rect1.x < rect2.x)  
      {  
           if (rect2.x + rect2.width < rect1.x + rect1.width)  
           {  
                rect.width = rect1.width;  
           }  
           else  
           {  
                rect.width = rect1.x + rect1.width - rect2.x;  
           }  
      }  
      else if (rect1.x > rect2.x)  
      {  
           if (rect1.x + rect1.width < rect2.x + rect2.width)  
           {  
                rect.width = rect2.width;  
           }  
           else  
           {  
                rect.width = rect2.x + rect2.width - rect1.x;  
           }  
      }  
      else  
      {  
           rect.width = Mathf.Max(rect1.width, rect2.width);  
      }  
      //calculate height  
      if (rect1.y < rect2.y)  
      {  
           if (rect2.y + rect2.height < rect1.y + rect1.height)  
           {  
                rect.height = rect1.height;  
           }  
           else  
           {  
                rect.height = rect1.y + rect1.height - rect2.y;  
           }  
      }  
      else if (rect1.y > rect2.y)  
      {  
           if (rect1.y + rect1.height < rect2.y + rect2.height)  
           {  
                rect.height = rect2.height;  
           }  
           else  
           {  
                rect.height = rect2.y + rect2.height - rect1.y;  
           }  
      }  
      else  
      {  
           rect.height = Mathf.Max(rect1.height, rect2.height);  
      }  
      return rect;  
 }  

happy coding 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *