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

📄 tindoc.cpp

📁 并行TIN生成算法, 基于DeWall算法理论实现
💻 CPP
字号:
// TinDoc.cpp : implementation of the CTinDoc class
//

#include "stdafx.h"
#include "TinApp.h"

#include "TinDoc.h"

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

/////////////////////////////////////////////////////////////////////////////
// CTinDoc

IMPLEMENT_DYNCREATE(CTinDoc, CDocument)

BEGIN_MESSAGE_MAP(CTinDoc, CDocument)
	//{{AFX_MSG_MAP(CTinDoc)
	ON_COMMAND(ID_ZOOM_ALL, OnZoomAll)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(ID_BUILD_TIN, OnBuildTIN)
	ON_UPDATE_COMMAND_UI(ID_BUILD_TIN, OnUpdateBuildTIN)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTinDoc construction/destruction

CTinDoc::CTinDoc()
{
	m_prs.num = 0;	m_prs.prs = 0;	m_TN = 0;	m_TT = 0;	m_RN = 0;	m_TR = 0;

	m_lx = m_rx = 0;	m_by = m_ty = 0;	m_xs = m_ys = 0;

	m_oTan = new CTcsTan2;
}

CTinDoc::~CTinDoc()
{
	if (m_prs.num)
	{
		for (long i = 0; i < m_prs.num; i++)
		{
			delete []m_prs.prs[i].pts;
		}
		delete []m_prs.prs;
		m_prs.num = 0;
	}

	if (m_TT)
		delete []m_TT;
	m_TT = 0;

	if (m_TR)
		delete []m_TR;
	m_TR = 0;

	if (m_oTan)
		delete m_oTan;
	m_oTan = 0;
}

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

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

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CTinDoc serialization

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

/////////////////////////////////////////////////////////////////////////////
// CTinDoc diagnostics

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

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

/////////////////////////////////////////////////////////////////////////////
// CTinDoc commands

void CTinDoc::SetViewportExt(long cw, long ch)
{
	m_rx = m_lx + cw * m_xs;
	m_by = m_ty - ch * m_ys;
	m_cw = cw;	m_ch = ch;
}

void CTinDoc::Move(CDC *pDC, long mx, long my)
{
	double dx = mx * m_xs;
	double dy = my * m_ys;

	m_lx += dx;	m_rx += dx;
	m_by += dy;	m_ty += dy;

//	m_Draw.Draw(&m_Tset, &m_Data, pDC->m_hDC, m_lx, m_rx, m_by, m_ty, m_cw, m_ch);
	DrawPTS(pDC->m_hDC, m_lx, m_rx, m_by, m_ty, m_xs, m_ys);
	DrawTIN(pDC->m_hDC, m_lx, m_rx, m_by, m_ty, m_xs, m_ys);
}

void CTinDoc::MoveTo(CDC *pDC, double x, double y)
{
	double dx = x - (m_lx + m_rx) / 2;
	double dy = y - (m_by + m_ty) / 2;

	m_lx += dx;	m_rx += dx;
	m_by += dy;	m_ty += dy;

//	m_Draw.Draw(&m_Tset, &m_Data, pDC->m_hDC, m_lx, m_rx, m_by, m_ty, m_cw, m_ch);
	DrawPTS(pDC->m_hDC, m_lx, m_rx, m_by, m_ty, m_xs, m_ys);
	DrawTIN(pDC->m_hDC, m_lx, m_rx, m_by, m_ty, m_xs, m_ys);
}

void CTinDoc::Zoom(CDC *pDC, long mx, long my, double xs, double ys, BOOL bZoom)
{
	if (xs <= 0 || ys <= 0)	return;
	///////////////////////////////////////////

	double dx = mx * m_xs;
	double dy = my * m_ys;
	double cx = (m_lx + m_rx) / 2 - dx;
	double cy = (m_ty + m_by) / 2 - dy;

	if (bZoom) // zoom in
	{
		m_xs /= xs;
		m_ys /= ys;
	}
	else
	{
		m_xs *= xs;
		m_ys *= ys;
	}

	double dw = m_cw * m_xs / 2;
	double dh = m_ch * m_ys / 2;

	m_lx = cx - dw;	m_rx = cx + dw;
	m_by = cy - dh;	m_ty = cy + dh;
	///////////////////////////////////////////

	Move(pDC, 0, 0);
}

