📄 dataprodoc.cpp
字号:
// dataproDoc.cpp : CdataproDoc 类的实现
//
#include "stdafx.h"
#include "datapro.h"
#include "YuzhiDlg.h"
#include "dataproDoc.h"
#include ".\dataprodoc.h"
#include "fpoint.h"
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CdataproDoc
IMPLEMENT_DYNCREATE(CdataproDoc, CDocument)
BEGIN_MESSAGE_MAP(CdataproDoc, CDocument)
ON_COMMAND(ID_DATA_YASUO, OnDataPress)
END_MESSAGE_MAP()
// CdataproDoc 构造/析构
CdataproDoc::CdataproDoc()
{
// TODO: 在此添加一次性构造代码
}
CdataproDoc::~CdataproDoc()
{
}
BOOL CdataproDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: 在此添加重新初始化代码
// (SDI 文档将重用该文档)
return TRUE;
}
// CdataproDoc 序列化
void CdataproDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: 在此添加存储代码
}
else
{
// TODO: 在此添加加载代码
}
}
// CdataproDoc 诊断
#ifdef _DEBUG
void CdataproDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CdataproDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
// CdataproDoc 命令
BOOL CdataproDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
strPath=lpszPathName;
ReadSourceFile();
return TRUE;
}
bool CdataproDoc::ReadSourceFile()
{
int num=0;
CStdioFile temFile;
CFpoint pt;
CString line;//用于存储读取一行数据
if( !temFile.Open(strPath, CFile::modeRead | CFile::typeText) ) //error
{
AfxMessageBox("读取源文件失败!\n");
return false;
}
int i=-1;
CLineSet temp;
while(temFile.ReadString(line) )
{
if((line!="END"||line!="end")&&(line.GetLength()<6))
{
num=0;
}
if(line.GetLength()>8&&(line!="END"||line!="end"))
{
pt = GetPoints(line);
temp.fPoint.Add(pt);
}
if((line=="END"||line=="end"))
{
num++;
if(num>1)
break;
lineset.Add(temp);
temp.fPoint.RemoveAll();
}
}
temFile.Close();
return true;
}
CFpoint CdataproDoc::GetPoints(CString line)//解析原数据文件
{
CFpoint temPt;
CString temLine = "";
temLine = line.Left(line.Find(','));
temPt.y = atof(temLine);
temLine = line.Right(line.GetLength() - line.ReverseFind(',')- 1);
temPt.x = atof(temLine);
return temPt;
}
void CdataproDoc::OnDataPress()
{
// TODO: 在此添加命令处理程序代码
CThredsholdDlg dlg;
if(IDOK==dlg.DoModal())
{
double Thredshold=dlg.Thredshold;
int n=lineset.GetSize();
for(int i=0;i<n-1;i++)
{
CArray<CFpoint,CFpoint> temp;
temp.Add(lineset[i].fPoint[0]);
int ln=lineset[i].fPoint.GetSize();
Douglas_Peuker(i,temp,0,(ln-1),Thredshold);
temp.Add(lineset[i].fPoint[(ln-1)]);
lineset[i].fPoint.RemoveAll();
for(int j=0;j<temp.GetSize();j++)
{
lineset[i].fPoint.Add(temp[j]);
}
}
UpdateAllViews(NULL);
}
}
void CdataproDoc::Douglas_Peuker(int num,CArray<CFpoint,CFpoint> &result_ppts,int begin,int end,double len)
{
if (abs(begin-end)<2)
return;
double dbLen = 0.0;
int index = FindFurthestPt(num,begin, end, dbLen);
if (dbLen >len)
{
Douglas_Peuker(num,result_ppts,begin, index, len);
result_ppts.Add(lineset[num].fPoint[index]);
Douglas_Peuker(num,result_ppts,index, end, len);
}
}
int CdataproDoc::FindFurthestPt(int num,int begin,int end,double &len)
{
int index=begin +1;
len = PointLine(num,begin,end, index);
for (int s = index+1; s<end-1; s++)
{
double dbTemp = PointLine(num,begin, end, s);
if (dbTemp >len)
{
len = dbTemp;
index = s;
}
}
return index;
}
double CdataproDoc::PointLine(int num,int begin,int end,int s)
{
double a,b,c;
//计算三条边的距离
a=(double)sqrt((lineset[num].fPoint[begin].x-lineset[num].fPoint[s].x)*(lineset[num].fPoint[begin].x-lineset[num].fPoint[s].x)+(lineset[num].fPoint[begin].y-lineset[num].fPoint[s].y)*(lineset[num].fPoint[begin].y-lineset[num].fPoint[s].y));
if(a==0.0)
return 0.0;
b=(double)sqrt((lineset[num].fPoint[end].x-lineset[num].fPoint[s].x)*(lineset[num].fPoint[end].x-lineset[num].fPoint[s].x)+(lineset[num].fPoint[end].y-lineset[num].fPoint[s].y)*(lineset[num].fPoint[end].y-lineset[num].fPoint[s].y));
if(b==0.0)
return 0.0;
c=(double)sqrt((lineset[num].fPoint[end].x-lineset[num].fPoint[begin].x)*(lineset[num].fPoint[end].x-lineset[num].fPoint[begin].x)+(lineset[num].fPoint[end].y-lineset[num].fPoint[begin].y)*(lineset[num].fPoint[end].y-lineset[num].fPoint[begin].y));
//如果是一个点直接返回距离
if(c==0.0) return a;
double p=(a+b+c)/2;
double size=sqrt(p*(p-a)*(p-b)*(p-c));//海伦公式
double d= (2*size/c);//得出到直线得距离
return d;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -