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

📄 dataprodoc.cpp

📁 道格拉斯数据压缩算法。 算法特征:1.在不扰乱拓扑关系的前提下
💻 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 + -