Міністерство освіти і науки, молоді та спорту України
Національний університет «Львівська політехніка»
Звіт
лабораторної роботи № 4
з курсу «Програмування комп’ютерної графіки»
Мета: вивчити функції для управління кольорами та стилями графічних зображень, навчитися складати програми на алгоритмічній мові С++ для побудови різноманітних графічних зображень в середовищі Microsoft Visual Studio C++ 2008.
Завдання:
Домашня підготовка до роботи.
Вивчити основні графічні процедури і функції алгоритмічної мови для побудови рухомих зображень.
Написати програму на алгоритмічній мові С++, яка виводить на екран рухоме графічне зображення. Варіанти завдань брати за вказівкою викладача з таблиці 1.
Робота в лабораторії.
Ввести в комп’ютер програму написану на мові С++ згідно з отриманим завданням.
Здійснити відлагодження введеної програми, виправивши виявлені компілятором помилки.
Виконати програму. Текст відлагодженої програми та отримані результати оформити в звіт по лабораторній роботі.
Таблиця 1.
Варіант
Зображення
Опис
8
/
Рух сектора проти годинникової стрілки. Кольори заливки сектора змінюються (7 кольорів).
R = 40; φ = 30˚.
Зміст звіту:
Повний текст завдання.
Блок-схема алгоритму програми.
Список ідентифікаторів констант, змінних, процедур і функцій, використовуваних в програмі та їх пояснення.
Остаточно відлагоджений текст програми згідно з отриманим завданням.
Результат виконання програми.
2. Блок-схема алгоритму програми.
Рис. 1
/
/
3. Список ідентифікаторів констант, змінних, процедур і функцій, використовуваних в програмі та їх пояснення.
h_brush – пензель;
h_Pen – перо товщиною 2 рх;
CPen – функція для створення пера;
LineTo – проводить лінію з поточної вершини до точки, координати якої задані;
MoveTo – переміщує поточну вершину;
FloodFill – зафарбовує замкнуту область;
SelectObject – вибирає потрібний пензль або перо;
DeleteObject - видаляє потрібний пензль або перо;
GetClientRect – визначення параметрів екрану користувача;
Vec – структура для повороту координати;
Rotate – функція повороту координати;
Segment – функція побудови сегменту;
unSegment – функція приховування сегменту;
FloodSegment – функція зафарбовування сегменту;
unFloodSegment – функція приховування кольору заливки сегменту;
Center - центр повороту;
Angle - кут повороту в радіанах;
x, y – машинні координати;
xc, yc – координати центру екрану;
sleeptime = 200; - час спання;
R = 40; - змінна радіусу;
k = 80; - кількість сегментів;
seg_angle = 30 * 3.1415926535897932384626433832795/180; - Величина кута;
color_R[7] = {0, 0, 204, 204, 0, 255, 255}; - масив з палітрою R для заливки сегмента;
color_G[7] = {51, 204, 204, 0, 204, 0, 255}; - масив з палітрою G для заливки сегмента;
color_B[7] = {204, 51, 0, 204, 204, 51, 0}; - масив з палітрою B для заливки сегмента;
color_pos_x[80]; - координата для заливки Х;
color_pos_y[80]; - координата для заливки У;
4. Остаточно відлагоджений текст програми згідно з отриманим завданням.
Вміст файлу ChildView.cpp
// ChildView.cpp : implementation of the CChildView class
//
#include "stdafx.h"
#include "lr1.h"
#include "ChildView.h"
#include <cmath>
#include "seg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
/* Функція розрахунку координат для повороту фігури*/
struct Vec
{
double x;
double y;
};
// Center - центр повороту
// Angle - в радіанах
Vec Rotate(const Vec& Center, double Angle, const Vec& Point)
{
double dx = Point.x - Center.x;
double dy = Point.y - Center.y;
Vec Res;
Res.x = Center.x + cos(Angle) * dx + sin(Angle) * dy;
Res.y = Center.y - sin(Angle) * dx + cos(Angle) * dy;
return Res;
}
// CChildView
CChildView::CChildView()
{
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
// CChildView message handlers
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);
return TRUE;
}
void CChildView::OnPaint()
{
SEGdc dcc(this); // device context for painting
double xc, yc; // змінні центральних координат.
int sleeptime = 200; // час спання
double R = 40; // змінна радіусу.
int k = 80; //кількість сегментів.
double seg_angle = 30 * 3.1415926535897932384626433832795/180; //Величина кута.
int color_R[7] = {0, 0, 204, 204, 0, 255, 255}; // масив з палітрою R для заливки сегмента
int color_G[7] = {51, 204, 204, 0, 204, 0, 255}; // масив з палітрою G для заливки сегмента
int color_B[7] = {204, 51, 0, 204, 204, 51, 0}; // масив з палітрою B для заливки сегмента
double color_pos_x[80]; // координата для заливки Х
double color_pos_y[80]; // координата для заливки У
RECT rect;
GetClientRect(&rect);
xc = (rect.right - rect.left)/2;
yc = (rect.bottom - rect.top)/2;
double sc_oldpos_x = xc, sc_oldpos_y = yc - R/2; // змінні кородинат
/* Розрахунок координат для зафарбовування області сегменту і занесення їх в масив*/
for (int i = 0; i < k; i++) {
Vec Center = { xc, yc };
Vec OldPos = { sc_oldpos_x, sc_oldpos_y };
if (i == 0) {
Vec NewPos = Rotate(Center, seg_angle/2, OldPos);
sc_oldpos_x = NewPos.x;
sc_oldpos_y = NewPos.y;
color_pos_x[i] = NewPos.x;
color_pos_y[i] = NewPos.y;
}
else {
Vec NewPos = Rotate(Center, seg_angle, OldPos);
sc_oldpos_x = NewPos.x;
sc_oldpos_y = NewPos.y;
color_pos_x[i] = NewPos.x;
color_pos_y[i] = NewPos.y;
}
}
/* Розрахунок координат і побудова сегменту*/
sc_oldpos_x = xc, sc_oldpos_y = yc - R;
int j = 0;
for (int i = 0; i < k; i++) {
if (j == 7)
j = 0;
Vec Center = { xc, yc };
Vec OldPos = { sc_oldpos_x, sc_oldpos_y };
Vec NewPos = Rotate(Center, seg_angle, OldPos);
sc_oldpos_x = NewPos.x;
sc_oldpos_y = NewPos.y;
dcc.Segment(OldPos.x, OldPos.y, NewPos.x, NewPos.y, Center.x, Center.y, R, RGB(0,0,0));
dcc.FloodSegment(color_pos_x[i], color_pos_y[i],RGB(color_R[j],color_G[j],color_B[j]));
j++;
Sleep(sleeptime);
//
if (i != k-1) {
dcc.unSegment(OldPos.x, OldPos.y, NewPos.x, NewPos.y, Center.x, Center.y, R, RGB(255,255,255));
dcc.unFloodSegment(color_pos_x[i], color_pos_y[i]);
}
}
}
Вміст файлу seg.cpp
#include "stdafx.h"
#include "seg.h"
SEGdc::SEGdc(CWnd *pWnd):CPaintDC(pWnd)
{
}
void SEGdc::Segment(int x1, int y1, int x2, int y2, int x3, int y3, int r,COLORREF cl)
{
CPen h_pen;
h_pen.CreatePen(PS_SOLID,2,cl);
SelectObject(h_pen);
MoveTo (x2, y2);
LineTo (x3, y3);
MoveTo (x1, y1);
LineTo (x3, y3);
Arc(x3-r, y3-r, x3+r, y3+r, x1, y1, x2, y2);
}
void SEGdc::unSegment(int x1, int y1, int x2, int y2, int x3, int y3, int r,COLORREF cl)
{
CPen h_pen;
h_pen.CreatePen(PS_SOLID,2,cl);
SelectObject(h_pen);
MoveTo (x2, y2);
LineTo (x3, y3);
MoveTo (x1, y1);
LineTo (x3, y3);
Arc(x3-r, y3-r, x3+r, y3+r, x1, y1, x2, y2);
}
void SEGdc::FloodSegment(int x, int y,COLORREF cl)
{
CBrush h_brush;
h_brush.CreateSolidBrush(cl);
SelectObject(&h_brush);
FloodFill(x,y,RGB(0,0,0));
h_brush.DeleteObject();
}
void SEGdc::unFloodSegment(int x, int y)
{
CBrush h_brush;
h_brush.CreateSolidBrush(RGB(255,255,255));
SelectObject(&h_brush);
FloodFill(x,y,RGB(0,0,0));
h_brush.DeleteObject();
}
Вміст файлу seg.h
class SEGdc: public CPaintDC
{
public:
SEGdc(CWnd* pWnd);
void Segment(int x1, int y1, int x2, int y2, int x3, int y3, int r,COLORREF cl);
void unSegment(int x1, int y1, int x2, int y2, int x3, int y3, int r,COLORREF cl);
void FloodSegment(int x, int y,COLORREF cl);
void unFloodSegment(int x, int y);
};
5. Результат виконання програми.
Рис. 2
/