void CTinDoc::OnZoomAll() 
{
	if (m_cw == 0 || m_ch == 0)
		return;

	long bFind = 0;
	if (m_prs.num)
	{
		for (long i = 0; i < m_prs.num; i++)
		{
			if (i == 0)
			{
				m_lx = m_prs.prs[i].mix;	m_rx = m_prs.prs[i].max;
				m_by = m_prs.prs[i].miy;	m_ty = m_prs.prs[i].may;
			}
			else
			{
				if (m_lx > m_prs.prs[i].mix)	m_lx = m_prs.prs[i].mix;
				if (m_rx < m_prs.prs[i].max)	m_rx = m_prs.prs[i].max;
				if (m_by > m_prs.prs[i].miy)	m_by = m_prs.prs[i].miy;
				if (m_ty < m_prs.prs[i].may)	m_ty = m_prs.prs[i].may;
			}
		}
		bFind = 1;
	}

	if (bFind)
	{
		double xs = (m_rx - m_lx) / m_cw;
		double ys = (m_ty - m_by) / m_ch;
		if (xs < ys)
			m_xs = m_ys = ys;
		else
			m_xs = m_ys = xs;

		double dw = m_cw * m_xs / 2;
		double dh = m_ch * m_ys / 2;
		double cx = (m_rx + m_lx) / 2;
		double cy = (m_ty + m_by) / 2;
		
		m_lx = cx - dw;	m_rx = cx + dw;
		m_by = cy - dh;	m_ty = cy + dh;
		
		UpdateAllViews(NULL);
	}
}

void CTinDoc::OnFileOpen() 
{
	CFileDialog fdlg(1, _T("PTS"), 0, OFN_HIDEREADONLY, _T("点数据文件(*.PTS)|*.PTS|"), 0);
			
	if (fdlg.DoModal() == IDOK)
	{
		CString strExt, strTmp;

		strTmp = fdlg.GetPathName();	strTmp.MakeUpper();
		strExt = strTmp.Right(strTmp.GetLength() - strTmp.ReverseFind('.') - 1);
		if (strExt == _T("PTS"))
		{
			if (!OpenPTS(strTmp))
			{
				AfxMessageBox("打开点数据文件失败!");
				UpdateAllViews(0);
				return;
			}
		}

		UpdateViews();
	}
}

void CTinDoc::UpdateViews(void)
{
	if (m_lx == m_rx || m_by == m_ty)
		OnZoomAll();
	else
		UpdateAllViews(0);
}

long CTinDoc::OpenPTS(CString ptsPath)
{
	if (m_prs.num)
	{
		for (long i = 0; i < m_prs.num; i++)
		{
			delete []m_prs.prs[i].pts;
		}
		delete []m_prs.prs;
	}
	m_prs.num = 0;	m_prs.prs = 0;
	if (m_TT)
		delete []m_TT;
	m_TT = 0;	m_TN = 0;
	////////////////////////////////////////////////

	long dim, num;
	char buf[300];
	CString tmp1, tmp2;

	FILE *in = 0;
	::fopen_s(&in, ptsPath, "r");
	if (in == 0)	return 0;

	memset(buf, 0, 300);	fgets(buf, 300, in);
	tmp1 = buf;	tmp1.MakeUpper();	tmp1.TrimLeft();	tmp1.TrimRight();
	memset(buf, 0, 300);	memcpy(buf, tmp1, tmp1.GetLength());
	if (tmp1.Find("NUM_2D=", 0) == 0)
	{
		dim = 2;	sscanf_s(buf, "NUM_2D=%d\n", &num);
	}
	else if (tmp1.Find("NUM_3D=", 0) == 0)
	{
		dim = 3;	sscanf_s(buf, "NUM_3D=%d\n", &num);
	}
	else
	{	fclose(in);		return 0;	}

	if (num <= 0)
	{	fclose(in);		return 0;	}
	////////////////////////////////////////////////

	double x, y, z, minx, miny, minz, maxx, maxy, maxz;

	if (dim == 2)
	{
		POINT2D *pts = new POINT2D[num];
		if (pts == 0)
		{	fclose(in);		return 0;	}

		long cnt = 0;
		for (long i = 0; i < num; i++)
		{
			if (feof(in))
				break;
			fscanf_s(in, "%lf,%lf", &x, &y);
			if (i == 0)
			{	minx = maxx = x;	miny = maxy = y;	}
			else
			{
				if		(minx > x)	minx = x;
				else if (maxx < x)	maxx = x;
				if		(miny > y)	miny = y;
				else if (maxy < y)	maxy = y;
			}
			pts[i].x = x;
			pts[i].y = y;
			cnt++;
		}
		fclose(in);
		if (cnt == 0)
		{	delete []pts;	return 1;	}
		if (cnt != num)
			num = cnt;

		PART2D *prs = new PART2D[1];
		prs[0].mix = minx;	prs[0].miy = miny;
		prs[0].max = maxx;	prs[0].may = maxy;
		prs[0].num = num;	prs[0].pts = pts;
		m_prs.num = 1;	m_prs.prs = prs;
	}
	else
	{
		POINT2D *pts = new POINT2D[num];
		if (pts == 0)
		{	fclose(in);		return 0;	}

		long cnt = 0;
		for (long i = 0; i < num; i++)
		{
			if (feof(in))
				break;
			fscanf_s(in, "%lf,%lf,%lf", &x, &y, &z);
			if (i == 0)
			{	minx = maxx = x;	miny = maxy = y;	minz = maxz = z;	}
			else
			{
				if		(minx > x)	minx = x;
				else if (maxx < x)	maxx = x;
				if		(miny > y)	miny = y;
				else if (maxy < y)	maxy = y;
				if		(minz > z)	minz = z;
				else if (maxz < z)	maxz = z;
			}
			pts[i].x = x;
			pts[i].y = y;
			cnt++;
		}
		fclose(in);
		if (cnt == 0)
		{	delete []pts;	return 1;	}
		if (cnt != num)
			num = cnt;

		PART2D *prs = new PART2D[1];
		prs[0].mix = minx;	prs[0].miy = miny;
		prs[0].max = maxx;	prs[0].may = maxy;
		prs[0].num = num;	prs[0].pts = pts;
		m_prs.num = 1;	m_prs.prs = prs;

	}

	return 1;
}

void CTinDoc::DrawPTS(HDC hdc, double lx, double rx, double by, double ty, double xs, double ys)
{
	POINT pt;
	double dx, dy;
	long i, k, x, y;

	for (i = 0; i < m_prs.num; i++)
	{
		POINT2D *pts = m_prs.prs[i].pts;
		for (k = 0; k < m_prs.prs[i].num; k++)
		{
			dx = pts[k].x - lx;
			if (dx < 0)
				continue;
			dy = ty - pts[k].y;
			if (dy < 0)
				continue;
			if (pts[k].x - rx > 0)
				continue;
			if (pts[k].y - by < 0)
				continue;
			x = long(dx / xs);
			y = long(dy / ys);
			
			MoveToEx(hdc, x - 2, y, &pt);
			LineTo(hdc, x + 3, y);
			MoveToEx(hdc, x, y - 2, &pt);
			LineTo(hdc, x, y + 3);
		}
	}
}

void CTinDoc::DrawTIN(HDC hdc, double lx, double rx, double by, double ty, double xs, double ys)
{
	if (!m_prs.num)
		return;

	CString tx;

	POINT pt;
	double dx, dy;
	POINT2D *p0, *p1, *p2, ce;
	POINT2D *ppts = m_prs.prs[0].pts;
	long i, x1, y1, x2, y2, x3, y3, r;

	long sw = 1;
	// 绘制三角形
	if (sw)
	{
		for (i = 0; i < m_TN; i++)
		{
			p0 = ppts + m_TT[i].pid[0];
			p1 = ppts + m_TT[i].pid[1];
			p2 = ppts + m_TT[i].pid[2];
			dx = p0->x - lx;	dy = ty - p0->y;
			x1 = long(dx / xs);	y1 = long(dy / ys);
			MoveToEx(hdc, x1, y1, &pt);
			dx = p1->x - lx;	dy = ty - p1->y;
			x2 = long(dx / xs);	y2 = long(dy / ys);
			LineTo(hdc, x2, y2);
			dx = p2->x - lx;	dy = ty - p2->y;
			x3 = long(dx / xs);	y3 = long(dy / ys);
			LineTo(hdc, x3, y3);

			LineTo(hdc, x1, y1);
			// 绘制方向
//			MoveToEx(hdc, x3, y3, &pt);	LineTo(hdc, (x1 + x2) / 2, (y1 + y2) / 2);

//			tx.Format("%d", i);	TextOut(hdc, (x1 + x2) / 2, (y1 + y2) / 2, tx, strlen(tx));

			ComCen2((double*)p0, (double*)p1, (double*)p2, (double*)&ce);
			dx = ce.x - lx;	dy = ty - ce.y;
			x1 = long(dx / xs);	y1 = long(dy / ys);
			dx = p1->x - ce.x;	dy = p1->y - ce.y;
			dx = sqrt(dx * dx + dy * dy);
			r = long(dx / xs);
			//		MoveToEx(hdc, x, y, &pt);	AngleArc(hdc, x, y, r, 0, 360);
		}
	}

	// 绘制隔离活动边
	if (!sw)
	{
		// 绘制隔离边和圈
		for (i = 0; i < m_RN; i++)
		{
			// 绘制边
			CTcsHL *ASL = m_TR[i].ASL;
			TIN_S *S = (TIN_S*)ASL->GetHead();
			while (S)
			{
				p0 = ppts + S->sid[0];
				p1 = ppts + S->eid[0];
				dx = p0->x - lx;	dy = ty - p0->y;
				x1 = long(dx / xs);	y1 = long(dy / ys);
				MoveToEx(hdc, x1, y1, &pt);
				dx = p1->x - lx;	dy = ty - p1->y;
				x2 = long(dx / xs);	y2 = long(dy / ys);
				LineTo(hdc, x2, y2);
				// 标记
				tx.Format("%d", i);	TextOut(hdc, (x1 + x2) / 2, (y1 + y2) / 2, tx, strlen(tx));

				S = (TIN_S*)ASL->GetNext();
			}
			// 绘制圈
			TIN_G *G = m_TR[i].G;
			dx = G->bnd[0] - lx;	dy = ty - G->bnd[1];
			x1 = long(dx / xs);		y1 = long(dy / ys);
			MoveToEx(hdc, x1, y1, &pt);
			dx = G->bnd[2] - lx;	dy = ty - G->bnd[1];
			x2 = long(dx / xs);		y2 = long(dy / ys);
			LineTo(hdc, x2, y2);
			dx = G->bnd[2] - lx;	dy = ty - G->bnd[3];
			x3 = long(dx / xs);		y3 = long(dy / ys);
			LineTo(hdc, x3, y3);
			dx = G->bnd[0] - lx;	dy = ty - G->bnd[3];
			x3 = long(dx / xs);		y3 = long(dy / ys);
			LineTo(hdc, x3, y3);
			LineTo(hdc, x1, y1);
		}
	}
}

#include "DlgBuildTIN.h"
void CTinDoc::OnBuildTIN() 
{
	CDlgBuildTIN dlg;

	dlg.Init(m_prs.prs[0].pts, m_prs.prs[0].num, 2, m_oTan, &m_TT, &m_TN, &m_TR, &m_RN);

	dlg.DoModal();
}

void CTinDoc::OnUpdateBuildTIN(CCmdUI* pCmdUI) 
{
	if (m_prs.num)	pCmdUI->Enable(1);
	else			pCmdUI->Enable(0);
}

// 计算外接圆心
void CTinDoc::ComCen2(double *p1, double *p2, double *p3, double *p4)
{
	// 11(+|-), 12(*), 2(/)
	double dx21 = p2[0] - p1[0];
	double dy21 = p2[1] - p1[1];
	double xy21 = dx21 * dx21 + dy21 * dy21;

	double dx31 = p3[0] - p1[0];
	double dy31 = p3[1] - p1[1];
	double xy31 = dx31 * dx31 + dy31 * dy31;

	double top1 =   dy21 * xy31 - dy31 * xy21;
	double top2 = - dx21 * xy31 + dx31 * xy21;
	double deno =   dy21 * dx31 - dy31 * dx21;

	p4[0] = p1[0] + 0.5 * top1 / deno;
	p4[1] = p1[1] + 0.5 * top2 / deno;
}

⌨️ 快捷键说明

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