[从头读历史] 第305节 星球战争 BC2899 至 BC2800(公元前29世纪)

剧情提要:
最初的时候是原始时期战争,所谓原始时期,指的是约公元前30世纪—前22世纪。
公元前29世纪,没有发生什么有记录的战争。


正剧开始:
星历2016年07月15日 15:52:05, 银河系厄尔斯星球中华帝国江南行省。

[工程师阿伟]正在和[机器小伟]一起研究[星球战争 BC2899 至 BC2800(公元前29世纪)]。




这个世纪竟然没有发生战争,于是阿伟就去找这个年代的大佬神农氏询问情况。

 

阿伟找到了神农氏,就问他:你们怎么不打仗啊,不打仗我写什么呀,总要有点故事吧。

 

神农氏对阿伟说:其实这是有原因的,我们不是刚打了斧燧氏嘛,那帮家伙当时说是服我们了,但这都好多年过去了,他们消极怠工,做出的石头工具也不如以前那么高质量了,我们都在想怎么办呢,哪有心思去打仗啊。

 

阿伟噢了一下,表示理解。

 

这时神农氏就带领阿伟参观他们自己的工具制造工厂。




对这些东西,阿伟表示理解不能。




这都是干什么用的呢。


或许,等下个世纪再过来看看吧。


彩蛋:

下面是C++语言的三角形分割代码:

<span style="font-size:18px;">/*
D:\360极速浏览器下载\Bowyer_Watson\Bowyer_Watson\BowyerWatson.cpp
D:\360极速浏览器下载\Bowyer_Watson\Bowyer_Watson\BowyerWatson.h
D:\360极速浏览器下载\Bowyer_Watson\Bowyer_Watson\Line.cpp
D:\360极速浏览器下载\Bowyer_Watson\Bowyer_Watson\Line.h
D:\360极速浏览器下载\Bowyer_Watson\Bowyer_Watson\Main.cpp
D:\360极速浏览器下载\Bowyer_Watson\Bowyer_Watson\Point.cpp
D:\360极速浏览器下载\Bowyer_Watson\Bowyer_Watson\Point.h
D:\360极速浏览器下载\Bowyer_Watson\Bowyer_Watson\Triangle.cpp
D:\360极速浏览器下载\Bowyer_Watson\Bowyer_Watson\Triangle.h
*/

///D:\360极速浏览器下载\Bowyer_Watson\Bowyer_Watson\BowyerWatson.cpp
#include "Point.h"
#include "Line.h"
#include "Triangle.h"
#include "BowyerWatson.h"



CBowyerWatson* CBowyerWatson::m_pBowyerWatson = NULL;

CBowyerWatson::CBowyerWatson()
{
	ClearBowyerWatson();
}
CBowyerWatson::~CBowyerWatson()
{
	ClearBowyerWatson();
}

CBowyerWatson* CBowyerWatson::GetInstance()
{
	if( !m_pBowyerWatson )
		m_pBowyerWatson = new CBowyerWatson;
	return m_pBowyerWatson;
}

void CBowyerWatson::ClearBowyerWatson()
{
	m_bUpdateDrawFlag = false;

	std::list<CPoint*>::iterator iter_point =	m_lstBowyerWatsonPointList.begin();
	while (iter_point != m_lstBowyerWatsonPointList.end())
	{
		std::list<CPoint*>::iterator iter_pointNext = iter_point;
		iter_pointNext++;

		SAFE_DELETE(*iter_point);
		m_lstBowyerWatsonPointList.erase(iter_point);

		iter_point = iter_pointNext;
	}//Point

	std::list<CLine*>::iterator iter_line =	m_lstBowyerWatsonLineList.begin();
	while (iter_line != m_lstBowyerWatsonLineList.end())
	{
		std::list<CLine*>::iterator iter_lineNext = iter_line;
		iter_lineNext++;

		SAFE_DELETE(*iter_line);
		m_lstBowyerWatsonLineList.erase(iter_line);

		iter_line = iter_lineNext;
	}//line

	std::list<CTriangle*>::iterator iter_triangle =	m_lstBowyerWatsonTriangleList.begin();
	while (iter_triangle != m_lstBowyerWatsonTriangleList.end())
	{
		std::list<CTriangle*>::iterator iter_triangleNext = iter_triangle;
		iter_triangleNext++;

		SAFE_DELETE(*iter_triangle);
		m_lstBowyerWatsonTriangleList.erase(iter_triangle);

		iter_triangle = iter_triangleNext;
	}//Triangle

	iter_point = m_lstAddPointList.begin();
	while (iter_point != m_lstAddPointList.end())
	{
		std::list<CPoint*>::iterator iter_pointNext = iter_point;
		iter_pointNext++;

		SAFE_DELETE(*iter_point);
		m_lstAddPointList.erase(iter_point);

		iter_point = iter_pointNext;
	}//Point
}

