📄 kclusteringdlg.cpp
字号:
// KClusteringDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "KClustering.h"
#include "KClusteringDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CKClusteringDlg 对话框
CKClusteringDlg::CKClusteringDlg(CWnd* pParent /*=NULL*/)
: CBitmapDialog(CKClusteringDlg::IDD, pParent),
m_ClusterNum(3),
m_pKCluster(NULL)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CKClusteringDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_BUTTON_MINIMIZE, m_btnMinimize);
DDX_Control(pDX, IDC_BUTTON_CLOSE, m_btnClose);
DDX_Control(pDX, IDC_EDIT_CLUSTER_NUM, m_editClusterNum);
DDX_Control(pDX, IDC_BUTTON_LEFT, m_btnLeft);
DDX_Control(pDX, IDC_BUTTON_RIGHT, m_btnRight);
DDX_Control(pDX, IDC_BUTTON_START_CLUSTERING, m_btnStartClustering);
DDX_Control(pDX, IDC_EDIT_AIM_VALUE, m_editAimValue);
DDX_Control(pDX, IDC_EDIT_NOW_STATE, m_editNowState);
}
BEGIN_MESSAGE_MAP(CKClusteringDlg, CBitmapDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON_MINIMIZE, &CKClusteringDlg::OnBnClickedButtonMinimize)
ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CKClusteringDlg::OnBnClickedButtonClose)
ON_BN_CLICKED(IDC_BUTTON_LEFT, &CKClusteringDlg::OnBnClickedButtonLeft)
ON_BN_CLICKED(IDC_BUTTON_RIGHT, &CKClusteringDlg::OnBnClickedButtonRight)
ON_BN_CLICKED(IDC_BUTTON_START_CLUSTERING, &CKClusteringDlg::OnBnClickedButtonStartClustering)
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
// CKClusteringDlg 消息处理程序
BOOL CKClusteringDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// 初始化对话框
MoveWindow(0, 0, 700, 547, 0);
LoadBitmap(IDB_BITMAP_BACKGROUND);
SetTransparent(FALSE);
SetClickAnywhereMove(TRUE);
// 初始化最小化按钮
m_btnMinimize.LoadImages(IDB_BITMAP_MINIMIZE_NORMAL, IDB_BITMAP_MINIMIZE_NORMAL, IDB_BITMAP_MINIMIZE_PUSHED);
m_btnMinimize.MoveWindow(655, 6, 18, 18);
// 初始化关闭按钮
m_btnClose.LoadImages(IDB_BITMAP_CLOSE_NORMAL, IDB_BITMAP_CLOSE_NORMAL, IDB_BITMAP_CLOSE_PUSHED);
m_btnClose.MoveWindow(675, 6, 18, 18);
// 初始化向左按钮
m_btnLeft.LoadImages(IDB_BITMAP_LEFT_NORMAL, IDB_BITMAP_LEFT_NORMAL, IDB_BITMAP_LEFT_PUSHED);
m_btnLeft.MoveWindow(530, 116, 18, 18);
m_btnRight.LoadImages(IDB_BITMAP_RIGHT_NORMAL, IDB_BITMAP_RIGHT_NORMAL, IDB_BITMAP_RIGHT_PUSHED);
m_btnRight.MoveWindow(662, 116, 18, 18);
m_btnStartClustering.LoadImages(IDB_BITMAP_STARTCLUSTERING_NORMAL, IDB_BITMAP_STARTCLUSTERING_NORMAL, IDB_BITMAP_STARTCLUSTERING_PUSHED);
m_btnStartClustering.MoveWindow(536, 385, 140, 24);
// 初始化聚类个数选择
m_editClusterNum.MoveWindow(580, 118, 48, 16);
m_editClusterNum.SetWindowText(TEXT("3"));
// 初始化目标函数值
m_editAimValue.MoveWindow(529, 207, 152, 16);
m_editAimValue.SetWindowText(TEXT("0"));
// 初始化双缓冲
m_DrawBuffer.Create(500, 500, 16);
// 清空绘图板
CDC *MemDC = CDC::FromHandle(m_DrawBuffer.GetDC());
MemDC->FillSolidRect(0, 0, 500, 500, RGB(62, 70, 55));
m_editNowState.MoveWindow(529, 296, 152, 16);
m_editNowState.SetWindowText(TEXT("等待开始"));
SetWindowText(TEXT("K-均值算法演示程序"));
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CKClusteringDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CBitmapDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CKClusteringDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
CDC *MemDC = CDC::FromHandle(m_DrawBuffer.GetDC());
CDC *pDC = GetDC();
pDC->BitBlt(12, 35, 500, 500, MemDC, 0, 0, SRCCOPY);
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
//
HCURSOR CKClusteringDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CKClusteringDlg::OnCancel()
{
// CBitmapDialog::OnCancel();
}
void CKClusteringDlg::OnOK()
{
// CBitmapDialog::OnOK();
}
void CKClusteringDlg::OnBnClickedButtonMinimize()
{
SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, NULL);
}
void CKClusteringDlg::OnBnClickedButtonClose()
{
CBitmapDialog::OnOK();
}
// 聚类结果绘制
void CKClusteringDlg::DrawClustering(CDC* pDC)
{
int DataNum, CenterNum;
int i, j, x, y;
// 保存旧画笔
CPen *oldpen, pen;
oldpen = pDC->SelectObject(&pen);
// 保存旧画刷
CBrush *oldbrush, brush;
oldbrush = pDC->SelectObject(&brush);
// 重新绘制底色
pDC->FillSolidRect(0, 0, 500, 500, RGB(62, 70, 55));
CenterNum = m_pKCluster->GetClusterCenter(&m_Center[0][0]);
COLORREF Color;
// 边线画笔
CPen BorderPen(PS_DOT|PS_GEOMETRIC|PS_ENDCAP_ROUND, 1, RGB(0,0,0));
// 连线画笔
CPen LinePen(PS_DOT|PS_GEOMETRIC|PS_ENDCAP_ROUND, 1, RGB(92,96,88));
CBrush dataBrush(RGB(143,195,31));
pDC->SelectObject(&LinePen);
// 对每一簇
for(i=0; i<m_ClusterNum; i++)
{
// 获得数据
DataNum = m_pKCluster->GetClusterData(i, &m_DataSet[0][0]);
// 画线
pDC->SelectObject(&LinePen);
for (j=0; j<DataNum; j++)
{
x = (int)m_DataSet[j][0];
y = (int)m_DataSet[j][1];
pDC->MoveTo((int)m_Center[i][0], (int)m_Center[i][1]);
pDC->LineTo(x,y);
}
// 画点
pDC->SelectObject(&BorderPen);
pDC->SelectObject(&dataBrush);
for (j=0; j<DataNum; j++)
{
x = (int)m_DataSet[j][0];
y = (int)m_DataSet[j][1];
pDC->Ellipse(x-2, y-2, x+2, y+2);
}
dataBrush.DeleteObject();
}
CBrush centerBrush(RGB(255,255,255));
pDC->SelectObject(¢erBrush);
for (i=0; i<CenterNum; i++)
{
x = (int)m_Center[i][0];
y = (int)m_Center[i][1];
pDC->Ellipse(x-4, y-4, x+4, y+4);
}
pDC->SelectObject(oldbrush);
pDC->SelectObject(oldpen);
pen.DeleteObject();
brush.DeleteObject();
}
void CKClusteringDlg::OnBnClickedButtonLeft()
{
CString temp;
if (m_ClusterNum==1) return;
m_ClusterNum--;
temp.Format(TEXT("%d"), m_ClusterNum);
m_editClusterNum.SetWindowText(temp);
}
void CKClusteringDlg::OnBnClickedButtonRight()
{
CString temp;
if (m_ClusterNum==20) return;
m_ClusterNum++;
temp.Format(TEXT("%d"), m_ClusterNum);
m_editClusterNum.SetWindowText(temp);
}
// 开始聚类
void CKClusteringDlg::OnBnClickedButtonStartClustering()
{
int i;
double DataSet[400][2] = {0};
srand(time(0));
for(i=0; i<400; i++)
{
DataSet[i][0] = (double)(rand()%500);
DataSet[i][1] = (double)(rand()%500);
}
if (m_pKCluster) delete m_pKCluster;
m_pKCluster = new KCluster(400 , 2, m_ClusterNum, &DataSet[0][0]);
m_editNowState.SetWindowText(TEXT("正在聚类"));
m_pKCluster->StartClustering();
m_nTimerCluster = SetTimer(1, 1000, 0);
if ( m_pKCluster->SetupClustering() == true)
{
KillTimer(m_nTimerCluster);
m_editNowState.SetWindowText(TEXT("聚类成功"));
}
CDC *MemDC = CDC::FromHandle( m_DrawBuffer.GetDC() );
DrawClustering(MemDC);
InvalidateRect(CRect(12, 35, 512, 535), 0);
}
void CKClusteringDlg::OnDestroy()
{
CBitmapDialog::OnDestroy();
if (m_pKCluster)
{
delete m_pKCluster;
}
}
void CKClusteringDlg::OnTimer(UINT_PTR nIDEvent)
{
if(nIDEvent==m_nTimerCluster)
{
CString tmp;
if ( m_pKCluster->SetupClustering() == true)
{
KillTimer(m_nTimerCluster);
m_editNowState.SetWindowText(TEXT("聚类成功"));
}
tmp.Format(TEXT("%f"), m_pKCluster->AimFunction());
m_editAimValue.SetWindowText(tmp);
CDC *MemDC = CDC::FromHandle( m_DrawBuffer.GetDC() );
DrawClustering(MemDC);
InvalidateRect(CRect(12, 35, 512, 535), 0);
}
CBitmapDialog::OnTimer(nIDEvent);
}
void CKClusteringDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
/*
//Check if the key pressed was a DOWN ARROW key
if (nChar == VK_DOWN)
MessageBox(TEXT("It is a down arrow key!"));
if (nChar == VK_RIGHT)
OnBnClickedButtonRight();
if (nChar == VK_LEFT)
OnBnClickedButtonRight();
if (nChar == VK_UP)
MessageBox(TEXT("It is a up arrow key!"));
TRACE(TEXT("It is a key!"));
*/
CBitmapDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -