⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 凸包doc.cpp

📁 凸包问题~基于mfc的实现。界面粗糙点
💻 CPP
字号:
// 凸包Doc.cpp : implementation of the CMyDoc class
//

#include "stdafx.h"
#include "凸包.h"

#include "凸包Doc.h"
#include <math.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMyDoc

IMPLEMENT_DYNCREATE(CMyDoc, CDocument)

BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
	//{{AFX_MSG_MAP(CMyDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyDoc construction/destruction

CMyDoc::CMyDoc()
{
	// TODO: add one-time construction code here

}

CMyDoc::~CMyDoc()
{
}

BOOL CMyDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CMyDoc serialization

void CMyDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CMyDoc diagnostics

#ifdef _DEBUG
void CMyDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CMyDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMyDoc commands
Node::Node(long double p_x,long double p_y)
{
	x=p_x;
	y=p_y;
}
Node::~Node()
{

}
long double Node::X()
{
	return x;
}
long double Node::Y()
{
	return y;
}
Link::Link()
{
	now=LeftEnd=RightEnd=0;
	num=0;
	length=0;
}
Link::~Link()
{
	
}
Node& Link::Now()
{
	return *now;
}
bool Link::Find(int k)         //now指向第k个元素 1,2,3,4
{
	if (k<1)return false;
	Node *find=LeftEnd;
	int index=1;
	while (index<k&&find!=RightEnd)
	{
		find=find->right;
		index++;
	}
	if (find) 
	{
		now=find;
		return true;
	}
	return false;
}
Link& Link::Insert(int k,long double x,long double y)///k=0,1,2,3,4插入后成为第k+1个数
{
	Node *mid=new Node(x,y);
	if (LeftEnd==0&&RightEnd==0)
	{
		if (k==0)
		{
			RightEnd=LeftEnd=mid;
		    LeftEnd->left=RightEnd;
	        RightEnd->right=LeftEnd;
	    	mid->left=LeftEnd;
	    	mid->right=RightEnd;
	    	LeftEnd->right=mid;
	    	RightEnd->left=mid;
	    	now=mid;
		}
		else if(k==1&&now!=0)
		{	
			{
				mid->left=now;
			    mid->right=now->right;
	        	now->right->left=mid;
    		    now->right=mid;
    			if (now==RightEnd)
				{
					RightEnd=mid;
				}
				now=mid;
			}
		}
	}
	else if(Find(k))
		{	
			{
				mid->left=now;
			    mid->right=now->right;
	        	now->right->left=mid;
    		    now->right=mid;
    			if (now==RightEnd)
				{
					RightEnd=mid;
				}
				now=mid;
			}
		}
	length++;
	return *this;
}
Link& Link::Delete(int k)//k=1,2,3,4  删除第k个元素,now指向后一个
{
	if (Find(k))
	{
		Node *p=now->right;
		now->left->right=now->right;
		now->right->left=now->left;
		delete now;
		now=p;
		if (k==1)
		{
			LeftEnd=now;
		}
		else if (now==LeftEnd)
		{
			RightEnd=LeftEnd->left;
		}
	}
	length--;
	return *this;
}
int Link::Num(Node &x)
{
	Node *p=LeftEnd;
	int index=1;
	while (p!=&x)
	{
		index++;
		p=p->right;
	}
	return index;
}
/////////////////////////////////////////////
long double Rad(long double x0,long double y0,long double x,long double y)//(x0,y0)为基准点,(x,y)为所求点
{
	if (x==x0&&y!=y0)
	{
		return 3.1415926/2;
	}
	else if (y==y0)
	{
		return 0;
	}
	else
	{
		long double mid=atan((y0-y)/(x-x0));
		if(mid<0) mid=mid+3.1415926;
		return mid;

	}
}
///////////////////////////////////////////////
bool Link::IsLine()
{
	Node *mid=LeftEnd;
	long double rad=Rad(LeftEnd->x,LeftEnd->y,mid->right->x,mid->right->y);
	long double mid_rad;
	for (;mid->right!=LeftEnd;)
	{
		mid=mid->right;
		mid_rad=Rad(LeftEnd->x,LeftEnd->y,mid->x,mid->y);
		if(rad!=mid_rad)
			return false;
	}
	return true;
}
//////////////////////////////////////////////
Node& Link::Find_Node_max_y()
{
	Node *mid=LeftEnd->right;
	Node *max_Node=LeftEnd;
	long double index=LeftEnd->y;
	for (int i=0;i<length;i++)
	{
		if(index<mid->y)
		{
			index=mid->y;
			max_Node=mid;
		}	
		mid=mid->right;
	}
	return *max_Node;

}
/////////////////////////////////////////////
Node& Link::Find_Node_min_x()
{
	Node *mid=LeftEnd->right;
	Node *min_Node=LeftEnd;
	long double index=LeftEnd->x;
	for (int i=0;i<length;i++)
	{
		if(index>mid->x)
		{
			index=mid->x;
			min_Node=mid;
		}	
		mid=mid->right;
	}
	return *min_Node;
}
//////////////////////////////////////////////
long double Point_length(long double x0,long double y0,long double x,long double y)
{
	return sqrt(pow(x-x0,2)+pow(y-y0,2));
}
///////////////////////////////////////////
void Link::Line_Delete()
{
	Node *m_x=&Find_Node_min_x();
	Node *m_y=&Find_Node_max_y();
	Node *mid=LeftEnd;
	Node *p=mid;
	for (;mid->right!=LeftEnd;)
	{
		if (mid!=m_x&&mid!=m_y)
		{
			p=mid->right;
			Delete(Num(*mid));
			mid=p;
		}
		else
		{
			mid=mid->right;
		}
	}
}
////////////////////////////////////////////////
void swap(long double& x, long double& y)
{
	long double mid;
	mid=x,x=y,y=mid;
}
/////////////////////////////////////////////
void Link::PaiXu()
{
	Node *p_y=&Find_Node_max_y();
	Node *mid=LeftEnd;
	long double f=0;
	long double l_rad,n_rad;
	for (int i=0;i<length;i++)
	{
		mid=LeftEnd;
		for (int j=length-i-1;j>0;j--)
		{
			l_rad=Rad(p_y->x,p_y->y,mid->x,mid->y);
			n_rad=Rad(p_y->x,p_y->y,mid->right->x,mid->right->y);
			if (l_rad>n_rad)
			{
				swap(mid->x,mid->right->x);
				swap(mid->y,mid->right->y);
				p_y=&Find_Node_max_y();
			}
			if (l_rad==n_rad)
			{
				if (Point_length(p_y->x,p_y->y,mid->x,mid->y)>Point_length(p_y->x,p_y->y,mid->right->x,mid->right->y))
				{
					swap(mid->x,mid->right->x);
				    swap(mid->y,mid->right->y);
				    p_y=&Find_Node_max_y();
				}
			}
			mid=mid->right;
		}
	}
}
//////////////////////////////////////////////
long double Link::Tp_rad(Node last,Node mid,Node next)
{
	long double fi_se,se_th;
	fi_se=Rad(last.x,last.y,mid.x,mid.y);
	se_th=Rad(mid.x,mid.y,next.x,next.y);
	long double sub;
	sub=fi_se-se_th;
	if(sub<0) sub=-sub;
	if (last.y>mid.y&&next.y<mid.y)
	{
		if (mid.x>=(mid.y-last.y)*(next.x-last.x)/(next.y-last.y)+last.x)
		{
			return 3.1415926+sub;
		}
		else if (mid.x<(mid.y-last.y)*(next.x-last.x)/(next.y-last.y)+last.x)
		{
			return 3.1415926-sub;
		}

	}
	else if (last.y<mid.y&&next.y>mid.y)
	{
		if (mid.x>=(mid.y-last.y)*(next.x-last.x)/(next.y-last.y)+last.x)
		{
			return 3.1415926-sub;
		}
		else if (mid.x<(mid.y-last.y)*(next.x-last.x)/(next.y-last.y)+last.x)
		{
			return 3.1415926+sub;
		}
		
	}/////////////////////////////////////////
	else if (last.y>mid.y&&next.y>mid.y)
	{
		if (next.x<mid.x&&mid.x<last.x)
		{
			return 2*3.1415926-sub;
		}
		else if (next.x>mid.x&&mid.x>last.x)
		{
			return sub;
		}
		else if (next.x<mid.x&&mid.x>last.x||next.x>mid.x&&mid.x<last.x)
		{
			if (fi_se<se_th)
			{
				return sub;
			}
			else if (fi_se>se_th)
			{
				return 2*3.1415926-sub;
			}
			else return 0;
		}
		
	}
	else if (last.y<mid.y&&next.y<mid.y)
	{
		if (next.x<mid.x&&mid.x<last.x)
		{
			return sub;
		}
		else if (next.x>mid.x&&mid.x>last.x)
		{
			return 2*3.1415926-sub;
		}
		else if (next.x<mid.x&&mid.x>last.x||next.x>mid.x&&mid.x<last.x)
		{
			if (fi_se<se_th)
			{
				return sub;
			}
			else if (fi_se>se_th)
			{
				return 2*3.1415926-sub;
			}
			else return 0;
		}
	}
	else if (last.y==mid.y)
	{
		if (last.x>mid.x)
		{
			if (next.y>last.y)
			{
				return 2*3.1415926-sub;
			}
			else if (next.y<last.y)
			{
				return sub;
			}
			else return 0;
			 	
		}
		else if (last.x<mid.x)
		{
			if (next.y>last.y)
			{
				return sub;
			}
			else if (next.y<last.y)
			{
				return 2*3.1415926-sub;
			}
			else return 0;			
		}
	}
	else if (next.y==mid.y)
	{
		if (next.x>mid.x)
		{
			if (last.y>next.y)
			{
				return sub;
			}
			else if (last.y<next.y)
			{
				return 2*3.1415926-sub;
			}
			else return 0;
		}
		else if (next.x<mid.x)
		{
			if (last.y>next.y)
			{
				return 2*3.1415926-sub;
			}
			else if (last.y<next.y)
			{
				return sub;
			}
			else return 0;
		}
	}
}
/////////////////////////////////////////////////
void Link::Delete_NN()
{
	Node *max_y=&Find_Node_max_y();
	Node *mid=LeftEnd;
	for(;mid->right!=LeftEnd;) 
	{
		long double mid_rad=Tp_rad(*mid,*mid->right,*mid->right->right);
		if (mid_rad<=3.1415926)
		{
			//Node *p=;
			Delete(Num(*(mid->right)));
			mid=mid->left;
		}
		else
		{
			mid=mid->right;
		}
	} 
	
}
/////////////////////////////////////////////////
Link& Link::TuBao()
{
	if (length<3)
	{
		return *this;
	}
	if (IsLine())
	{
		Line_Delete();
		return *this;
	}
	PaiXu();
	Delete_NN();
	return *this;
}
int Link::Length()
{
	return length;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -