內包含多邊形區域填充

#pragma once
#include <list>
#include <algorithm>
#include <vector>
#include <iostream>  
#include <stack>  
#include <cassert>  
using namespace std;

typedef vector<SkPoint>		PolygonData;
void DrawPolygons( const vector<PolygonData> t,SkCanvas* canvas );
bool IsPolyInPoly(BoostPolygon2Wm5 * bp1,BoostPolygon2Wm5 * bp2);
void draw_tree(htree_node<BoostPolygon2Wm5>* some, unsigned recurs_level,SkCanvas* canvas);


template<class T>  
class htree_node{  
public:  
	typedef htree_node<T> node_type;  
	htree_node()  
		:parent(0),format("  ")  
	{}  
	htree_node(const T& x)        
		:name(x), parent(0), format("  ")  
	{}  
	~htree_node()  
	{}  
	T name;  
	//默認爲兩個空格  
	std::string format;  
	node_type *parent;  
	std::vector<node_type*> children;  
};  
template<class T, class Container = htree_node<T> >  
class htree{  
protected:  
	typedef Container tree_node;          
public:  
	htree()  
		:root(0)  
	{ Init(); }  
	htree(tree_node *node)  
		:root(node)  
	{ Init(); }  
	~htree(){  
		destroy(root);  
	}  
	//pre_order_iterator  
	class iterator{  
	public:  
		iterator()  
			: _node(0)  
			, skip_current_children_(false)  
		{  
			skip_children();  
		}  
		iterator(tree_node *node)  
			: _node(node)  
			, skip_current_children_(false)  
		{  
			skip_children();  
		}  
		~iterator()  
		{}  
		T& operator*() const  
		{  
			return _node->name;  
		}  
		T* operator->() const  
		{  
			return &(_node->name);  
		}  
		tree_node* get()  
		{  
			return _node;  
		}  
		//開始位置  
		iterator begin() const  
		{  
			return iterator(_node);  
		}  
		//結束位置  const????  
		iterator end() const  
		{  
			return iterator( _find_end(_node) );  
		}  

		tree_node *_node;  
	protected:  
		bool skip_current_children_;  
		void         skip_children()  
		{  
			skip_current_children_=true;  
		}  
		tree_node* _find_end(tree_node* current) const  
		{  
			int pos = current->children.size()-1;  
			if( pos<0 )  
				return (current);  
			//這裏返回iterator會被析構掉,臨時對象  
			//從最後一個孩子找起,  
			else  
				_find_end(current->children[pos]);  
		}  
	};  
public:  
	//注意傳position的引用  
	iterator insert(iterator& position, const T& x)       
	{  
		tree_node *tmp = new tree_node(x);  
		position._node->children.push_back(tmp);  
		tmp->parent = position._node;  
		return iterator(tmp);  
	}  
	//後序遞歸輸出  
	void post_recurs_render(tree_node* some, unsigned recurs_level)  
	{  
		for (unsigned i = 0; i < some->children.size(); i++)  
			post_recurs_render(some->children[i], recurs_level+1);  
		for (int i = 0; i<recurs_level; i++)  
			cout << "  ";  
		cout << some->name << endl;  
	}  
	//先序遞歸輸出  
	void pre_recurs_render(tree_node* some, unsigned recurs_level)  
	{  
		for (int i = 0; i<recurs_level; i++)  
			cout << "  ";  
		cout << some->name << endl;  
		for (unsigned i = 0; i < some->children.size(); i++)  
			pre_recurs_render(some->children[i], recurs_level+1);  
	}  

	//利用stack  
	//使用Transform格式化輸出  
	void recurs_render(tree_node* some)  
	{  
		std::string temp;  
		temp = form_stack.top() + some->format;  
		form_stack.push(temp);  

		cout << temp;  
		cout << some->name;  
		cout << endl;  
		for (unsigned i = 0; i < some->children.size(); i++)  
			recurs_render(some->children[i]);  
		form_stack.pop();  
	}  
	tree_node *root;  
private:  
	void Init(){  
		form_stack.push(std::string(" "));
	};  
	void destroy(tree_node *some)  
	{  
#define SAFE_DELETE(p) {if(p){delete p; p=NULL;}}  
		//後序刪除  
		for (unsigned i = 0; i < some->children.size(); i++)  
			destroy(some->children[i]);  
		SAFE_DELETE(some);  
	}  
	std::stack<std::string> form_stack;  
};  


//調用接口,傳入一個vector<vector<Skpoint>>數據
void DrawPolygons( const vector<PolygonData> t,SkCanvas* canvas )
{
	vector<BoostPolygon2Wm5> vectorOfPoly;
	for (int i = 0; i < t.size() ; i++ )
	{
		vector<BoostPolygon2Wm5::Wm5Point>	v_poly;
		for (int j = 0; j < t[i].size(); j++ )
		{
			v_poly.push_back(BoostPolygon2Wm5::Wm5Point(t[i][j].fX,t[i][j].fY));
		}
		BoostPolygon2Wm5 bpoly(v_poly);
		vectorOfPoly.push_back(bpoly);
	}
	//排序
	for (int i = 0; i < vectorOfPoly.size() ; i++ )
	{
		for ( int j = i ; j < vectorOfPoly.size() ; j++)
		{
			if (vectorOfPoly[i].Area() < vectorOfPoly[j].Area())
			{
				BoostPolygon2Wm5 bpolyTemp(vectorOfPoly[i]);
				vectorOfPoly[i] = vectorOfPoly[j];
				vectorOfPoly[j] = bpolyTemp;
			}
		}
	}
 
	typedef htree_node<BoostPolygon2Wm5> node_type; 
	typedef htree<BoostPolygon2Wm5> tree_type;  
	node_type *one = new node_type(vectorOfPoly[0]);
	tree_type::iterator iter(one);
	tree_type tr1(one);  

	vector<tree_type::iterator> vectorOfIterator;
	vectorOfIterator.push_back(iter);
	tree_type::iterator newIterator;
	int k = 1;
	//將多邊形的關係放入tree中去
	while ( k < vectorOfPoly.size())
	{
		if (IsPolyInPoly(&vectorOfPoly[k],&vectorOfPoly[k-1]))
		{
			newIterator = tr1.insert(vectorOfIterator[k-1], vectorOfPoly[k]);
		}
		else
		{
			int j = 2;
			while(k-j >= 0)
			{
				if (IsPolyInPoly(&vectorOfPoly[k],&vectorOfPoly[k-j]))
				{
					newIterator = tr1.insert(vectorOfIterator[k-j], vectorOfPoly[k]);
					j++;
					break;
				}
				j++;
			}
		}
		k++;
		vectorOfIterator.push_back(newIterator);
	}
	draw_tree(tr1.root,1,canvas);
}
//判斷多邊形的包含關係
bool IsPolyInPoly(BoostPolygon2Wm5 * bp1,BoostPolygon2Wm5 * bp2)
{
	vector<BoostPolygon2Wm5::Wm5Point> pt = bp1->GetVectorPoints();
	for (int i = 0; i < pt.size() ; i++ )
	{
		if (!(bp2->is_in(pt[i])))
			return false;
	}
	return true;
}

void draw_tree(htree_node<BoostPolygon2Wm5>* some, unsigned recurs_level,SkCanvas* canvas)  
{
	//隔一組tree中的父親和孩子畫圖
	if (recurs_level%2)
	{
		canvas->save(SkCanvas::kClip_SaveFlag);
		vector<BoostPolygon2Wm5::Wm5Point> ptFather = some->name.GetVectorPoints();
		SkPoint * pPointFather = new SkPoint[ptFather.size()];
		for ( int i = 0; i < ptFather.size() ; i++ )
		{
			pPointFather[i] = SkPoint::Make(ptFather[i].X(),ptFather[i].Y());
		}
		SkPath pathFather;
		pathFather.addPoly(pPointFather,ptFather.size(),true);
		SkPaint paint;
		paint.setStyle(SkPaint::kFill_Style);
		paint.setColor(SK_ColorRED);
		paint.setAntiAlias(true);
		for (unsigned i = 0; i < some->children.size(); i++)  
		{
			vector<BoostPolygon2Wm5::Wm5Point> ptChildren = some->children[i]->name.GetVectorPoints();
			SkPoint * pPointChildren = new SkPoint[ptChildren.size()];
			for ( int i = 0; i < ptChildren.size() ; i++ )
			{
				pPointChildren[i] = SkPoint::Make(ptChildren[i].X(),ptChildren[i].Y());
			}
			SkPath pathChildren;
			pathChildren.addPoly(pPointChildren,ptChildren.size(),true);

			canvas->clipPath(pathChildren,SkRegion::kDifference_Op);

			delete pPointChildren;

		}
		canvas->drawPath(pathFather,paint);
		delete pPointFather;
		canvas->restore();
	}

  	for (unsigned i = 0; i < some->children.size(); i++)  
  		draw_tree(some->children[i], recurs_level+1,canvas);

}  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章