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

📄 kmeanview.cpp

📁 神经网络中的K-MEAN聚类算法
💻 CPP
字号:
// KmeanView.cpp : implementation of the CKmeanView class
//

#include "stdafx.h"
#include "Kmean.h"

#include "KmeanDoc.h"
#include "KmeanView.h"
#include "ResetDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CKmeanView

IMPLEMENT_DYNCREATE(CKmeanView, CView)

BEGIN_MESSAGE_MAP(CKmeanView, CView)
	//{{AFX_MSG_MAP(CKmeanView)
	ON_COMMAND(ID_K_MEANS, OnKMeans)
	ON_UPDATE_COMMAND_UI(ID_K_MEANS, OnUpdateKMeans)
	ON_COMMAND(ID_RESET, OnReset)
	ON_UPDATE_COMMAND_UI(ID_RESET, OnUpdateReset)
	ON_COMMAND(ID_STOP, OnStop)
	ON_UPDATE_COMMAND_UI(ID_STOP, OnUpdateStop)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CKmeanView construction/destruction

CKmeanView::CKmeanView()
{
	// TODO: add construction code here
    m_nTimeID = 0x0f1f2f3f;
    m_nState = STOPPED;
    m_nIndex = -1;

    m_pPainter = NULL;
}

CKmeanView::~CKmeanView()
{
}

BOOL CKmeanView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CKmeanView drawing

void CKmeanView::OnDraw(CDC* pDC)
{
	CKmeanDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

    static CPen penPoint(PS_SOLID, 3, RGB(255, 0, 0));
    static CPen penCenter(PS_SOLID, 5, RGB(0, 0, 0));
    static CPen penCircle(PS_SOLID, 1, RGB(0, 0, 255));
    static CPen penCorrdinate(PS_SOLID, 1, RGB(0, 0, 0));
    static CDC memDC;
    static CBitmap memBitMap;
    CBitmap *pOldBit;
    CBrush *pOldBrush;
    CPen *pOldPen;
    const CRect& rect = m_pPainter->GetRect();

    memDC.CreateCompatibleDC(pDC);
    memBitMap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Width());
    pOldPen = memDC.GetCurrentPen();
    pOldBrush = memDC.GetCurrentBrush();
    pOldBit = memDC.SelectObject(&memBitMap);

    memDC.SelectObject(&penCorrdinate);
    m_pPainter->DrawCoordinate(&memDC);

    const Vecpf& vecCenters = pDoc->GetCenters();
    const Vecpf& vecPoints = pDoc->GetPoints();
    int i;
    memDC.SelectObject(&penPoint);
    for (i = 0; i < vecPoints.size(); i++)
        m_pPainter->DrawPoint(&memDC, &vecPoints[i]);
    
    memDC.SelectObject(&penCenter);
    for (i = 0; i < vecCenters.size(); i++)
        m_pPainter->DrawPoint(&memDC, &vecCenters[i]);

    memDC.SelectObject(&penCircle);
    for (i = 0; i < vecCenters.size(); i++)
        m_pPainter->DrawEllipse(&memDC, &vecCenters[i], 15, 15);

    pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
            &memDC, 0, 0, SRCCOPY);

    memDC.SelectObject(pOldPen);
    memDC.SelectObject(pOldBrush);
    memDC.SelectObject(pOldBit);
    memDC.DeleteDC();
    memBitMap.DeleteObject();
}

/////////////////////////////////////////////////////////////////////////////
// CKmeanView diagnostics

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CKmeanView message handlers

void CKmeanView::OnKMeans() 
{
    SetTimer(m_nTimeID, 20, NULL);
    m_nState = KMEAN;
    m_nIndex = 0;

    const Vecpf& vecCenters = GetDocument()->GetCenters();
    m_vecLastCenters.clear();
    m_vecLastCenters.insert(m_vecLastCenters.begin(), 
                            vecCenters.begin(), vecCenters.end());
}

void CKmeanView::OnUpdateKMeans(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_nState == IDLE);
}

void CKmeanView::OnReset() 
{
	OnStop();
    static CResetDlg dlg;
    int ret = dlg.DoModal();
    if (ret == IDOK)
    {
        GetDocument()->ResetCenters(dlg.m_nCenterNum);
        m_dbRate = dlg.m_dbRate;
        m_nState = IDLE;
    }
}

void CKmeanView::OnUpdateReset(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(TRUE);
}

void CKmeanView::OnStop() 
{
    if (m_nState == KMEAN)
    {
        KillTimer(m_nTimeID);
        m_nState = STOPPED;
        m_nIndex = -1;
    }
}

void CKmeanView::OnUpdateStop(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_nState == KMEAN);
}

void CKmeanView::OnTimer(UINT nIDEvent) 
{
	if (nIDEvent == m_nTimeID && m_nIndex != -1)
    {
        CKmeanDoc *pDoc = GetDocument();
        pDoc->Kmeans(m_nIndex++, m_dbRate);

        if (m_nIndex == pDoc->GetPoints().size())
        {
            const Vecpf& vecCenters = pDoc->GetCenters();
            double dbMaxDelta = 0.0;
            double dx, dy, d;
            for (int i = 0; i < vecCenters.size(); i++)
            {
                dx = vecCenters[i].x - m_vecLastCenters[i].x;
                dy = vecCenters[i].y - m_vecLastCenters[i].y;
                d = sqrt(dx * dx + dy * dy);
                if (dbMaxDelta < d)
                    dbMaxDelta = d;
            }
            if (dbMaxDelta < 0.1)
                OnStop();
            else
            {
                m_vecLastCenters.clear();
                m_vecLastCenters.insert(m_vecLastCenters.begin(), 
                                        vecCenters.begin(), vecCenters.end());
            }
            m_nIndex = 0;
        }
    }
	CView::OnTimer(nIDEvent);
}

void CKmeanView::OnInitialUpdate() 
{
	CView::OnInitialUpdate();
	
    if (m_pPainter == NULL)
    {
        CRect rect;
	    GetClientRect(&rect);
        rect.right = rect.left + 300;
        rect.bottom = rect.top + 300;
        m_pPainter = new PainterFacade(rect, 50);
    }
	
}

⌨️ 快捷键说明

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