Advertisement
Guest User

rectpack

a guest
Dec 29th, 2011
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.73 KB | None | 0 0
  1. class Node(object):
  2.     def __init__(self, width, height, x = 0, y = 0):
  3.         assert width >= 0 and height >= 0 and x >= 0 and y >= 0, 'width={0}; height={1}; x={2}; y={3}'.format(width, height, x, y)
  4.         self.left = self.right = None
  5.         self.wbound = self.width = width
  6.         self.hbound = self.height = height
  7.         self.x = x
  8.         self.y = y
  9.  
  10.     # Inserts a new rectangle in the subtree rooted at the given node.
  11.     def insert(self, width, height):
  12.         assert width > 0 and height > 0
  13.         # If this node is an internal node, try both leaves for possible space.
  14.         # (The rectangle in an internal node stores used space, the leaves store free space)
  15.         if self.left:
  16.             return self.left.insert(width, height) or self.right.insert(width, height)
  17.  
  18.         # This node is a leaf, but can we fit the new rectangle here?
  19.         if width > self.width or height > self.height:
  20.             return None # Too bad, no space.
  21.  
  22.         # The new cell will fit, split the remaining space along the shorter axis,
  23.         # that is probably more optimal.
  24.         w = self.width - width
  25.         h = self.height - height
  26.         if w <= h: # Split the remaining space in horizontal direction.
  27.             self.left  = Node(w         , height, self.x + width, self.y         )
  28.             self.right = Node(self.width, h     , self.x        , self.y + height)
  29.         else: # Split the remaining space in vertical direction.
  30.             self.left  = Node(width, h          , self.x        , self.y + height)
  31.             self.right = Node(w    , self.height, self.x + width, self.y         )
  32.  
  33.         # Note that as a result of the above, it can happen that self.left or self.right
  34.         # is now a degenerate (zero area) rectangle. No need to do anything about it,
  35.         # like remove the nodes as "unnecessary" since they need to exist as children of
  36.         # this node (this node can't be a leaf anymore).
  37.  
  38.         # This node is now a non-leaf, so shrink its area - it now denotes
  39.         # *occupied* space instead of free space. Its children spawn the resulting
  40.         # area of free space.
  41.         self.width = width
  42.         self.height = height
  43.         return self
  44.  
  45.     def __str__(self):
  46.         return 'Node({0}, {1}, {2}, {3})'.format(self.x, self.y, self.width, self.height)
  47.  
  48.     def bbox(self):
  49.         return (self.x, self.y, self.x + self.width, self.y + self.height)
  50.  
  51.     def coverage(self, depth=0):
  52.         #print '{0}{1}, {2}'.format('  '*depth, self.wbound, self.hbound)
  53.         return self.left.coverage(depth + 1) + self.right.coverage(depth + 1) if self.left else self.width*self.height
  54.  
  55.     def density(self):
  56.         return float(self.coverage())/(self.wbound*self.hbound)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement