bin packing

#ifndef packing_h
#define packing_h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define INVALID_PT_ID 0
#define WAITING_FOR_WRITE 1

struct PTRect
{
	int x,y,w,h;

	PTRect()
	{
		x = y = w = h = 0;
	}
	PTRect(int _x,int _y,int _w,int _h):w(_w),h(_h),x(_x),y(_y)
	{
	}

	const PTRect&operator =(const PTRect&rc)
	{
		x = rc.x;
		y = rc.y;
		w = rc.w;
		h = rc.h;
		return *this;
	}
};

struct PTNode
{
	PTNode* child[2];
	PTRect world;
//	PTRect master;
	int	ID;


	PTNode(PTRect rc)
	{
		memset(child,0,sizeof(PTNode*));
		ID = INVALID_PT_ID;
		world = rc;
	}

	PTNode(int x,int y,int w,int h)
	{
		memset(child,0,sizeof(PTNode*));
		world = PTRect(x,y,w,h);
		ID = INVALID_PT_ID;
	}

	// 如果没有左子点,则肯定没有右子点
	bool isLeaf(){return child[0]== 0;}
	bool isFit(PTRect &rc){return (world.w >= rc.w && world.h >= rc.h);}
	bool isFitComplete(PTRect &rc)
	{
		return (world.w-rc.w == 0 && world.h-rc.h == 0);
	}

	PTNode* insert(PTRect rc)
	{
		if(isLeaf())
		{
			// 该节点上已经有元素了
			if(ID != INVALID_PT_ID) return NULL;
			if(!isFit(rc)) return NULL;
			if(isFitComplete(rc))
			{
				ID = WAITING_FOR_WRITE;
				return this;
			}
			else
			{
				// 哪个方向剩余的量比较大
				int dw = world.w - rc.w;
				int dh = world.h - rc.h;

				if(dw >= dh)
				{
					child[0]= new PTNode(world.x,world.y,rc.w,world.h);
					child[1]= new PTNode(world.x+rc.w+1,world.y,world.w - rc.w -1,world.h);

					// insert into child[0]
					PTNode *NodeChild0 = child[0];
					NodeChild0->child[0] = new PTNode(NodeChild0->world.x,NodeChild0->world.y,rc.w,rc.h);
					NodeChild0->child[1] = new PTNode(NodeChild0->world.x,NodeChild0->world.y+ rc.h + 1,rc.w,NodeChild0->world.h - 1 - rc.h);
					NodeChild0->child[0]->ID = WAITING_FOR_WRITE;
					return NodeChild0->child[0];
				}
				else
				{
					child[0] = new PTNode(world.x,world.y,world.w,rc.h);
					child[1] = new PTNode(world.x,world.y+rc.h+1,world.w,world.h-rc.h -1);


					// insert into child[0]
					PTNode *NodeChild0 = child[0];
					NodeChild0->child[0] = new PTNode(NodeChild0->world.x,NodeChild0->world.y,rc.w,rc.h);
					NodeChild0->child[1] = new PTNode(NodeChild0->world.x+rc.w+1,NodeChild0->world.y,NodeChild0->world.w - rc.w -1,rc.h);
					NodeChild0->child[0]->ID = WAITING_FOR_WRITE;
					return NodeChild0->child[0];
				}
			}
		}

		else
		{
			PTNode* pNode = child[0]->insert(rc);
			if(pNode) 
				return pNode;
			else
			{
				return child[1]->insert(rc);
			}
		}
	}
};




#endif

你可能感兴趣的:(bin packing)