www.pudn.com > cluster_KM_DS.rar > clusterView.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;  
}