void CBowyerWatson::CreateHelperPoint(CPoint pt1, CPoint pt2, CPoint pt3, CPoint pt4)
{
	mHelperPoints[0] = pt1;
	mHelperPoints[1] = pt2;
	mHelperPoints[2] = pt3;
	mHelperPoints[3] = pt4;

	//加入辅助点4个
	AddBowyerWatsonPoint(pt1);
	AddBowyerWatsonPoint(pt2);
	AddBowyerWatsonPoint(pt3);
	AddBowyerWatsonPoint(pt4);

	//加入辅助窗体的5条边
	CLine line1 = CLine(pt1,pt2);
	CLine line2 = CLine(pt2,pt3);
	CLine line3 = CLine(pt3,pt4);
	CLine line4 = CLine(pt4,pt1);
	CLine line5 = CLine(pt2,pt4);
	AddBowyerWatsonLine(line1);
	AddBowyerWatsonLine(line2);
	AddBowyerWatsonLine(line3);
	AddBowyerWatsonLine(line4);
	AddBowyerWatsonLine(line5);

	//加入辅助三角形2个
	CTriangle tg1 = CTriangle(pt1,pt2,pt4);
	CTriangle tg2 = CTriangle(pt2,pt3,pt4);
	AddBowyerWatsonTriangle(tg1);
	AddBowyerWatsonTriangle(tg2);

}

void CBowyerWatson::AddNewPoint(CPoint pt)
{
	bool existflag = false;
	std::list<CPoint*>::iterator iter_point = m_lstAddPointList.begin();
	for ( ;iter_point != m_lstAddPointList.end();iter_point++)
	{
		if (pt == (**iter_point))
		{
			existflag = true;
		}
	}

	if (!existflag)
	{
		CPoint* newPoint = new CPoint(pt.x,pt.y);
		m_lstAddPointList.push_back(newPoint);
	}
}

void CBowyerWatson::UpdateNewPoint()
{
	std::list<CPoint*>::iterator iter_point = m_lstAddPointList.begin();
	while (iter_point != m_lstAddPointList.end())
	{
		ProcessNewPoint(**iter_point);

		std::list<CPoint*>::iterator iter_pointNext = iter_point;
		iter_pointNext++;

		SAFE_DELETE(*iter_point);
		m_lstAddPointList.erase(iter_point);

		iter_point = iter_pointNext;
	}//Point

	//剔除辅助边
	std::list<CLine*>::iterator iter = m_lstBowyerWatsonLineList.begin();
	while(iter != m_lstBowyerWatsonLineList.end())
	{
		CLine line = (**iter);
		if (line.CheckPointExist(mHelperPoints[0]) || line.CheckPointExist(mHelperPoints[1]) || \
			line.CheckPointExist(mHelperPoints[2]) || line.CheckPointExist(mHelperPoints[3]))
		{
			std::list<CLine*>::iterator iter_next = iter;
			iter_next++;
			SAFE_DELETE(*iter);
			m_lstBowyerWatsonLineList.erase(iter);

			iter = iter_next;
		}
		else{
			iter++;
		}
	}

	//剔除辅助三角形
	std::list<CTriangle*>::iterator iter_triangle = m_lstBowyerWatsonTriangleList.begin();
	while(iter_triangle != m_lstBowyerWatsonTriangleList.end())
	{
		CTriangle triangle = (**iter_triangle);
		if (triangle.CheckPointExist(mHelperPoints[0]) || triangle.CheckPointExist(mHelperPoints[1]) || \
			triangle.CheckPointExist(mHelperPoints[2]) || triangle.CheckPointExist(mHelperPoints[3]))
		{
			std::list<CTriangle*>::iterator iter_nextTriangle = iter_triangle;
			iter_nextTriangle++;
			SAFE_DELETE(*iter_triangle);
			m_lstBowyerWatsonTriangleList.erase(iter_triangle);

			iter_triangle = iter_nextTriangle;
		}
		else{
			iter_triangle++;
		}
	}
}

void CBowyerWatson::AddBowyerWatsonPoint(CPoint pt)
{
	bool existflag = false;
	std::list<CPoint*>::iterator iter_point = m_lstBowyerWatsonPointList.begin();
	for ( ;iter_point != m_lstBowyerWatsonPointList.end();iter_point++)
	{
		if (pt == (**iter_point))
		{
			existflag = true;
		}
	}

	if (!existflag)
	{
		CPoint* newPoint = new CPoint(pt.x,pt.y);
		m_lstBowyerWatsonPointList.push_back(newPoint);
	}

}

void CBowyerWatson::AddBowyerWatsonLine(CLine line)
{
	bool existflag = false;
	std::list<CLine*>::iterator iter_line = m_lstBowyerWatsonLineList.begin();
	for ( ;iter_line != m_lstBowyerWatsonLineList.end();iter_line++)
	{
		if (line == (**iter_line))
		{
			existflag = true;
		}
	}

	if (!existflag)
	{
		CLine* newLine = new CLine(line.p1,line.p2);
		m_lstBowyerWatsonLineList.push_back(newLine);
	}
}

void CBowyerWatson::DelBowyerWatsonLine(CLine line)
{
	std::list<CLine*>::iterator iter_line =	m_lstBowyerWatsonLineList.begin();
	while (iter_line != m_lstBowyerWatsonLineList.end())
	{
		if (line == (**iter_line))
		{
			SAFE_DELETE(*iter_line);
			m_lstBowyerWatsonLineList.erase(iter_line);
			break;
		}
		else
			iter_line++;
	}//line

	std::list<CTriangle*>::iterator iter_Triangle =	m_lstBowyerWatsonTriangleList.begin();
	while (iter_Triangle != m_lstBowyerWatsonTriangleList.end())
	{
		if ((*iter_Triangle)->l1 == line || (*iter_Triangle)->l2 == line || (*iter_Triangle)->l3 == line )
		{
			SAFE_DELETE(*iter_Triangle);
			m_lstBowyerWatsonTriangleList.erase(iter_Triangle);
			break;
		}
		else
			iter_Triangle++;
	}//Triangle
}

void CBowyerWatson::AddBowyerWatsonTriangle(CTriangle triangle)
{
	bool existflag = false;
	std::list<CTriangle*>::iterator iter_Triangle = m_lstBowyerWatsonTriangleList.begin();
	for ( ;iter_Triangle != m_lstBowyerWatsonTriangleList.end();iter_Triangle++)
	{
		if (triangle == (**iter_Triangle))
		{
			existflag = true;
		}
	}

	if (!existflag)
	{
		CTriangle* newTriangle = new CTriangle(triangle.p1,triangle.p2,triangle.p3);
		m_lstBowyerWatsonTriangleList.push_back(newTriangle);
	}
}

void CBowyerWatson::DelBowyerWatsonTriangle(CTriangle triangle)
{
	std::list<CTriangle*>::iterator iter_Triangle =	m_lstBowyerWatsonTriangleList.begin();
	while (iter_Triangle != m_lstBowyerWatsonTriangleList.end())
	{
		if (triangle == (**iter_Triangle))
		{
			SAFE_DELETE(*iter_Triangle);
			m_lstBowyerWatsonTriangleList.erase(iter_Triangle);
			return;
		}
		else
			iter_Triangle++;
	}//line
}

void CBowyerWatson::ProcessNewPoint(CPoint pt)
{
	std::list<CLine*>	lineList ;
	std::list<CTriangle*> triangleList;
	std::vector<CTriangle*> commonTriangleVector;

	std::list<CLine*>::iterator iter_line =	m_lstBowyerWatsonLineList.begin();
	for(;iter_line != m_lstBowyerWatsonLineList.end();iter_line++)
	{
		CLine* newline = new CLine();
		memcpy(newline, *iter_line, sizeof(CLine));

		lineList.push_back(newline);
	}
	std::list<CTriangle*>::iterator iter_triangle =	m_lstBowyerWatsonTriangleList.begin();
	for(;iter_triangle != m_lstBowyerWatsonTriangleList.end();iter_triangle++)
	{
		CTriangle* newtriangle = new CTriangle();
		memcpy(newtriangle, *iter_triangle, sizeof(CTriangle));

		triangleList.push_back(newtriangle);
	}

	iter_triangle = triangleList.begin();
	while (iter_triangle != triangleList.end())
	{
		//是否存在三角形外接圆内
		if ((*iter_triangle)->CheckInCircle(pt))
		{
			commonTriangleVector.push_back(*iter_triangle);
		}
		iter_triangle++;
	}// triangle

	if (commonTriangleVector.size() == 1)
	{
		std::vector<CTriangle*>::iterator iter_v =	commonTriangleVector.begin();

		
		//删除三角形
		DelBowyerWatsonTriangle(**iter_v);

		/
		//连接三角形三点
		CLine line1 = CLine(pt,(*iter_v)->p1);
		CLine line2 = CLine(pt,(*iter_v)->p2);
		CLine line3 = CLine(pt,(*iter_v)->p3);
		AddBowyerWatsonLine(line1);
		AddBowyerWatsonLine(line2);
		AddBowyerWatsonLine(line3);

		//加入新三角形
		if (CheckTriangleLinesExist(pt, (*iter_v)->p1, (*iter_v)->p2))
		{
			CTriangle tg1 = CTriangle(pt,(*iter_v)->p1,(*iter_v)->p2);
			AddBowyerWatsonTriangle(tg1);
		}
		if (CheckTriangleLinesExist(pt, (*iter_v)->p2, (*iter_v)->p3))
		{
			CTriangle tg2 = CTriangle(pt,(*iter_v)->p2,(*iter_v)->p3);
			AddBowyerWatsonTriangle(tg2);
		}
		if (CheckTriangleLinesExist(pt, (*iter_v)->p3, (*iter_v)->p1))
		{
			CTriangle tg3 = CTriangle(pt,(*iter_v)->p3,(*iter_v)->p1);
			AddBowyerWatsonTriangle(tg3);
		}
	}

	if (commonTriangleVector.size() > 1)
	{
		for (int i = 0;i < (commonTriangleVector.size()-1);i++)
		{
			for (int j = i+1;j <commonTriangleVector.size();j++)
			{
				CTriangle* trg1 =	*(commonTriangleVector.begin() + i);
				CTriangle* trg2 =	*(commonTriangleVector.begin() +j);

				CLine* commonLine = trg1->FindCommonLine(*trg2);
				if (commonLine != NULL)
				{
					
					//删除影响三角形
					DelBowyerWatsonTriangle(*trg1);
					DelBowyerWatsonTriangle(*trg2);

					//删除公共边
					DelBowyerWatsonLine(*commonLine);

					/
					//连接三角形三点
					CLine line1_1 = CLine(pt,trg1->p1);
					CLine line1_2 = CLine(pt,trg1->p2);
					CLine line1_3 = CLine(pt,trg1->p3);
					CLine line2_1 = CLine(pt,trg2->p1);
					CLine line2_2 = CLine(pt,trg2->p2);
					CLine line2_3 = CLine(pt,trg2->p3);

					AddBowyerWatsonLine(line1_1);
					AddBowyerWatsonLine(line1_2);
					AddBowyerWatsonLine(line1_3);
					AddBowyerWatsonLine(line2_1);
					AddBowyerWatsonLine(line2_2);
					AddBowyerWatsonLine(line2_3);

					//加入新三角形
					if (CheckTriangleLinesExist(pt, trg1->p1, trg1->p2))
					{
						CTriangle tg1 = CTriangle(pt, trg1->p1, trg1->p2);
						AddBowyerWatsonTriangle(tg1);
					}
					if (CheckTriangleLinesExist(pt, trg1->p2, trg1->p3))
					{
						CTriangle tg2 = CTriangle(pt,trg1->p2,trg1->p3);
						AddBowyerWatsonTriangle(tg2);
					}
					if (CheckTriangleLinesExist(pt, trg1->p3, trg1->p1))
					{
						CTriangle tg3 = CTriangle(pt, trg1->p3, trg1->p1);
						AddBowyerWatsonTriangle(tg3);
					}

					if (CheckTriangleLinesExist(pt, trg2->p1, trg2->p2))
					{
						CTriangle tg1 = CTriangle(pt, trg2->p1, trg2->p2);
						AddBowyerWatsonTriangle(tg1);
					}
					if (CheckTriangleLinesExist(pt, trg2->p2, trg2->p3))
					{
						CTriangle tg2 = CTriangle(pt,trg2->p2,trg2->p3);
						AddBowyerWatsonTriangle(tg2);
					}
					if (CheckTriangleLinesExist(pt, trg2->p3, trg2->p1))
					{
						CTriangle tg3 = CTriangle(pt, trg2->p3, trg2->p1);
						AddBowyerWatsonTriangle(tg3);
					}

				}
			}
		}
	}

	AddBowyerWatsonPoint(pt);

	iter_line =	lineList.begin();
	while (iter_line != lineList.end())
	{
		std::list<CLine*>::iterator iter_lineNext = iter_line;
		iter_lineNext++;

		SAFE_DELETE(*iter_line);
		lineList.erase(iter_line);

		iter_line = iter_lineNext;
	}//line

	iter_triangle =	triangleList.begin();
	while (iter_triangle != triangleList.end())
	{
		std::list<CTriangle*>::iterator iter_triangleNext = iter_triangle;
		iter_triangleNext++;

		SAFE_DELETE(*iter_triangle);
		triangleList.erase(iter_triangle);

		iter_triangle = iter_triangleNext;
	}//Triangle
}

bool CBowyerWatson::CheckTriangleLinesExist(CPoint pt1, CPoint pt2, CPoint pt3)
{
	bool exist_line1 = false;
	bool exist_line2 = false;
	bool exist_line3 = false;

	CLine line1 = CLine(pt1, pt2);
	CLine line2 = CLine(pt2, pt3);
	CLine line3 = CLine(pt3, pt1);

	std::list<CLine*>::iterator iter_line = m_lstBowyerWatsonLineList.begin();
	for ( ;iter_line != m_lstBowyerWatsonLineList.end();iter_line++)
	{
		if (line1 == (**iter_line))
		{
			exist_line1 = true;
			continue;
		}
		if (line2 == (**iter_line))
		{
			exist_line2 = true;
			continue;
		}
		if (line3 == (**iter_line))
		{
			exist_line3 = true;
		}
	}

	if (exist_line1 && exist_line2 && exist_line3)
	{
		return true;
	}

	return false;
}

void CBowyerWatson::DrawMesh()
{
	std::list<CLine*>::iterator iter = m_lstBowyerWatsonLineList.begin(); 
	for ( ;iter != m_lstBowyerWatsonLineList.end();iter++)
	{
		//(*iter)->p1.x, (*iter)->p1.y
		//(*iter)->p2.x, (*iter)->p2.y
	}
}

void CBowyerWatson::Update()
{
	if (m_bUpdateDrawFlag)
	{
		DrawMesh();
	}
}




///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/BowyerWatson.h


#ifndef __CBOWYER_WATSON_H__
#define __CBOWYER_WATSON_H__

#include <list> 
#include <vector>

class CPoint;
class CLine;
class CTriangle;

class CBowyerWatson{
public:

	CBowyerWatson();
	~CBowyerWatson();

	static		CBowyerWatson* GetInstance();

	void		ClearBowyerWatson();

	void		CreateHelperPoint(CPoint pt1, CPoint pt2, CPoint pt3, CPoint pt4);

	void		AddNewPoint(CPoint pt);
	void		UpdateNewPoint();

	void		AddBowyerWatsonPoint(CPoint pt);

	void		AddBowyerWatsonLine(CLine line);
	void		DelBowyerWatsonLine(CLine line);

	void		AddBowyerWatsonTriangle(CTriangle triangle);
	void		DelBowyerWatsonTriangle(CTriangle triangle);

	void		ProcessNewPoint(CPoint pt);
	bool		CheckTriangleLinesExist(CPoint pt1, CPoint pt2, CPoint pt3);

	void		DrawMesh();

	void		SetUpdateDrawFlag(bool flag){m_bUpdateDrawFlag = flag;};
	void		Update();

	const std::list<CLine*>& GetBowyerWatsonLines(){return m_lstBowyerWatsonLineList;};
	const std::list<CTriangle*>& GetBowyerWatsonTriangles(){return m_lstBowyerWatsonTriangleList;};

private:

	std::list<CPoint*>		m_lstBowyerWatsonPointList;
	std::list<CLine*>			m_lstBowyerWatsonLineList;
	std::list<CTriangle*>		m_lstBowyerWatsonTriangleList;

	std::list<CPoint*>		m_lstAddPointList;

	CPoint mHelperPoints[4];

	static CBowyerWatson* m_pBowyerWatson;

	bool	m_bUpdateDrawFlag;
	
};




#endif




///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Line.cpp



#include "Line.h"
#include "Point.h"


float CLine::Point2LineDistance(CPoint pt)
{
	float a = p2.y - p1.y;
	float b = p1.x - p2.x;
	float c = p2.x*p1.y - p1.x*p2.y;

	float dis = fabs(a*pt.x + b*pt.y + c)/sqrt(a*a + b*b);

	return dis;
}


bool CLine::operator ==(const CLine& l)
{
	if (l.p1.x == p1.x && l.p1.y == p1.y &&l.p2.x == p2.x && l.p2.y == p2.y)
	{
		return true;
	}

	if (l.p2.x == p1.x && l.p2.y == p1.y &&l.p1.x == p2.x && l.p1.y == p2.y)
	{
		return true;
	}

	return false;
}

CLine& CLine::operator =(const CLine& l)
{
	p1 = l.p1;
	p2 = l.p2;
	return *this;
}




///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Line.h


#ifndef __CLINEH__
#define __CLINEH__

#include "Point.h"

class CLine{
public:
	CPoint p1;
	CPoint p2;

	CLine()
	{

	};

	CLine(CPoint pt1, CPoint pt2)
	{
		p1.x = pt1.x;
		p1.y = pt1.y;
		p2.x = pt2.x;
		p2.y = pt2.y;
	};

	bool CheckPointExist(CPoint pt)
	{
		if (pt == p1 || pt == p2)
		{
			return true;
		}

		return false;
	};

	float Point2LineDistance(CPoint pt);

	bool operator ==(const CLine& l);
	CLine& operator =(const CLine& l);
};

#endif




///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Main.cpp


#include<iostream> 
#include <map> 
#include "Line.h"
#include "Point.h"
#include "Triangle.h"
#include "BowyerWatson.h"
using namespace std; 


void main()
{
	cout<<"********************* Bowyer_Watson_algorithm              ****************** "<<endl;
	cout<<"********************* 本程序目标为实现Bowyer_Watson算法    ******************"<<endl;
	cout<<"********************* 如有遇到BUG请联系作者                ******************"<<endl;
	cout<<"********************* email: zzzzyu@sina.com               ******************"<<endl;
	cout<<"********************* Blog: blog.csdn.net/zzzzyu           ******************"<<endl;
	cout<<endl<<endl;

	CBowyerWatson::GetInstance()->ClearBowyerWatson();
	CBowyerWatson::GetInstance()->CreateHelperPoint(CPoint(0,0),CPoint(0,100),CPoint(100,100),CPoint(100,0));

	CBowyerWatson::GetInstance()->AddNewPoint(CPoint(25,25));
	CBowyerWatson::GetInstance()->AddNewPoint(CPoint(35,50));
	CBowyerWatson::GetInstance()->AddNewPoint(CPoint(40,48));
	CBowyerWatson::GetInstance()->AddNewPoint(CPoint(50,25));
	CBowyerWatson::GetInstance()->AddNewPoint(CPoint(50,40));

	CBowyerWatson::GetInstance()->UpdateNewPoint();

	const std::list<CLine*> lineList = CBowyerWatson::GetInstance()->GetBowyerWatsonLines();
	std::list<CLine*>::const_iterator ite_line = lineList.begin(); 
	for ( ;ite_line != lineList.end();ite_line++)
	{
		cout<<"line : ("<<(*ite_line)->p1.x<<" "<<(*ite_line)->p1.y<<")  "  \
					<<"("<<(*ite_line)->p2.x<<" "<<(*ite_line)->p2.y<<")"<<endl;
	}

	cout<<endl<<endl;

	const std::list<CTriangle*> triangleList = CBowyerWatson::GetInstance()->GetBowyerWatsonTriangles();
	std::list<CTriangle*>::const_iterator iter_triangle = triangleList.begin(); 
	for ( ;iter_triangle != triangleList.end();iter_triangle++)
	{
		cout<<"Triangle : ("<<(*iter_triangle)->p1.x<<" "<<(*iter_triangle)->p1.y<<")  "  \
			<<(*iter_triangle)->p2.x<<" "<<(*iter_triangle)->p2.y<<")  "  \
			<<"("<<(*iter_triangle)->p3.x<<" "<<(*iter_triangle)->p3.y<<")"<<endl;
	}

	cout<<"Lines count : "<<lineList.size()<<endl;
	cout<<"Triangles count : "<<triangleList.size()<<endl;

	int ci;

	cin>>ci;

	return;

} 




///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Point.cpp



#include "Point.h"


bool CPoint::operator ==(const CPoint& p)
{
	if (p.x == x && p.y == y)
	{
		return true;
	}

	return false;
}

CPoint& CPoint::operator =(const CPoint& p)
{
	x = p.x;
	y = p.y;

	return *this;
}




///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Point.h


#ifndef __CPOINTH__
#define __CPOINTH__

#define NULL 0 
#define SAFE_DELETE(x) if( (x)!=NULL ) { delete (x); (x)=NULL; } 

#include <math.h> 

class CPoint{

public:
	float x;
	float y;

	CPoint()
	{
		x = 0;
		y = 0;
	};

	static float distance(CPoint pt1 , CPoint pt2)
	{
		return sqrt((pt1.x-pt2.x)*(pt1.x-pt2.x) + (pt1.y-pt2.y)*(pt1.y-pt2.y));
	};

	CPoint(float fx, float fy)
	{
		x = fx;
		y = fy;
	};

	bool operator ==(const CPoint& p);
	CPoint& operator =(const CPoint& p);
};


#endif




///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Triangle.cpp



#include "Triangle.h"
#include <math.h> 

CTriangle::CTriangle(CPoint pt1, CPoint pt2, CPoint pt3)
{	
	p1 = pt1;
	p2 = pt2;
	p3 = pt3;

	l1 = CLine(p1,p2);
	l2 = CLine(p2,p3);
	l3 = CLine(p3,p1);

	float dis1 = CPoint::distance(p1,p2);
	float dis2 = CPoint::distance(p2,p3);
	float dis3 = CPoint::distance(p3,p1);

	radiu = dis1*dis2*dis3/TriangleArea()/4;

	float c1, c2;   
	float xA, yA, xB, yB, xC, yC;  

	xA = p1.x; yA = p1.y;   
	xB = p2.x; yB = p2.y;   
	xC = p3.x; yC = p3.y;   
	c1 = (xA * xA + yA * yA - xB * xB - yB * yB) / 2;   
	c2 = (xA * xA + yA * yA - xC * xC - yC * yC) / 2;   

	center.x = (c1 * (yA - yC) - c2 * (yA - yB)) /    
		((xA - xB) * (yA - yC) - (xA - xC) * (yA - yB));    
	center.y = (c1 * (xA - xC) - c2 * (xA - xB)) /    
		((yA - yB) * (xA - xC) - (yA - yC) * (xA - xB));    

}

float CTriangle::TriangleArea()
{
	return fabs(p1.x * p2.y + p2.x * p3.y    
		+ p3.x * p1.y - p2.x * p1.y   
		- p3.x * p2.y - p1.x * p3.y) / 2; 
}

bool CTriangle::CheckInCircle(CPoint pt)
{
	if (CPoint::distance(center,pt) <= radiu)
	{
		return true;
	}

	return false;
}


CLine CTriangle::FindNearestLine(CPoint pt)
{
	float dis1 = l1.Point2LineDistance(pt);
	float dis2 = l2.Point2LineDistance(pt);
	float dis3 = l3.Point2LineDistance(pt);

	if (dis1 <= dis2 && dis1 <= dis3)
	{
		return l1;
	}
	if (dis2 <= dis1 && dis2 <= dis3)
	{
		return l2;
	}

	return l3;
}

CLine* CTriangle::FindCommonLine(CTriangle tg)
{
	if (this->l1 == tg.l1 || this->l1 == tg.l2 || this->l1 == tg.l3)
	{
		return &l1;
	}

	if (this->l2 == tg.l1 || this->l2 == tg.l2 || this->l2 == tg.l3)
	{
		return &l2;
	}

	if (this->l3 == tg.l1 || this->l3 == tg.l2 || this->l3 == tg.l3)
	{
		return &l3;
	}

	return NULL;
}

CPoint CTriangle::GetOtherPoint(CPoint pt1, CPoint pt2)
{
	if (!(p1 == pt1) && !(p1 == pt2))
	{
		return p1;
	}

	if (!(p2 == pt1) && !(p2 == pt2))
	{
		return p2;
	}

	return p3;
}

bool CTriangle::CheckPointExist(CPoint pt)
{
	if (pt == p1 || pt == p2 || pt == p3)
	{
		return true;
	}

	return false;
}

bool CTriangle::operator ==(const CTriangle& t)
{
	if ((p1 == t.p1) && (p2 == t.p2) && (p3 == t.p3))
	{
		return true;
	}
	if ((p1 == t.p1) && (p3 == t.p2) && (p2 == t.p3))
	{
		return true;
	}

	if ((p2 == t.p1) && (p1 == t.p2) && (p3 == t.p3))
	{
		return true;
	}
	if ((p2 == t.p1) && (p3 == t.p2) && (p1 == t.p3))
	{
		return true;
	}

	if ((p3 == t.p1) && (p2 == t.p2) && (p1 == t.p3))
	{
		return true;
	}
	if ((p3 == t.p1) && (p1 == t.p2) && (p2 == t.p3))
	{
		return true;
	}

	return false;
}




///D:/360极速浏览器下载/Bowyer_Watson/Bowyer_Watson/Triangle.h



#ifndef __CTRIANGLEH__
#define __CTRIANGLEH__

#include "Point.h"
#include "Line.h"

class CTriangle{

public :
	CPoint p1;
	CPoint p2;
	CPoint p3;

	CLine l1;
	CLine l2;
	CLine l3;

	CPoint center;
	float radiu;

	CTriangle(){};
	CTriangle(CPoint pt1, CPoint pt2, CPoint pt3);

	bool CheckInCircle(CPoint pt);

	float TriangleArea();

	CLine FindNearestLine(CPoint pt);
	CLine* FindCommonLine(CTriangle tg);

	CPoint GetOtherPoint(CPoint pt1, CPoint pt2);

	bool CheckPointExist(CPoint pt);

	bool operator ==(const CTriangle& t);
};

#endif




</span>

下面是python的三角形分割代码:

<span style="font-size:18px;">import geo;

###
# @usage   Bowyer-Watson算法进行Delaunay三角剖分
# @author  mw
# @date    2016年07月15日  星期五  10:31:36 
# @param
# @return
#
###
class Delaunay():
    #设置顶点
    #vertices是[[x_0, y_0], [x_1, y_1], ...]顶点对格式
    def setVertice(self, vertices):
        return vertices;

    def sortVerticebyX(self, vertices):
        v_x = sorted(vertices, key = lambda a : a[0]);
        return v_x;

    def sortVerticebyY(self, vertices):
        v_y = sorted(vertices, key = lambda a : a[1]);
        return v_y;

    #去除重复点
    def removeDup(self, vertices):
        v_new = [];
        len_1 = len(vertices);
        len_2 = 0;

        for i in range(len_1):
            len_2 = len(v_new);
            if (len_2 < 1):
                v_new.append(vertices[i]);
            else:
                for j in range(len_2):
                    if v_new[j] == vertices[i]:
                        break;
                    if (j >= len_2-1):
                        v_new.append(vertices[i]);

        return v_new;
        
    #计算边界
    def calcBound(self, vertices):
        len_ = len(vertices)
        v_x = self.sortVerticebyX(vertices);
        xMin = v_x[0][0];
        xMax = v_x[len_-1][0];

        v_y = self.sortVerticebyY(vertices);
        yMin = v_y[0][1];
        yMax = v_y[len_-1][1];

        return [xMin, xMax, yMin, yMax];

    #超级三角形
    def superTri(self, vertices):
        bound = self.calcBound(vertices);

        xMin = bound[0]-10;
        xMax = bound[1]+10;
        yMin = bound[2]-10;
        yMax = bound[3]+10;

        xCenter = (xMin+xMax)/2;
        yCenter = (yMin+yMax)/2;
        xR = (xMax-xMin)/2;
        yR = (yMax-yMin)/2;

        xMin_ = xCenter-2*xR;
        xMax_ = xCenter+2*xR;
        yMin_ = yMin;
        yMax_ = yMin + 4*yR;

        return [[xMin_, yMin_], [xMax_, yMin_], [xCenter, yMax_]];

    #计算剖分三角形
    def calcDelaunayTri(self, vertices, mode = 1):
        #移除重复点
        vertices = self.removeDup(vertices);
        #按X坐标由小到大排序
        vertices = self.sortVerticebyX(vertices);
        #顶点数量
        vertNum = len(vertices);

        #临时三角形存放处
        tempTriArray = [];
        #三角形存放处
        triArray = [];
        #边存放处
        edgeArray = [];

        supertri = self.superTri(vertices);
        tempTriArray.append(supertri);
        triArray.append(supertri);

        for i in range(vertNum):
            P0 = vertices[i];
            tmpTriNum = len(tempTriArray);
            edgeArray = [];            
            tmpTri = [];
            
            for j in range(tmpTriNum):
                P1, P2, P3 = tempTriArray[j][0], tempTriArray[j][1], tempTriArray[j][2];
                #调用geo的circle方法
                circleProp = geo.circle(P1, P2, P3);
                #取得圆心和半径
                P_center, R = circleProp[0], circleProp[1];

                d = geo.distance2D(P0, P_center);
                if (d <= R):
                    #对比点在圆内,这个三角形被淘汰
                    edgeArray.append([P1, P2]);
                    edgeArray.append([P2, P3]);
                    edgeArray.append([P3, P1]);
                else:
                    if (P0[0] > P_center[0]+R):
                        #对比点是在圆外右侧的三角形,已经得到晋级确认
                        triArray.append([P1, P2, P3]);
                    else:
                        #不确定的三角形,不理它
                        tmpTri.append([P1, P2, P3]);

            edgeArray = self.removeDup(edgeArray);
            edges = len(edgeArray);
            for k in range(edges):
                P1, P2 = edgeArray[k][0], edgeArray[k][1];
                tmpTri.append([P0, P1, P2]);
            #临时数组已经重新安排
            tempTriArray = tmpTri;

        triArray += tempTriArray;

        if (mode == 0):
            return triArray;
        else:
            newTriArray = [];
            
            triNum = len(triArray);
            
            for i in range(triNum):
                tri_ = triArray[i];
                relate = False;
                for j in range(3):
                    if relate == True:
                        break;
                    for k in range(3):
                        if tri_[j] == supertri[k]:
                            relate = True;
                            break;

                if relate == False:
                    newTriArray.append(tri_);

            
            return newTriArray;
        
