Государственное образовательное учреждение
Высшего профессионального образования
«Санкт-Петербургский государственный технологический институт
(технический университет)»
Факультет информационных технологий и управления
Специальность: 230100 «Автоматизированные системы обработки информации и управления»
Кафедра систем автоматизированного
Проектирования и управления
Курсовая работа
По дисциплине: «Программирование»
Выполнил: Мордюк Д.О.
Группа № 321
Проверил: Брасов В.Н.
Санкт-Петербург
г.
Используя библиотеку MFC, необходимо разработать программу, которая позволит решить следующие задачи:
. Создать 30 окружностей со случайными параметрами (координаты центра, радиус, цвет) и вывести их на экран.
. Обеспечить интерфейс изменения параметров окружностей.
. Созданные окружности должны перемещаться по определенному закону в соответствии с вариантами заданий.
Окружности перемещаются слева направо, при достижении правой границы они перемещаются скачком к левой границе и случайным образом меняется радиус окружностей в пределах 1 - 30.
1. При инициализации окружности не должны накладываться друг на друга.
. В процессе перемещения окружности не должны вылетать за указанные координаты экранной области.
Для реализации движения окружностей был написан алгоритм приводящий к их перемещению слава направо с последующим появлением окружностей в левой части экрана, при достижении ими правой границы. Алгоритм представляет собой простейший вариант имитации движения окружностей.
Библиотека MFC (Microsoft Foundation Classes) предлагает поддержку модели документ/представление, в которой логика работы приложения явным образом отделяется от кода, ответственного за пользовательский интерфейс.
Разделение происходит как на уровне файлов (этот код содержится в разных единицах трансляции), так и на уровне классов - за хранение данных приложения и работу с ними отвечает один класс, а за реализацию пользовательского интерфейса - другой.
В нашем случае код этих классов размещён в следующих файлах:
|
Класс |
Файл |
Назначение |
|
CSpheresDoc |
SpheresDoc.h |
Заголовочный файл документа, хранящего данные приложения. |
|
|
SpheresDoc.cpp |
Исходный файл документа, хранящего данные приложения. |
|
CSpheresView |
SpheresView.h |
Заголовочный файл вида. |
|
|
SpheresView.cpp |
Исходный файл вида, отвечающий за отображение информации. |
В программе использовались следующие константы:
|
Имя |
Тип |
Значение |
Описание |
|
min_radius |
const int |
1 |
Минимальный радиус окружности |
|
max_radius |
const int |
40 |
Максимальный радиус окружности |
|
nCircles |
const int |
30 |
Число создаваемых окружностей |
|
nTries |
const int |
1000 |
Число попыток установить окружность |
microsoft foundation classes алгоритм
Для хранения координат точки на экране (точками задаются центры окружностей), а также, для задания скорости смещения по осям X и Y во время перемещения используется структура: vec2d.
Для задания параметров окружностей используется структура Circle, в которой определены:
pos - структура vec2d, центр окружности (pos.x и pos.y координаты X и Y соответственно);- радиус окружности;- структура vec2d, скорость перемещения (velocity.x и velocity.y скорости перемещения по осям);- цвет окружности.
В программе использовались следующие функции:
|
Имя |
Описание |
|
|
SpheresDoc.cpp |
||
|
int GetCircleIndex(const CPoint& pt) const |
Позволяет по точке в плоскости получить индекс окружности, которая содержит эту точку |
Возвращает ссылку на окружность по её индексу |
|
void DrawCircle(CDC *pDC) |
Отрисовка окружностей |
|
|
bool IsIntersect(Circle) |
Определение пересечения окружностей |
|
|
void DoSimulation() |
Функция содержит алгоритм движения |
|
|
SpheresView.cpp |
||
|
afx_msg void OnTimer(UINT_PTR nIDEvent) |
Функция по таймеру осуществляет вызов DoSimulation() таким образом реализуя один шаг имитации движения |
|
|
afx_msg void OnLButtonDown(UINT nFlags, CPoint point) |
Отслеживание нажатия левой кнопки мыши |
|
|
afx_msg void OnMouseMove(UINT nFlags, CPoint point) |
Отслеживание перемещения мыши |
|
|
afx_msg void OnLButtonUp(UINT nFlags, CPoint point) |
Отслеживание отпускания левой кнопки мыши |
|
|
afx_msg void OnActionStartsimulation() |
Запустить имитацию движения окружностей посредством пункта меню или нажатия F5 |
|
|
afx_msg void OnActionStopsimulation() |
Остановить имитацию движения окружностей посредством пункта меню или нажатия F6 |
|
|
afx_msg void OnRButtonDown(UINT nFlags, CPoint point) |
Отслеживание нажатия правой кнопки мыши для вызова контекстного меню |
|
|
afx_msg void PopupMenuCircleProps() |
Вызов окна изменения радиуса окружностей |
|
|
afx_msg void PopupMenuCircleColor() |
Вызов окна изменения цвета окружностей |
|
При запуске программы создаются окружности. Их можно перемещать курсором
мыши, изменять радиус и цвет. Запустить/остановить имитацию движения
окружностей можно с помощью соответствующего пункта меню Action или нажатием
функциональных клавиш F5/F6.
Листинг программы
// SpheresDoc.h : interface of the CSpheresDoc class
//
#include<vector>
#pragma oncevec2d {d () {}d (double x, double y) : x(x), y(y){}d (vec2d const& other) : x(other.x), y(other.y){}
// ACCESSORSlength() const;
// MANIPULATORSd& operator+=(vec2d const& other);d& operator-=(vec2d const& other);d& operator*=(double value);d& operator/=(double value);d& normalize();x,y;
};Circle {() : velocity(1,0), color(RGB(0,0,0)) {}
vec2d pos;d velocity;
// Переменная color хранит информацию о цвете окружности
COLORREF color;radius;
};CSpheresDoc : public CDocument
{: // create from serialization only();_DYNCREATE(CSpheresDoc)
// Attributes:::vector<Circle> m_circles;m_area;
// Operations:GetCircleIndex(const CPoint& pt) const;
Circle& GetCircleById(int id);
// Описание метода DrawCircle для прорисовки окружностей в окнеDrawCircle(CDC *pDC);
// Проверка на пересечение окружностейIsIntersect(Circle);
// Моделирование движения окружностей
void DoSimulation();
// Overrides:BOOL OnNewDocument();void Serialize(CArchive& ar);
// Implementation:~CSpheresDoc();
#ifdef _DEBUGvoid AssertValid() const;void Dump(CDumpContext& dc) const;
#endif:
// Generated message map functions:_MESSAGE_MAP()
};
// SpheresDoc.cpp : implementation of the CSpheresDoc class
//
#include "stdafx.h"
#include "Spheres.h"
#include <sstream>
#include "SpheresDoc.h"
#include <math.h>
#include <algorithm>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CSpheresDoc_DYNCREATE(CSpheresDoc, CDocument)_MESSAGE_MAP(CSpheresDoc, CDocument)_MESSAGE_MAP()
// CSpheresDoc construction/destruction::CSpheresDoc()
{
// TODO: add one-time construction code here
}::~CSpheresDoc(){}int bottom=660,right=660, min_radius=1, max_radius=40,nCircles = 30,nTries = 1000;CSpheresDoc::OnNewDocument()
// TODO: add reinitialization code here
// (SDI documents will reuse this document)(!CDocument::OnNewDocument()) return FALSE;
// Размеры виртуальной области
m_area = CRect(0,0,bottom,right);
const int area_width = m_area.right - m_area.left;int area_high = m_area.bottom - m_area.top;_circles.clear();(int tries=0 ; tries < nTries && m_circles.size() < nCircles; tries++) {cir;.pos.x = (int)(rand()%(area_width-2*max_radius)+max_radius);.pos.y = (int)(rand()%(area_high-2*max_radius)+max_radius);.radius= rand()%(max_radius-min_radius)+min_radius;.color=RGB(rand()%255,rand()%255,rand()%255);
// Проверка на пересечение с существующими окружностями(!IsIntersect(cir))_circles.push_back(cir); // Пересечения нет - ставим окружность
}TRUE;
}
// CSpheresDoc serializationCSpheresDoc::Serialize(CArchive& ar)
{(ar.IsStoring())
{
// TODO: add storing code here
}
{
// TODO: add loading code here
}
}
// CSpheresDoc diagnostics
#ifdef _DEBUGCSpheresDoc::AssertValid() const
{::AssertValid();
}CSpheresDoc::Dump(CDumpContext& dc) const
{::Dump(dc);
}
#endif //_DEBUG
// CSpheresDoc commandsCSpheresDoc::GetCircleIndex(const CPoint& pt) const
{(int i=(int)m_circles.size()-1; i >= 0; i--)( pow(pt.x-m_circles[i].pos.x,2) +(pt.y-m_circles[i].pos.y,2) < pow(m_circles[i].radius,2))i;-1;
}& CSpheresDoc::GetCircleById(int id)
{m_circles[id];
}
// Проверка на пересечение с существующими окружностями
bool CSpheresDoc::IsIntersect(Circle cir)
{(unsigned int i=0; i<m_circles.size(); i++)(sqrt(pow(cir.pos.x - m_circles[i].pos.x, 2) +(cir.pos.y - m_circles[i].pos.y, 2)) <=.radius+m_circles[i].radius)true;false;
}CSpheresDoc::DrawCircle(CDC *pDC)
{x, y, r;int min_drawable_radius=2;(unsigned int i=0; i<m_circles.size(); i++)
{= (int)m_circles[i].pos.x;= (int)m_circles[i].pos.y;= (int)max(m_circles[i].radius, min_drawable_radius);pen(PS_SOLID,1,m_circles[i].color);>SelectObject(&pen);>Ellipse(x-r,y-r,x+r,y+r);
}
}obn=false;mass[nCircles];CSpheresDoc::DoSimulation()
{ch=1;(!obn)
{(int i=0; i<nCircles; i++)[i]=-1;=true;
}(unsigned int i=0; i<m_circles.size(); i++)
{(mass[i]!=i)
{((m_circles[i].pos.x+m_circles[i].radius)>=bottom)
{[i]=i;_circles[i].color=RGB(rand()%255,rand()%255,rand()%255);_circles[i].pos.x -=ch;
}_circles[i].pos.x +=ch;
}
{((m_circles[i].pos.x-m_circles[i].radius)<=0)
{[i]=-1;_circles[i].color=RGB(rand()%255,rand()%255,rand()%255);_circles[i].pos.x +=ch;
}
{_circles[i].pos.x -=ch+3;_circles[i].radius=rand()%max_radius+min_radius;
}
}
}(NULL);
}
// SpheresView.h : interface of the CSpheresView class
//
#pragma onceCSpheresView : public CView
{: // create from serialization only();_DYNCREATE(CSpheresView)
// Attributes:* GetDocument() const;selected_circle;
// Operations:
// Overrides:void OnDraw(CDC* pDC); // overridden to draw this viewBOOL PreCreateWindow(CREATESTRUCT& cs);:
// Implementation:~CSpheresView();
#ifdef _DEBUGvoid AssertValid() const;void Dump(CDumpContext& dc) const;
#endif:
// Generated message map functions:_MESSAGE_MAP():_msg void OnTimer(UINT_PTR nIDEvent);_msg void OnLButtonDown(UINT nFlags, CPoint point);_msg void OnMouseMove(UINT nFlags, CPoint point);_msg void OnLButtonUp(UINT nFlags, CPoint point);_msg void OnActionStartsimulation();_msg void OnActionStopsimulation();_msg void OnRButtonDown(UINT nFlags, CPoint point);_msg void PopupMenuCircleProps();_msg void PopupMenuCircleColor();_msg void OnActionStopsimulaton();
};
#ifndef _DEBUG // debug version in SpheresView.cppCSpheresDoc* CSpheresView::GetDocument() const
{ return reinterpret_cast<CSpheresDoc*>(m_pDocument); }
#endif
// SpheresView.cpp : implementation of the CSpheresView class
//
#include "Spheres.h"
#include "SpheresDoc.h"
#include "SpheresView.h"
#include "DlgCircleProps.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CSpheresView_DYNCREATE(CSpheresView, CView)_MESSAGE_MAP(CSpheresView, CView)
// ON_WM_TIMER()_WM_LBUTTONDOWN()_WM_MOUSEMOVE()_WM_LBUTTONUP()
//ON_WM_CONTEXTMENU()_COMMAND(ID_ACTION_STARTSIMULATION, &CSpheresView::OnActionStartsimulation)_COMMAND(ID_ACTION_STOPSIMULATION, &CSpheresView::OnActionStopsimulation)_WM_TIMER()_WM_RBUTTONDOWN()_COMMAND(ID__PROPERTIES, &CSpheresView::PopupMenuCircleProps)_COMMAND(ID__COLOR, &CSpheresView::PopupMenuCircleColor)_COMMAND(ID_ACTION_STOPSIMULATON, &CSpheresView::OnActionStopsimulaton)_MESSAGE_MAP()
// CSpheresView construction/destruction::CSpheresView() : selected_circle(-1)
{
// TODO: add construction code here
}::~CSpheresView()
{
}CSpheresView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT csCView::PreCreateWindow(cs);
}
// CSpheresView drawingCSpheresView::OnDraw(CDC* pDC)
{
// Получение указателя на документ и проверка его валидности
CSpheresDoc* pDoc = GetDocument();_VALID(pDoc);(!pDoc);
// Рисование окружностей>DrawCircle(pDC);
}
// CSpheresView diagnostics
#ifdef _DEBUGCSpheresView::AssertValid() const
{::AssertValid();
}CSpheresView::Dump(CDumpContext& dc) const
{::Dump(dc);
}* CSpheresView::GetDocument() const // non-debug version is inline
{(m_pDocument->IsKindOf(RUNTIME_CLASS(CSpheresDoc)));(CSpheresDoc*)m_pDocument;
}
#endif //_DEBUGCSpheresView::OnLButtonDown(UINT nFlags, CPoint point)
{
// Получение указателя на документ и проверка его валидности
CSpheresDoc* pDoc = GetDocument();_VALID(pDoc);
if (!pDoc);
// Запросить индекс окружности, в которой находится точка
selected_circle = pDoc->GetCircleIndex(point);::OnLButtonDown(nFlags, point);
}CSpheresView::OnMouseMove(UINT nFlags, CPoint point)
{
// Получение указателя на документ и проверка его валидности
CSpheresDoc* pDoc = GetDocument();_VALID(pDoc);(!pDoc);(selected_circle != -1){
// Перемещение окружности в точку, указанную мышью
pDoc->GetCircleById(selected_circle).pos.x = point.x;>GetCircleById(selected_circle).pos.y = point.y;();
}::OnMouseMove(nFlags, point);
}CSpheresView::OnLButtonUp(UINT nFlags, CPoint point)
{_circle = -1;::OnLButtonUp(nFlags, point);
}CSpheresView::OnActionStartsimulation()
{(1,0,NULL);
}CSpheresView::OnActionStopsimulation()
{(1);
}CSpheresView::OnActionStopsimulaton()
{(1);
}CSpheresView::OnTimer(UINT_PTR nIDEvent)
{* pDoc = GetDocument();_VALID(pDoc);(!pDoc);>DoSimulation();::OnTimer(nIDEvent);
}CSpheresView::OnRButtonDown(UINT nFlags, CPoint point)
{* pDoc = GetDocument();_VALID(pDoc);(!pDoc);screen_point(point);(&screen_point);_circle = pDoc->GetCircleIndex(point);(selected_circle != -1) {
// Popup menupopup;.LoadMenu(IDR_MENU_POPUP);* real_menu=popup.GetSubMenu(0);_menu->TrackPopupMenu(TPM_LEFTALIGN,screen_point.x,screen_point.y,this);
}::OnRButtonDown(nFlags, point);
}CSpheresView::PopupMenuCircleProps()
{* pDoc = GetDocument();_VALID(pDoc);(!pDoc);
// Создание диалогаdlg;
// Инициализация данных диалога.m_radius=pDoc->GetCircleById(selected_circle).radius;
// Отображение диалога и проверка выхода по нажатию «ОК»(dlg.DoModal() == IDOK)
// Если радиус был изменён( pDoc->GetCircleById(selected_circle).radius != dlg.m_radius ) {
// Обновить радиус>GetCircleById(selected_circle).radius = dlg.m_radius;
// Перерисовать окно();
}CSpheresView::PopupMenuCircleColor()
{* pDoc = GetDocument();_VALID(pDoc);(!pDoc);dlg;(dlg.DoModal() == IDOK)( pDoc->GetCircleById(selected_circle).color != dlg.GetColor() ) {>GetCircleById(selected_circle).color = dlg.GetColor();
Invalidate();
}_circle = -1;
}