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

📄 board.cpp

📁 基于点轨迹的手势识别.鼠标右键点击开始记录鼠标轨迹,基于记录的轨迹,利用神经网络算法进行识别.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 Copyright (c) 2001 
 Author: Konstantin Boukreev 
 E-mail: konstantin@mail.primorye.ru 

 Created: 01.11.2001 17:39:39
 Version: 1.0.0

*/

/*
	bugs : sometimes, it doesn't draw anything in a top desk even if the pattern was recognized
*/

#include "stdafx.h"
#include "board.h"
#include "resource.h"
#include "GestureData.h"

const int DESK_WIDTH	= 100;
const int DESK_HEIGHT	= 100;
const int STATUS_HEIGHT	= 20;
const int STATUS_INDENT	= 2;

const double pi = 3.1415926535;

#ifdef max
#undef max
#endif

Board::Board(unsigned range) 
	: 
	NUMBER_OF_ANGLES(range),
	NUMBER_OF_ANCHOR_POINTS(range + 1),		
	m_angles (NUMBER_OF_ANGLES),
	m_cosines(NUMBER_OF_ANGLES),
	m_sinuses(NUMBER_OF_ANGLES),
	m_hpdesk(NUMBER_OF_ANGLES / 4),
	m_mode(untrained_mode)
{
	m_refresh	= false;
//	m_timestamp	= 0;	
	m_hMemDC	= 0;
	m_hBitmap	= 0;
	m_hOldBitmap = 0;
	m_hMemDC2	= 0;
	m_hBitmap2	= 0;
	m_hOldBitmap2 = 0;	
	m_hMemDC3	= 0;
	m_hBitmap3	= 0;
	m_hOldBitmap3 = 0;
	m_hMemDC4	= 0;
	m_hBitmap4	= 0;
	m_hOldBitmap4 = 0;
	
	m_hbrh1		= CreateSolidBrush(RGB(255, 255, 255));
	m_hbrh2		= CreateSolidBrush(RGB(231, 231, 231));
	m_hpen1		= CreatePen(PS_SOLID, 0, RGB(0, 0, 128));
	m_hpen2		= CreatePen(PS_SOLID, 0, RGB(192, 192, 192));
	m_hpen3		= CreatePen(PS_SOLID, 0, RGB(255, 0, 0));	
	m_hpen4		= CreatePen(PS_DOT, 0, RGB(221, 221, 221));	
	
	unsigned dc = 255 / m_hpdesk.size();
	for (unsigned i = 0; i < m_hpdesk.size(); ++i)
	{
		m_hpdesk[i] = CreatePen(PS_SOLID, 0, RGB(255 - i * dc, 0, i * dc));
	}
}

Board::~Board() 
{
	CleanupMemDC();

	if (m_hbrh1) DeleteObject(m_hbrh1);
	if (m_hbrh2) DeleteObject(m_hbrh2);
	if (m_hpen1) DeleteObject(m_hpen1);
	if (m_hpen2) DeleteObject(m_hpen2);
	if (m_hpen3) DeleteObject(m_hpen3);
	if (m_hpen4) DeleteObject(m_hpen4);

	for (unsigned i = 0; i < m_hpdesk.size(); ++i)
		if (m_hpdesk[i]) DeleteObject(m_hpdesk[i]);
}

LRESULT Board::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	RECT rc;
	GetClientRect(&rc);

	PAINTSTRUCT ps;		
	HDC hDC = BeginPaint(&ps);
	Draw(hDC, rc);
	EndPaint(&ps);

	return 0;
}

LRESULT Board::OnEraseBknd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	return 1;
}

LRESULT Board::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	CleanupMemDC();
	return 0;
}

LRESULT Board::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	if (wParam & MK_RBUTTON)
	{
		POINT pt = {LOWORD(lParam), HIWORD(lParam)};
		AddMouseRecord(pt);
	}
	return 0;
}

LRESULT Board::OnRButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{	
	// at first always tries to stop any active action (training or testing)
	CWindow(GetParent()).SendMessage(WM_COMMAND, MAKEWPARAM(ID_STOP, 0));
	StartMouseRecord();
	return 0;
}

LRESULT Board::OnRButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	StopMouseRecord();	
	return 0;
}

LRESULT Board::OnAsyncRefresh(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	MSG msg; 	
	while (PeekMessage(&msg, m_hWnd, WM_ASYNC_REFRESH, WM_ASYNC_REFRESH, PM_REMOVE))
		;
	Refresh();
	return 0;
}

void Board::Draw(HDC hDC, RECT& rc)
{
	if (!m_hMemDC) 
		CreateMemDC(hDC, rc);
	
	if (m_refresh) 
	{
		DrawMemDC();
		m_refresh = false;
	}			

	BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, 
		m_hMemDC, 0, 0, SRCCOPY);
	
//	m_timestamp = GetTickCount();
}

void Board::CreateMemDC(HDC hDC, RECT& rc)
{
	CleanupMemDC();		
	
	m_hMemDC	= CreateCompatibleDC(hDC);
	m_hBitmap	= CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top);
	m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);

	m_hMemDC2	= CreateCompatibleDC(hDC);
	m_hBitmap2	= CreateCompatibleBitmap(hDC, DESK_WIDTH, DESK_HEIGHT);
	m_hOldBitmap2 = (HBITMAP)SelectObject(m_hMemDC2, m_hBitmap2);

	m_hMemDC3	= CreateCompatibleDC(hDC);
	m_hBitmap3	= CreateCompatibleBitmap(hDC, rc.right - rc.left - STATUS_INDENT * 2, STATUS_HEIGHT);
	m_hOldBitmap3 = (HBITMAP)SelectObject(m_hMemDC3, m_hBitmap3);

	m_hMemDC4	= CreateCompatibleDC(hDC);
	m_hBitmap4	= CreateCompatibleBitmap(hDC, DESK_WIDTH, DESK_HEIGHT);
	m_hOldBitmap4 = (HBITMAP)SelectObject(m_hMemDC4, m_hBitmap4);

	m_refresh	= true;
	m_rcMemDC	= rc;
}

void Board::CleanupMemDC()
{
	if (m_hMemDC)
	{
		SelectObject(m_hMemDC, m_hOldBitmap);
		DeleteDC(m_hMemDC);
		DeleteObject(m_hBitmap);
		
		SelectObject(m_hMemDC2, m_hOldBitmap2);
		DeleteDC(m_hMemDC2);
		DeleteObject(m_hBitmap2);

		SelectObject(m_hMemDC3, m_hOldBitmap3);
		DeleteDC(m_hMemDC3);
		DeleteObject(m_hBitmap3);

		SelectObject(m_hMemDC4, m_hOldBitmap4);
		DeleteDC(m_hMemDC4);
		DeleteObject(m_hBitmap4);

		m_hMemDC = 0;
	}
}

void Board::DrawMemDC()
{
	unsigned cx = m_rcMemDC.right - m_rcMemDC.left;
	unsigned cy = m_rcMemDC.bottom - m_rcMemDC.top;

	int n_save_dc = SaveDC(m_hMemDC);

	FillRect(m_hMemDC, &m_rcMemDC, m_hbrh1);

	// draw grid

	SelectObject(m_hMemDC, m_hpen4);

	#define GRID_WIDTH	16
	#define GRID_HEIGHT 16

	for (int x = m_rcMemDC.left; x < m_rcMemDC.right; x += GRID_WIDTH)
	{
		MoveToEx(m_hMemDC, x, m_rcMemDC.top, 0);
		LineTo  (m_hMemDC, x, m_rcMemDC.bottom);
	}
		
	for (int y = m_rcMemDC.top; y < m_rcMemDC.bottom; y += GRID_HEIGHT)
	{
		MoveToEx(m_hMemDC, m_rcMemDC.left, y, 0);
		LineTo  (m_hMemDC, m_rcMemDC.right, y);
	}
		
	// draw main screen

	if (training_mode == m_mode || 
		trained_mode == m_mode)
	{
		RECT rc = m_rcMemDC;
		rc.top  += 3;
		rc.left += 3;
		rc.right  -= (DESK_WIDTH + 3);
		rc.bottom -= (STATUS_HEIGHT + 3);
		DrawGraph(m_hMemDC, rc);	
	}			
	else
	{
		DrawPath(m_hMemDC, m_rcMemDC);	

		if (recognized_success	== m_mode || 
			recognized_fail		== m_mode)
		{
			DrawWinners(m_hMemDC, m_rcMemDC);
		}		
	}
		
	// draw desks and status info

	int x_desk = m_rcMemDC.right - DESK_WIDTH - 3;
	int y_desk = m_rcMemDC.top   + 3;		
	RECT rcDesc = {0, 0, DESK_WIDTH, DESK_HEIGHT};

	DrawTopDesc(m_hMemDC2, rcDesc);
	BLENDFUNCTION bf = {AC_SRC_OVER, 0, 150, 0};

	AlphaBlend(m_hMemDC, x_desk, y_desk, DESK_WIDTH, DESK_HEIGHT, 
		m_hMemDC2, 0, 0, DESK_WIDTH, DESK_HEIGHT, bf);

	y_desk += (DESK_HEIGHT + 3);

	DrawBottomDesc(m_hMemDC2, rcDesc);
	bf.SourceConstantAlpha = 170; 
	AlphaBlend(m_hMemDC, x_desk, y_desk, DESK_WIDTH, DESK_HEIGHT, 
		m_hMemDC2, 0, 0, DESK_WIDTH, DESK_HEIGHT, bf);
	bf.SourceConstantAlpha = 150;

	RECT rcStatus = {0, 0, cx - STATUS_INDENT * 2, STATUS_HEIGHT};
	DrawStatusInfo(m_hMemDC3, rcStatus);
	AlphaBlend(m_hMemDC, STATUS_INDENT, cy - STATUS_HEIGHT, cx - STATUS_INDENT * 2, STATUS_HEIGHT, 
		m_hMemDC3, 0, 0, cx - STATUS_INDENT * 2, STATUS_HEIGHT, bf);

	RestoreDC(m_hMemDC, n_save_dc);
}

void Board::DrawWinners(HDC hDC, RECT& rc)
{
	int n_save_dc = SaveDC(hDC);

	SetBkMode   (hDC, TRANSPARENT);	
	SetTextColor(hDC, RGB(191, 191, 191));
	SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));

	char buf[255] = {0};
	SIZE sz;
	int x = rc.left + 3; 
	int y = rc.top  + 3;
	for (unsigned n = 0; n < sizeof(m_winners)/sizeof(m_winners[0]); ++n)
	{	
		sprintf(buf, "%s - %f", pattern_names[m_winners[n].m_id], m_winners[n].m_probability);
		TextOut(hDC, x, y, buf, lstrlen(buf));	
		GetTextExtentPoint32(hDC, buf, lstrlen(buf), &sz);
		y += sz.cy;
	}

	RestoreDC(hDC, n_save_dc);
}

void Board::DrawPath(HDC hDC, RECT& rc)
{
	typedef path_t::iterator iterator;
	iterator i;

	// draw a mouse's path

	for (i = m_path.begin(); i != m_path.end(); ++i)
	{
		POINT& pt = (*i);
		SetPixel(hDC, pt.x, pt.y, RGB(255, 0, 0));	
	}		

	_ASSERTE((m_path2.size() == NUMBER_OF_ANCHOR_POINTS) || (m_path2.size() == 0));

	// draw a smoothed path

	for (i = m_path2.begin(); i != m_path2.end(); ++i)
	{
		POINT& pt = (*i);

		SetPixel(hDC, pt.x - 1, pt.y + 0, RGB(0, 0, 255));
		SetPixel(hDC, pt.x + 1, pt.y + 0, RGB(0, 0, 255));
		SetPixel(hDC, pt.x + 0, pt.y + 1, RGB(0, 0, 255));
		SetPixel(hDC, pt.x + 0, pt.y - 1, RGB(0, 0, 255));
		SetPixel(hDC, pt.x + 0, pt.y + 0, RGB(0, 0, 255));
	}		
}

void Board::DrawGraph(HDC hDC, RECT& rc)
{
	int n_save_dc = SaveDC(hDC);

	SelectObject(hDC, m_hpen3);	

	typedef vector_real_t::iterator iterator;
	iterator i;

	int x = rc.left;		
	double ratio = ((double)rc.bottom - rc.top) / m_max_error;
	
	for (i = m_errors.begin(); i != m_errors.end(); ++i)
	{
		MoveToEx(hDC, x, rc.bottom, 0);
		LineTo(hDC, x, rc.bottom - int((*i) * ratio));
		++x;
	}		

	RestoreDC(hDC, n_save_dc);
}

void Board::DrawTopDesc(HDC hDC, RECT& rc)
{
	int n_save_dc = SaveDC(hDC);

	SelectObject(hDC, m_hbrh2);
	SelectObject(hDC, m_hpen2);
	Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);

	if ((recognizing_mode	== m_mode && m_path2.size()) ||
		(recognized_success	== m_mode && m_path2.size()) ||
		(recognized_fail	== m_mode && m_path2.size()) ||
		(training_mode		== m_mode && m_update_top_desk))
	{

⌨️ 快捷键说明

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