if __name__ == '__main__':
    delaunay = Delaunay();

    verts =[[0, 0], [30, 0], [30, 30], [40, 10], [50, 20]];
    
    a = delaunay.calcDelaunayTri(verts, 0);

    print(a);</span>

这是算法伪代码:

<span style="font-size:18px;">#伪代码思路
subroutine triangulate
input : vertex list
output : triangle list
   initialize the triangle list
   determine the supertriangle
   add supertriangle vertices to the end of the vertex list
   add the supertriangle to the triangle list
   for each sample point in the vertex list
      initialize the edge buffer
      for each triangle currently in the triangle list
         calculate the triangle circumcircle center and radius
         if the point lies in the triangle circumcircle then
            add the three triangle edges to the edge buffer
            remove the triangle from the triangle list
         endif
      endfor
      delete all doubly specified edges from the edge buffer
         this leaves the edges of the enclosing polygon only
      add to the triangle list all triangles formed between the point 
         and the edges of the enclosing polygon
   endfor
   remove any triangles from the triangle list that use the supertriangle vertices
   remove the supertriangle vertices from the vertex list
end

算法伪代码
input: 顶点列表(vertices)                       //vertices为外部生成的随机或乱序顶点列表
output:已确定的三角形列表(triangles)
    初始化顶点列表
    创建索引列表(indices = new Array(vertices.length))    //indices数组中的值为0,1,2,3,......,vertices.length-1
    基于vertices中的顶点x坐标对indices进行sort           //sort后的indices值顺序为顶点坐标x从小到大排序(也可对y坐标,本例中针对x坐标)
    确定超级三角形
    将超级三角形保存至未确定三角形列表(temp triangles)
    将超级三角形push到triangles列表
    遍历基于indices顺序的vertices中每一个点            //基于indices后,则顶点则是由x从小到大出现
      初始化边缓存数组(edge buffer)
      遍历temp triangles中的每一个三角形
        计算该三角形的圆心和半径
        如果该点在外接圆的右侧
          则该三角形为Delaunay三角形,保存到triangles
          并在temp里去除掉
          跳过
        如果该点在外接圆外(即也不是外接圆右侧)
          则该三角形为不确定                      //后面会在问题中讨论
          跳过
        如果该点在外接圆内
          则该三角形不为Delaunay三角形
          将三边保存至edge buffer
          在temp中去除掉该三角形
      对edge buffer进行去重
      将edge buffer中的边与当前的点进行组合成若干三角形并保存至temp triangles中
    将triangles与temp triangles进行合并
    除去与超级三角形有关的三角形
end

Watson算法的基本步骤是:
1、构造一个超级三角形,包含所有散点,放入三角形链表。
2、将点集中的散点依次插入,在三角形链表中找出外接圆包含插入点的三角形(称为该点的影响三角形),删除影响三角形的公共边,将插入点同影响三角形的全部顶点连接起来,完成一个点在Delaunay三角形链表中的插入。
3、根据优化准则对局部新形成的三角形优化。将形成的三角形放入Delaunay三角形链表。
4、循环执行上述第2步,直到所有散点插入完毕。</span>

本节到此结束,欲知后事如何,请看下回分解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值