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

📄 trianglecreator.cpp

📁 三角网的计算与绘制
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "StdAfx.h"
#include "TriangleCreator.h"
#include <float.h>
#include <math.h>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CBorder::CBorder()
{
	m_iTriangleIndex=-1;
	m_byteBorderIndex=255;
	m_byteFlag=0;
}
void CBorder::ClearFlag()
{
	m_byteFlag=0;
}
void CBorder::SetFlag(BYTE byteFlag)
{
	m_byteFlag=byteFlag;
}
BYTE CBorder::GetFlag()
{
	return m_byteFlag;
}
BOOL CBorder::IsValid()
{
	return m_iPointIndex0!=INT_MAX && m_iPointIndex1!=INT_MAX;
}
void CBorder::Reverse()
{
	int iPointIndex=m_iPointIndex0;
	m_iPointIndex0=m_iPointIndex1;
	m_iPointIndex1=iPointIndex;
}
int CBorder::GetPointIndex(BYTE byteIndex)
{
	if(byteIndex==0)
		return m_iPointIndex0;
	else
		return m_iPointIndex1;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CTriangle::CTriangle()
{
	m_byteFlag=0;

}
void CTriangle::ClearNeighbors()
{
	m_Border[0].m_iTriangleIndex=-1;
	m_Border[1].m_iTriangleIndex=-1;
	m_Border[2].m_iTriangleIndex=-1;
}
void CTriangle::ClearNeighbor(BYTE byteBorderIndex)
{
	m_Border[byteBorderIndex].m_iTriangleIndex=-1;
}
void CTriangle::SetNeighbor(BYTE byteBorderIndex,int iNeighborTriangleIndex,BYTE byteNeighborBorderIndex1)
{
	m_Border[byteBorderIndex].m_iTriangleIndex=iNeighborTriangleIndex;
	m_Border[byteBorderIndex].m_byteBorderIndex=byteNeighborBorderIndex1;
}
BOOL CTriangle::IsSameBorder(BYTE byteBorderIndex,CTriangle& triangle,BYTE byteBorderIndex1)
{
	int i0,i1;
	GetBorderPointIndex(byteBorderIndex,i0,i1);

	int j0,j1;
	
	triangle.GetBorderPointIndex(byteBorderIndex1,j0,j1);

	ASSERT(!(i0==j0 && i1==j1));

	return i0==j1 && i1==j0;
}
void CTriangle::ClearBorderFlag()
{
	m_Border[0].ClearFlag();
	m_Border[1].ClearFlag();
	m_Border[2].ClearFlag();
}
void CTriangle::SetBorderFlag(BYTE byteBorderIndex,BYTE byteFlag)
{
	m_Border[byteBorderIndex].SetFlag(byteFlag);
}
BYTE CTriangle::GetBorderFlag(BYTE byteBorderIndex)
{
	return m_Border[byteBorderIndex].GetFlag();
}
CBorder* CTriangle::GetBorder(BYTE byteBorderIndex)
{
	return m_Border+byteBorderIndex;
}
void CTriangle::GetPointIndex(int* piPointIndex)
{
	piPointIndex[0]=m_Border[0].m_iPointIndex0;
	piPointIndex[1]=m_Border[1].m_iPointIndex0;
	piPointIndex[2]=m_Border[2].m_iPointIndex0;
}
int CTriangle::GetPointIndex(BYTE byteNodeIndex)
{
	return m_Border[byteNodeIndex].m_iPointIndex0;
}
void CTriangle::SetPointIndex(BYTE byteNodeIndex,int iPointIndex)
{
	m_Border[byteNodeIndex].m_iPointIndex0=iPointIndex;
	m_Border[(byteNodeIndex+2)%3].m_iPointIndex1=iPointIndex;
}
void CTriangle::GetBorderPointIndex(BYTE byteBorderIndex,int& iPointIndex0,int& iPointIndex1)
{
	iPointIndex0=m_Border[byteBorderIndex].m_iPointIndex0;
	iPointIndex1=m_Border[byteBorderIndex].m_iPointIndex1;
}
void CTriangle::GetNeighbor(BYTE byteBorderIndex,int& iNeighborTriangleIndex,BYTE& byteNeighborBorderIndex)
{
	iNeighborTriangleIndex=m_Border[byteBorderIndex].m_iTriangleIndex;
	byteNeighborBorderIndex=m_Border[byteBorderIndex].m_byteBorderIndex;
}
void CTriangle::SetFlag()
{
	m_byteFlag=1;
}
BOOL CTriangle::GetFlag()
{
	return m_byteFlag>0;
}
void CTriangle::ClearFlag()
{
	m_byteFlag=0;
}
void CTriangle::operator=(CTriangle& triangle)
{
	memcpy(this,&triangle,sizeof(CTriangle));
}

CTriangleCreator::CTriangleCreator()
{

}
CTriangleCreator::~CTriangleCreator()
{

}
void CTriangleCreator::AddPoint(double x,double y)
{
	WPOINT p;
	p.x=x;
	p.y=y;
	m_PointArray.Add(p);
}
int CTriangleCreator::GetPointCount()
{
	return (int)m_PointArray.GetCount();
}
WPOINT* CTriangleCreator::GetPointArray()
{
	return m_PointArray.GetData();
}
void CTriangleCreator::CreateTriangle(double dLimitAngle)
{
	m_TriangleArray.RemoveAll();

	WPOINT* pPointArray=m_PointArray.GetData();
	int iPointCount=(int)m_PointArray.GetSize();

	if(iPointCount<3)
		return;

	double dLimit=cos(dLimitAngle*3.1415926/180.0);

	for(int i=0;i<iPointCount;i++)
		pPointArray[i].flag=0;

	CBorder border;
	CTriangle triangle;

	int index0=-1;
	int index1=-1;

	double d=FLT_MAX;
	for(int i=0;i<iPointCount;i++)
	{
		int k; for(k=i+1;k<iPointCount;k++)
		{
			double dx=pPointArray[k].x-pPointArray[0].x;
			double dy=pPointArray[k].y-pPointArray[0].y;

			double dd=sqrt(dx*dx+dy*dy);
			if(dd<d)
			{
				d=dd;
				index0=i;
				index1=k;
			}
		}
	}

	//先构造一个初始的三角形
	triangle.SetPointIndex(0,index0);
	triangle.SetPointIndex(1,index1);
	triangle.SetPointIndex(2,index0);

	m_TriangleArray.SetSize(iPointCount);
	m_TriangleArray.RemoveAll();

	m_TriangleArray.Add(triangle);

	CArray<CBorder,CBorder> BorderIndexArray;

	border.m_iTriangleIndex=(int)m_TriangleArray.GetSize()-1;
	border.m_byteBorderIndex=0;
	border.m_iPointIndex0=index0;
	border.m_iPointIndex1=index1;
	BorderIndexArray.Add(border);

	border.m_iTriangleIndex=(int)m_TriangleArray.GetSize()-1;
	border.m_byteBorderIndex=1;
	border.m_iPointIndex0=index1;
	border.m_iPointIndex1=index0;
	BorderIndexArray.Add(border);

	WPOINT fp0,fp1;

	int iStartSearchIndex=0;

	//扩充轮廓 
	while(TRUE) 
	{
		int iBorderCount=(int)BorderIndexArray.GetSize();
		int iTriangleCount=(int)m_TriangleArray.GetSize();
		CBorder* pBorderArray=BorderIndexArray.GetData();
		CTriangle* pTriangleArray=m_TriangleArray.GetData();

		double dAngle=FLT_MAX;
		int iBorderIndex=-1;
		int iPointIndex=-1;//新找到的点序号
		int iPointIndex0,iPointIndex1;//原来的点序号

		if(iStartSearchIndex>=iBorderCount) iStartSearchIndex=0;
		int i; for(i=0;i<iBorderCount;i++)
		{
			int ii=i+iStartSearchIndex;
			if(ii>=iBorderCount) ii-=iBorderCount;

			if(pBorderArray[ii].GetFlag()) continue;

			border=pBorderArray[ii];

			pTriangleArray[border.m_iTriangleIndex].GetBorderPointIndex(border.m_byteBorderIndex,iPointIndex0,iPointIndex1);

			ASSERT(iPointIndex0>=0);
			ASSERT(iPointIndex1>=0);

			fp0=pPointArray[iPointIndex0];
			fp1=pPointArray[iPointIndex1];

			double dy=fp1.y-fp0.y;
			double dx=fp1.x-fp0.x;
			double xy=fp0.y*fp1.x-fp0.x*fp1.y;
			double cc=dx*dx+dy*dy;
			double c=sqrt(cc);

			dAngle=FLT_MAX;
			iPointIndex=-1;

			int j; 
			for(j=0;j<iPointCount;j++)
			{
				if(j==iPointIndex0 || j==iPointIndex1) continue;

				if(pPointArray[j].x==FLT_MAX) continue;
				if(pPointArray[j].flag!=0) continue;

				double d=dy*pPointArray[j].x-dx*pPointArray[j].y+xy;
				if(d>=-0.1) continue;//只考虑fp0,fp1左侧的点

				double dxa=pPointArray[j].x-fp1.x;
				double dya=pPointArray[j].y-fp1.y;
				double aa=dxa*dxa+dya*dya;
				double a=sqrt(aa);

				double dxb=pPointArray[j].x-fp0.x;
				double dyb=pPointArray[j].y-fp0.y;
				double bb=dxb*dxb+dyb*dyb;
				double b=sqrt(bb);

				//				ASSERT(aa>0.0 && bb>0.0);

				double cosc;

				if(a==0.0 || b==0.0)
				{
					cosc=-1.0;
				}
				else
					cosc=(aa+bb-cc)/a/b/2.0;

				if(cosc<dAngle)

⌨️ 快捷键说明

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