Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Малювання геометричних фігур
Функція малювання крапки. Функція SetPixel встановлює колір crColor в точці (x, y): COLORREF SetPixel (HDC hdc, int x, int y, COLORREF crColor); Приклад. Задача. " Зафарбувати" червоним кольором точку на початку системи координат (0, 0). Розв‘язок. SetPixel(hdc, 0, 0, RGB(255, 0, 0)); Функція GetPixel повертає колір точки (х, у). COLORREF GetPixel(HDC hdc, int x, int y); За допомогою наступних трьох макрокоманд можна визначити значення кольорових компонент кольора rgb: #define GetRValue(rgb) ((BYTE)(rgb)) #define GetGValue(rgb) ((BYTE)(((WORD)(rgb))> > 8)) #define GetBValue(rgb) ((BYTE)((rgb)> > 16)) Функції малювання ліній. При малюванні ліній активно використовують значення поточної позиції пера. Поточну позицію обирає функція GetCurrentPositionEx: BOOL GetCurrentPositionEx(HDC hdc, LPPOINT lpPoint); Щоб намалювати пряму лінію, викликають функцію LineTo: BOOL LineTo(HDC hdc, int x, int y); Приклад. Задача. Намалювати графік функції 25*cos(x) для х, яке змінюється від 0 до 31.4159. Розв‘язок (графік функції). #include " Functions.h" #include < math.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HINSTANCE hInstance; char szClassName[]=" GraphClass"; typedef struct {char name[10]; float x[100]; float y[100]; } FUNC; INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT nCmdShow) { MSG msg; HWND hwnd;:: hInstance=hInstance; if (! RegClass(WndProc, szClass, COLOR_WINDOW)) return FALSE; hwnd=CreateWindow (szClass, " Графік сінуса", WS_OVERLAPPEDWINDOW| WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, NULL); if (! hwnd) return FALSE; while (GetMessage(& msg, NULL, 0, 0)) DispatchMessage(& msg); return(int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {static short cx, cy; static FUNC myfunc; switch(msg) {case WM_SIZE: {c[=LOWORD(lParam); cy=HIWORD(lParam); return 0; } case WM_CREATE: {strcpy(myfunc.name, " 25*cos(x)"); for (int i=0; i< 100; i++) {myfunc.x[i]=(float)(0.31415926535*i); myfunc.y[i]=(float)(25*cos(myfunc.x[i])); } return 0; } case WM_PAINT: {PAINTSTRUCT ps; HDC hdc=BeginPaint(hwnd, & ps); //Задаємо область для побудови графіку int x0=cx/10, //Лівий край графіку xr=cx-x0, //Правий край графіку y0=cy/10, //Верхній край графіку yc=cy/2, //Середина графку за віссю Y amp=yc-y0; //Амплітуда графіку на екрані float ymax=0., //Максимум функції ymin=0.; //Мінімум функції //Виводимо назву функції TextOut(hdc, x0+4, y0/3, myfunc.name, strlen(myfunc.name)); //Виводимо назву змінної TextOut(hdc, xr+x0/2, yc+y0/10, " t", 1); //Будуємо вісь ординат MoveToEx(hdc, x0, cy-y0+y0/2, NULL); LineTo(hdc, x0, y0-y0/2); //Будуємо вісь абсцис MoveToEx(hdc, x), yc, NULL); LineTo(hdc, xr+x0/2, yc); //Визначаємо максимум і мінімум функції for (int i=0; i< 100; i++) {float ycurr=myfunc.y[i]; if (ycurr> =0. & & ymax< ycurr) ymax=ycurr; else if (ymin> ycurr) ymin=ycurr; } if (ymax< fabs(ymin)) ymax=(float)fabs(ymin); //Встановлюємо масштаб за віссю Y float dy=(float) amp/ymax; //Встановлюємо масштаб за віссю Х float dx=(float) (xr-x0)/(myfunc.x[99]-myfunc.x[0]); //Для малювання створюємо перо синього кольору HPEN hPen=CreatePen(PS_SOLID, 2, RGB(0, 0, 255)); HPEN hOldPen=(HPEN) SelectObject(hdc, hPen); //Встановлюємо курсор в першу точку графіку MoveToEx(hdc, x0, (int)(yc-dy*myfunc.y[0], NULL); //Виводимо лінії від попередньої точки до поточної for (i=1; i< 100; i++) {//Обчислюємо координати поточої точки int xcurr=(int)(dx*(myfunc.x[i]-myfunc.x[0])+x0), ycurr=(int)(yc-dy*myfunc.y[i]); //Малюємо пряму до поточної точки LineTo(hdc, xcurr, ycurr); } SelectObject(hdc, hOldPen); DeleteObject(hPen); EndPaint(hwnd, & ps); return 0; } case WM_DESTROY: {PostQuitMessage(0); return 0; } } return DefWindowProc(hwnd, msg, wParam, lParam); } Функція Arc малює дугу елліпса або кола: BOOL Arc(HDC hdc, int l, int t, int r, int b, int x0, int y0, int x, int y); Рис.4.1 тлумачить геометричний зміст параметрів функції Arc.
Рис.4.1. Геометрична інтерпретація параметрів функції Arc. Функція Polyline з'єднує прямими cPoints точок, координати яких вказані в масиві lppt: BOOL Polyline(HDC hdc, CONST POINT *lppt, int cPoints); Приклад. Задача. Поверхню, обмежену елліпсом, розділити на 3 сектори з умовними долями 62, 5, 12, 5 та 25%. Розв‘язок (елліптична діаграма). #include " Functions.h" #include < math.h> #define PI 3.1415926535 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HINSTANCE hInstance; char szClass[]=" LinesClass"; INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT nCmdShow) { MSG msg; HWND hwnd;:: hInstance=hInstance; if (! RegClass(WndProc, szClass, COLOR_WINDOW)) return FALSE; hwnd=CreateWindow (szClass, " Елліптична діаграма", WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, NULL); if (! hwnd) return FALSE; while (GetMessage(& msg, NULL, 0, 0)) DispatchMessage(& msg); return(int)msg.wParam; } BOOL DrawLine(HDC hdc, int x0, int y0, int x, int y) {MoveToEx(hdc, x0, y0, NULL); return LineTo(hdc, x, y); } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {static short cx, cy; switch(msg) {case WM_SIZE: {c[=LOWORD(lParam); cy=HIWORD(lParam); return 0; } case WM_PAINT: {PAINTSTRUCT ps; HDC hdc=BeginPaint(hwnd, & ps); //Задаємо область для побудови елліпсу intl0=cx/10, //Лівий край елліпсу r=cx-l, //Правий край елліпсу t=cy/10, //Верхній край елліпсу b=cy-t, //Нижній край елліпсу yc=cy/2; //Центр елліпсу за віссю Y xc=cx/2, //Центр елліпсу за віссю Х int x0=(int)(xc+0.5*(r-l)), y0=yc, x=(int)(xc+0.5*(r-l)*cos(2.*PI*0.625)), y=(int)(yc-0.5*(b-t)*sin(2.*PI*0.625)); //Малюємо пряму лінію DrawLine(hdc, xc, yc, x0, y0); //Малюємо дугу елліпсу Arc(hdc, l, t, r, b, x0, y0, x, y); x0=x; y0=y; //Запам'ятовуємо координати точки //Виводимо текст x=(int)(xc+0.4*cx*cos(2.*PI*0.3125)); y=(int)(yc-0.4*cy*sin(2.*pi*0.3125)); TextOut(hdc, x, y, " 62.5%", 6); //Малюємо пряму лінію DrawLine(hdc, xc, yc, x0, y0); x=(int)(xc+0.5*(r-l)*cos(2.*PI*0.75)); y=(int)(yc-0.5*(b-t)*sin(2.*PI*0.75)); //Малюємо дугу елліпсу Arc(hdc, l, t, r, b, x0, y0, x, y); x0=x; y0=y; //Запам'ятовуємо координати точки //Виводимо текст x=(int)(xc+0.4*cx*cos(2.*PI*0.6875)); y=(int)(yc-0.4*cy*sin(2.*pi*0.6875)); TextOut(hdc, x, y, " 12.5%", 6); //Малюємо пряму лінію DrawLine(hdc, xc, yc, x0, y0); x=(int)(xc+0.5*(r-l)*cos(2.*PI)); y=(int)(yc-0.5*(b-t)*sin(2.*PI)); //Малюємо дугу елліпсу Arc(hdc, l, t, r, b, x0, y0, x, y); //Виводимо текст x=(int)(xc+0.4*cx*cos(2.*PI*0.875)); y=(int)(yc-0.4*cy*sin(2.*pi*0.875)); TextOut(hdc, x, y, " 25%", 4); EndPaint(hwnd, & ps); return 0; } case WM_DESTROY: {PostQuitMessage(0); return 0; } } return DefWindowProc(hwnd, msg, wParam, lParam); } Функції малювання замкнених фігур. Функції малювання замкнених фігур будують зафарбовані або незафарбовані фігури, такі, як прямокутники, елліпси, багатокутники з прямими та заокругленими кутами і т.д. Для зафарбування внутрішньої області замкнених фігур використовують пензль контексту відображення. Зовнішній контур фігури обводять пером контексту відображення. В залежності від стилю пера границя фігури може знаходитись повністю всередині заданого зовнішнього контура або виходити за його межі. Для малювання прямокутника викликають функцію Rectangle: BOOL Rectangle(HDC hdc, int l, int t, int r, int b); Функція RoundRect малює прямокутник з заокругленими кутами: BOOL RoundRect(HDC hdc, int l, int t, int r, int b, int w, int h); Функція FillRect зафарбовує прямокутну область вікна: int FillRect(HDC hdc, CONST RECT *lprc, HBRUSH hbr); Функція FrameRect мал.є прямокутну рамку: int FrameRect(HDC hdc, CONST RECT *lprc, HBRUSH hbr); Функція InvertRect інвертує значення кольорів точок прямокутної області lprc: BOOL InvertRect(HDC hdc, CONST RECT *lprc); Функція DrawFocusRect пунктиром позначає границі прямокутної області lprc: BOOL DrawFocusRect(HDC hdc, CONST RECT *lprc); Для малювання елліпса викликають функцію Ellipse: BOOL Ellipse(HDC hdc, int l, int t, int r, int b); Сегмент елліпса малюють функцією Chord: BOOL Chord(HDC hdc, int l, int t, int r, int b, int x0, int y0, int x, int y); Для малювання сектора елліпса використовують функцію Pie: BOOL Pie(HDC hdc, int l, int t, int r, int b, int x0, int y0, int x, int y); Функція Polygon малює багатокутник: BOOL Polygon(HDC hdc, CONST POINT *lpPoints, int nCount);
IІ. ЗМІСТ ЗВІТУ 1. Тема, мета, умова завдання. 2. Опис команд, за допомогою яких було виконано завдання, і результатів їх виконання. 3. Висновок. ІІІ. ЗАВДАННЯ Написати програму мовою програмування C++ з використанням GDI для реалізації завдання згідно варіанту. 1. Від лівого верхнього до нижнього правого кута робочої області вікна вивести текст таким чином, щоб він повністю розташовувався у вікні при будь-яких змінах розмірів вікна. Використовувати шрифт Times New Roman Cyr. 2. У вікні додатку багаторазово відобразити текст " Привіт!!! " напівжирним шрифтом Arial Cyr. Вивід тексту починати від нижнього краю вікна і продовжувати до верхнього краю, плавно змінюючи колір тексту від жовтого до чорного і колір фону від синього до жовтого. При цьому текст повинен повністю поміщатись по ширині при будь-яких розмірах вікна. 3. В центрі вікна намалювати елліптичну діаграму. Діаграму розбити на сектори 25, 65 та 10% червоного, зеленого блактиного кольорів та вказати по центру дуги кожного сектора відсотки. При всіх змінах розмірів вікна діаграма повинна бути відображена повністю. 4. Розробити вікно перегортання таблиці. Причому у вікна завжди відображати заголовки стовпців. Перший стовпець повинен містити номери рядків, а інші стовпці - дійсні числа, урізані до шести значущих цифр. Малювати стільки рядків і стовпців, скільки без урізання поміщаються у вікні. 5. У вікні додатку відобразити рейтинг учасників якоїсь події: для кожного учасника намалювати геометричне тіло, висота якого пропорційна рейтингу учасника, нижче фігури вивести прізвище учасника, вище - рейтинг у відсотках. Причому текст повинен бути набраний під деяким кутом. Для всіх учасників використовувати різні кольори. 6. У вікні додатку вивести текст " Анкета" російською мовою і строго під ним " Anketa" англійською мовою, першу літеру " А" збільшити в розмірі і зробити спільною для обох слів. Літеру " А" вивести червоним кольором, залишок слова російською мовою - синім, англійською - зеленим. При цьому текст, який виводиться, повинен займати всю висоту або ширину вікна при будь-яких розмірах вікна. 7. Текст заголовку вікна відобразити червоним кольором на фоні заголовку, а правіше цього тексту намалювати синій елліпс, вписаний в зелений прямокутник шириною в 3 смуги заголовку. 8. В робочій області знизу догори багатократно відобразити рядок " Пробний текст", плавно змінюючи фон і колір і збільшуючи висоту на насиченість шрифта. Вивід центрувати по горизонталі. Початкову висоту шрифта взяти за замовчуванням. Вивід завершується, якщо черговий рядок по висоті не поміщається в робочій області. 9. У вікні додатку в 3 стовпчики вивести привітання. В лівому і правому стовпцях розмір шрифта повинен зростати згори донизу, а в середньому - знизу догори. Кольори виводу повинні бути різні при клжному виводі тексту. У випадку перекриття текстів різних стовпців текст не повинен стиратись, причому правий стовпець може перкривати лівий, а середній - обидва стовпці. 10. В центрі вікна намалювати мішень з 10 полів і в кожному полі вивести його значення (від 1 від краю до 10 в центрі). При будь-яких змінах розмірів вікна мішень повинна повністю відображатись у вікні. Поля розфарбувати випадково обраними різними кольорами. 11. У вікні відобразити чорним кольором вісі координат та синім кольором графік функції c*cos(x), де х приймає значення від 0 до 10p і с¹ 0. Розмах виводу по осях ординат і абсцис - 90% розмірів вікна при будь-яких змінах розмірів. 12. Центр робочої області займає маліновий прямокутник з вписаним блакитним елліпсом розміром в половину області за осями. Після натискання лівої кнопки миші це місце займає синій прямокутник, а правої клавіші - зелений елліпс. При зміні розміру вікна повернутись до початкового стану. 13. Описати функцію, яка у вказаному прямокутнику будує елліптичну діаграму. Кількість секторів, їх доля в процентах та кольори зафарбування також передаються аргументами виклику функції. 14. Розмалювати робочу область вікна в різнокольорові клітинки, окреслені чорним кольором, плавно переходячи від червоного кольора в лівому верхньому куті вікна до синього в нижньому правому куті. 15. В центрі екрану створити квадратне вікно з текстом заголовку і стилю WS_POPUPWINDOW. У вікні намалювати шахматну дошку та позначити поля. При натисканні лівої кнопки миші над полем дошки повідомити ім'я поля. 16. В робочій частині вікна при русі миші з натиснутою лівою кнопкою малювати траєкторію руху курсора миші. При натисканні правої кнопки миші помніяти колір для малювання. 17. Робочу область зафарбувати спектром кольорів, починаючи зліва червоним кольором і закінчуючи синім на правому краю. Колір змінювати в 4 етапи: на першому етапі, при максимальній червоній складовій, збільшувати зелену, на другому, при максимальному зеленому, зменшувати червону складову, потім, при максимальному зеленому, збільшувати синю складову і, на останньому етапі, при максимальному синьому зменшити зелену складову. 18. У вікна відобразити клітинки для гри в хрестики-нолики. Прр натисканні лівої кнопки миші в клітинці намалювати хрестик, а правої - нолик. Заборонити заповняти клітинку більше одного разу. 19. Намалювати світлофор, в якому колір " засвічується" при натисканні на цю лампу лівою кнопкою миші. Одночасно може горіти лише один колір. 20. У вікні за допомогою миші виділити прямокутник і створити ефект мерехтіння цього прямокутника. 21. Намалювати декілька геометричних фігур. При натисканні лівої кнопки миші над будь-якою з них показати, що обрана ця фігура. 22. Намалювати графік функції: 2*a*cos(a). 23. В робочій області вікна пензлем за замовчуванням в метричній системі координат намалювати елліпс. 24. Створити вікно зі смугами перегляду та забезпечити перегляд всього вмісту таблиці. 25. Розробити функцію виводу тексту в заданій позиції зі спеціальним ефектом. Ефект полягає в тому, що текст повільно " випливає" зліва направо. Використовуючи цю функцію, відобразити рейтинги учасників деякої події. 26. В робочій області вікна пензлем за замовчуванням в метричній системі координат намалювати прямокутник. 27. У вікні за допомогою миші виділити елліпс і створити ефект мерехтіння цього елліпса. 28. Намалювати графік функції 5*a*sin(a). 29. Розробити функцію виводу тексту в заданій позиції зі спеціальним ефектом. Ефект полягає в тому, що текст повільно " випливає" зправа наліво. Використовуючи цю функцію, відобразити рейтинги учасників деякої події. 30. В центрі вікна намалювати елліптичну діаграму. Діаграму розбити на сектори 20, 60 та 12% червоного, зеленого блактиного кольорів та вказати по центру дуги кожного сектора відсотки. При всіх змінах розмірів вікна діаграма повинна бути відображена повністю.
IV. КОНТРОЛЬНІ ПИТАННЯ 1. Які особливості виводу у вікно? 2. Які кроки мітсить обробка повідомлення WM_PAINT? 3. Як вивоядть у вікно при обробці будь-яких повідомлень? 4. Які види контексту відображення існує? Основні атрибути контексту відображення. 5. З яких кроків складається процедру вибору нового шрифта в контекст відображення? 6. Які функції використовують при малюванні точок, ліній? 7. Як замальовують замкнені фігури?
|