📄 tindoc.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 + -