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

📄 clusterview.cpp

📁 聚类研究
💻 CPP
字号:
// clusterView.cpp : implementation of the CClusterView class
//

#include "stdafx.h"
#include "cluster.h"

#include "clusterDoc.h"
#include "clusterView.h"
#include "input_k.h"

#include "D_Dbscan.h"

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

/////////////////////////////////////////////////////////////////////////////
// CClusterView

IMPLEMENT_DYNCREATE(CClusterView, CView)

BEGIN_MESSAGE_MAP(CClusterView, CView)
//{{AFX_MSG_MAP(CClusterView)
ON_COMMAND(ID_BEGIN_INPUT, OnBeginInput)
ON_COMMAND(ID_BEGIN_END, OnBeginEnd)
ON_COMMAND(ID_BEGIN_KMEANS, OnBeginKmeans)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_UPDATE_COMMAND_UI(ID_BEGIN_END, OnUpdateBeginEnd)
ON_UPDATE_COMMAND_UI(ID_BEGIN_INPUT, OnUpdateBeginInput)
ON_WM_LBUTTONUP()
ON_COMMAND(ID_BEGIN_SHOW, OnBeginShow)
ON_UPDATE_COMMAND_UI(ID_BEGIN_SHOW, OnUpdateBeginShow)
ON_COMMAND(ID_BEGIN_HIDE, OnBeginHide)
ON_UPDATE_COMMAND_UI(ID_BEGIN_HIDE, OnUpdateBeginHide)
ON_COMMAND(ID_BEGIN_SAVE, OnBeginSave)
	ON_COMMAND(ID_BEGIN_DENSE, OnBeginDense)
	ON_COMMAND(ID_BEGIN_DBSCAN, OnBeginDbscan)
	//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClusterView construction/destruction

CClusterView::CClusterView()
{
	// TODO: add construction code here
    count =0;// k = 0;
	binput = false;
	bshowcenter = false;
	showDbscan = false;
	showkm =false;
}

CClusterView::~CClusterView()
{
}

BOOL CClusterView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	
	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CClusterView drawing

void CClusterView::OnDraw(CDC* pDC)
{
	CClusterDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc); 
	count = display();
	CString str;
	if( showkm && km.Cw )
		show();
	if( showDbscan )
		show_Dbscan(Ds.N,Ds.C,Ds.p);

	
	// TODO: add draw code for native data here
}
int CClusterView::display()
{
    int count = 0;
    CString lpszFile = GetPath(); 
	CFileFind  fFind;
	BOOL bSuccess;
	CClientDC dc(this);
	dc.MoveTo(50,50);
	dc.LineTo(600,50);  dc.TextOut(600,42,"〉");
	dc.MoveTo(50,50);
	dc.LineTo(50,370);  dc.TextOut(43,360,"∨");
	bSuccess=fFind.FindFile(lpszFile);
	fFind.Close ();
	if( bSuccess) {
		COleVariant var;	
		var.ChangeType(VT_BSTR, NULL);
		db.Open(lpszFile);
		CDaoRecordset RecSet(&db);
		RecSet.Open(AFX_DAO_USE_DEFAULT_TYPE,"SELECT * FROM points",NULL);
        int x,y;  
		while(!RecSet.IsEOF())	
		{
			RecSet.GetFieldValue("point_X",var);
			x = (int)var.pbstrVal;
			RecSet.GetFieldValue("point_Y",var);
			y = (int)var.pbstrVal;
			CString str;
			str.Format("(%d,%d)",x,y);
			//        dc.TextOut(x,y,"."/*+str*/);  /////////////////显示坐标
			CPen pen1;
			pen1.CreatePen(PS_SOLID,1,RGB(255,255,255));
			dc.Ellipse(x-1,y-1,x+1,y+1);
			count ++;
			RecSet.MoveNext();
		}
		
		RecSet.Close();
		db.Close();
	}
	return count;
	//    else AfxMessageBox("input points");
}

void CClusterView::show()
{
	CClientDC dc(this);
	CString str;
	int i ;
	CPen *pen = new CPen[km.Cl_k];
	
	//    dc.SetTextColor(arColors[7]);
	CPen pe1,pe2;
	pe1.CreatePen(PS_SOLID,1,RGB(0,0,0));
	pe2.CreatePen(PS_SOLID,1,RGB(255,255,255));
	dc.SelectObject(&pe2);
	dc.Rectangle(600,60,750,600);
	dc.SelectObject(&pe1);
	dc.Rectangle(600,60,750,30*(km.Cl_k+3));
	dc.TextOut(650,70,"result");
	for( i=0 ; i < km.Cl_k; i ++)
	{
		dc.SetTextColor(arColors[ i % 11 ]);
		pen[i].CreatePen(PS_SOLID,1,arColors[ i%11 ] );
		CPen *pOldPen = dc.SelectObject(&pen[i]);
		for(int j = 0;j < km.Cw[i].count ; j++ )
		{
			//			dc.TextOut(km.p[ km.Cw[i].num[j] ].x, km.p[ km.Cw[i].num[j] ].y,".");
			dc.Ellipse(km.p[ km.Cw[i].num[j] ].x -1,km.p[ km.Cw[i].num[j] ].y-1,
				km.p[ km.Cw[i].num[j] ].x+1,km.p[ km.Cw[i].num[j] ].y+1);
		}
		str.Format("Center(%d,%d) :%d",km.Cw[i].w.x,km.Cw[i].w.y,km.Cw[i].count);
		dc.TextOut(605,30*(i+3),str); 
		//		for(int j = 0; j< Cw[i].count ;j ++)
		//		{
		//			str.Format("%d",Cw[i].num[j] );
		//			dc.TextOut(50*(j+1),50*(i+1),str);
		//		}  
		
		if( bshowcenter ){
			//			dc.TextOut(km.Cw[i].w.x,km.Cw[i].w.y ,"+");
			//            dc.SelectObject(&pen1);
			dc.Ellipse(km.Cw[i].w.x -2,km.Cw[i].w.y-2,
				km.Cw[i].w.x+2,km.Cw[i].w.y+2);
		}
	}
	str.Format("%d",count);
	dc.SetTextColor(arColors[0]);
	dc.TextOut(620,30*(i+3),"共有 "+str+"个点");
	delete []pen; 
}

CString CClusterView::GetPath()//获取主程序所在路径
{
	CString sPath;
	GetModuleFileName(NULL,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH);
	sPath.ReleaseBuffer ();
	int nPos;
	nPos=sPath.ReverseFind ('\\');
	sPath=sPath.Left (nPos); 
	return sPath + "\\points.mdb";
}

bool CClusterView::initiate(point *p = NULL)
{
	CString lpszFile = GetPath();
	CFileFind  fFind;
	BOOL bSuccess;
	bSuccess=fFind.FindFile(lpszFile);
	fFind.Close ();
	if( p == NULL )
	{
		if( km.p ) 		delete []km.p;
		km.p = new point[count];
	}
	if( bSuccess) {
		COleVariant var;		
		var.ChangeType(VT_BSTR, NULL);
		db.Open(lpszFile);
		CDaoRecordset RecSet(&db);
		RecSet.Open(AFX_DAO_USE_DEFAULT_TYPE,"SELECT * FROM points",NULL);
        int x,y,i = 0;  
		while(!RecSet.IsEOF())	
		{
			RecSet.GetFieldValue("point_X",var);
			x = (int)var.pbstrVal;
			RecSet.GetFieldValue("point_Y",var);
			y = (int)var.pbstrVal;
			
			if( p )
			{
				p[i].x = x;
				p[i].y = y;
			}
			else 
			{
				km.p[i].x = x;
				km.p[i].y = y;
			}
			i++;
			RecSet.MoveNext(); 
		}
		
		RecSet.Close();
		db.Close();
	}
	
	
	return true;
}
/////////////////////////////////////////////////////////////////////////////
// CClusterView printing

BOOL CClusterView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CClusterView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CClusterView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CClusterView diagnostics

#ifdef _DEBUG
void CClusterView::AssertValid() const
{
	CView::AssertValid();
}

void CClusterView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CClusterDoc* CClusterView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CClusterDoc)));
	return (CClusterDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CClusterView message handlers
int CClusterView::CheckFile()
{
	CString lpszFile = GetPath(); 
	CFileFind  fFind;
	int bSuccess;
	bSuccess=fFind.FindFile(lpszFile);
	fFind.Close ();
	return bSuccess;
}

bool CClusterView::Create_db()
{	
	if(!CheckFile())
	{
		db.Create(GetPath());
		CString SqlCmd = "CREATE TABLE Points(point_X INT,point_Y INT,class INT);";
		db.Execute(SqlCmd);
		db.Close();
		AfxMessageBox("数据库创建成功,请输入数据!");
		return true;   
	}
	//	else
	//		AfxMessageBox("数据库已经存在,如要重新输入数据请删除数据库文件!");
	return false;
	
}
void CClusterView::OnBeginInput() 
{
	// TODO: Add your command handler code here
	if( !CheckFile() )
		Create_db();
	binput = true ;
	if( bshowcenter && km.Cw ) 
	{
		OnBeginHide();
		bshowcenter = false;
	}
}

void CClusterView::OnBeginEnd() 
{
	// TODO: Add your command handler code here
	if( binput )
	{
    	binput = false;
        count = display();
	}
}
void CClusterView::Add_Point(long x,long y, int c)
{
	CString strFile = GetPath(); 
	db.Open(strFile);		
    CString str;
	str.Format("%d,%d",x,y);
	db.Execute("INSERT INTO Points (point_X,point_Y,class) VALUES (" + str + ",0)");
	db.Close();
}

void CClusterView::OnBeginKmeans() 
{
	// TODO: Add your command handler code here
	if( binput ) 		
	{
		AfxMessageBox("请先按输入结束");
		return;
	}

	if(!initiate()) return;
		Input_k input;
label:
	if(input.DoModal() == IDOK )
	{
		km.Cl_k = input.m_k;
		if( km.Cl_k > count || km.Cl_k < 0 ) 
		{
			CString str;
			str.Format("%d",count);
			AfxMessageBox("请输入 1 到 "+str+" 的数");
			goto label;
		}
	}
	if( km.Cl_k == 0 || km.Cl_k > count ) return ;
	if( km.Cw ) delete [] km.Cw;
	km.Cw = new C_point[km.Cl_k];
	int *no = new int[km.Cl_k];
    time_t t;  
	
    srand((unsigned) time(&t));  
	
	for(int i=0 ; i < km.Cl_k;)
	{
		int j = rand()%count;
		bool bexist = false;
		for(int m = 0;m < i; m++)
			if( no[m] == j )
			{ bexist = true;
			break;
			}
			if( bexist ) continue;
			else no[i++] = j;
	}
	for(int j = 0; j < km.Cl_k; j++)
	{
		km.Cw[j].w.x = km.p[ no[j] ].x;
		km.Cw[j].w.y = km.p[ no[j] ].y;
		km.Cw[j].num = new int[count];
		km.Cw[j].count = 0;
	}
	delete []no;
	km.KMeans(count,km.Cl_k);
//		binput = false ;
/////////		OnBeginHide();///error
//		count = display();
//		km.KMeans(count,k);
//	}
//	if( bshowcenter )
//	{
//		OnBeginHide();
//		bshowcenter = true;
//	}
	showkm = true;
	showDbscan = false;
	show();
}

void CClusterView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	if(binput) 
	{	
		CClientDC dc(this);
		HCURSOR  m_HCross;
		m_HCross = AfxGetApp()->LoadStandardCursor(IDC_CROSS);
        ::SetCursor(m_HCross);
		CPen pen1;
		pen1.CreatePen(PS_SOLID,1,RGB(255,255,255));
		if( (point.x < 600 && point.x > 50) && ( point.y > 50 && point.y < 370) ) 
		{
			Add_Point(point.x,point.y,0);
			dc.Ellipse(point.x-1,point.y-1,point.x+1,point.y+1);
		}
	}
	CView::OnLButtonDown(nFlags, point);
}

void CClusterView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if( binput ) {
		HCURSOR  m_HCross;
		m_HCross = AfxGetApp()->LoadStandardCursor(IDC_CROSS);
		::SetCursor(m_HCross);
	}
	CView::OnMouseMove(nFlags, point);
}

void CClusterView::OnUpdateBeginEnd(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck( binput == false );
}

void CClusterView::OnUpdateBeginInput(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck( binput );
}

void CClusterView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if( binput ) {
		HCURSOR  m_HCross;
		m_HCross = AfxGetApp()->LoadStandardCursor(IDC_CROSS);
		::SetCursor(m_HCross);
	}
	CView::OnLButtonUp(nFlags, point);
}

void CClusterView::OnBeginShow() 
{
	// TODO: Add your command handler code here
	
	if( km.Cl_k > 0 )
	{		
		bshowcenter = true;
		show();
	}
}

void CClusterView::OnUpdateBeginShow(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(bshowcenter);
}

void CClusterView::OnBeginHide() 
{
	// TODO: Add your command handler code here
	if( km.Cl_k > 0)
	{
		bshowcenter = false;
		CClientDC dc(this);
		CPen pen1(PS_SOLID,1,RGB(0,0,0)) ,pen2(PS_SOLID,1,RGB(255,255,255));
		dc.SelectObject(&pen2);
		dc.Rectangle(50,50,600,370);
		dc.SelectObject(&pen1);
		dc.MoveTo(50,50);
		dc.LineTo(600,50);  dc.TextOut(600,42,"〉");
		dc.MoveTo(50,50);
		dc.LineTo(50,370);  dc.TextOut(43,360,"∨");
		show();
	}
}

void CClusterView::OnUpdateBeginHide(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck( bshowcenter == false );
}

void CClusterView::OnBeginSave() 
{
	// TODO: Add your command handler code here
//	if( km.Cl_k == 0) return ;
	CString strFile = GetPath(); 
	CDaoDatabase db;
	db.Open(strFile);	
	//	db.Execute("USE PUBS TRUNCATE POINTS");
    CString str1,str2,str3;
	if( showkm ) {
		for(int i = 1 ;i < km.Cl_k; i++ )
			for( int j = 0; j < km.Cw[i].count ; j++)
			{
				str1.Format("%d",i); 
				str2.Format("%d",km.p[ km.Cw[i].num[ j ] ].x);
				str3.Format("%d",km.p[ km.Cw[i].num[ j ] ].y);
				db.Execute("UPDATE Points SET class = " + str1 +
					" WHERE point_X = " + str2 + " and point_Y = " + str3);
			} 
			AfxMessageBox("保存完毕");
	}
	if( showDbscan )
	{
			for( int j = 0; j < Ds.N ; j++)
			{
				str1.Format("%d",Ds.C[j]); 
				str2.Format("%d",Ds.p[j].x);
				str3.Format("%d",Ds.p[j].y);
				db.Execute("UPDATE Points SET class = " + str1 +
					" WHERE point_X = " + str2 + " and point_Y = " + str3);
			} 
			AfxMessageBox("保存完毕");
	}
	db.Close();
}

void CClusterView::OnBeginDense() 
{
	// TODO: Add your command handler code here
	if( binput ) 		
	{
		AfxMessageBox("请先按输入结束");
		return;
	}
	if(!initiate()) return;
	km.dense(count);
	showkm = true;
	showDbscan = false;
	bshowcenter = false;
	show();
}

void CClusterView::OnBeginDbscan() 
{
	// TODO: Add your command handler code here
	if( binput ) 		
	{
		AfxMessageBox("请先按输入结束");
		return;
	}
	D_Dbscan Dia_in;
	int Eps = 5,Minpts = 4;
	Dia_in.m_Eps = Eps;
	Dia_in.m_MinPts = Minpts;
	if(Dia_in.DoModal() == IDOK )
	{
		Eps = Dia_in.m_Eps;
		Minpts = Dia_in.m_MinPts;
	}
	showDbscan = true;
	bshowcenter = false;
	showkm = false;
	Ds.set(count,Eps,Minpts);
	initiate(Ds.p);
	Ds.Db_scan();
	show_Dbscan(Ds.N,Ds.C,Ds.p);
}

void CClusterView::show_Dbscan(int n ,int *C,point *p)
{	
	CClientDC dc(this);
	CString str;
	int i ;
	CPen *pen = new CPen[10];
	for(int ii = 0 ; ii < 10 ; ii ++)
		pen[ii].CreatePen(PS_SOLID,1,arColors[ ii%11 ]);
	CPen pe1,pe2;
	pe1.CreatePen(PS_SOLID,1,RGB(0,0,0));
	pe2.CreatePen(PS_SOLID,1,RGB(255,255,255));
	dc.SelectObject(&pe2);
	dc.Rectangle(600,60,750,600);
	dc.SelectObject(&pe1);
	dc.Rectangle(600,60,750,30*(km.Cl_k+3));
	dc.TextOut(650,70,"result");
	for( i=0 ; i < n; i ++)
	{
		if( C[i] == -1 ) 
		{
			dc.SelectObject(&pe1);
			dc.TextOut(p[ i ].x-3,p[ i ].y-5,"*");
		}
		else{
			
			CPen *pOldPen = dc.SelectObject(&pen[ C[i] ]);
			switch( C[i] )
			{
			case 0:{
			dc.Ellipse(p[ i ].x -1,p[ i ].y-1,p[ i ].x+1,p[ i ].y+1);
			break;}
			case 1:
				{
					dc.Ellipse(p[ i ].x -2,p[ i ].y-2,p[ i ].x+2,p[ i ].y+2);
					break;
				}
			case 2:
				{
					dc.Rectangle(p[ i ].x -2,p[ i ].y-2,p[ i ].x+2,p[ i ].y+2);
				break;
				}
			default: break;
			}
		}
	}
	delete []pen; 
}

⌨️ 快捷键说明

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