📄 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -