
- •6.080200 – «Інформатика»
- •Лабораторна робота № 3
- •Тема. Функції рисування графічних зображень з використанням різних растрових операцій
- •Мета роботи: ознайомитися з функціями рисування графічних зображень за допомогою бібліотеки opengl.
- •Короткі теоретичні відомості
- •Хід роботи
- •Завдання
- •Контрольні питання
- •Лабораторна робота № 4 Тема. Відображення фігур зі зміною атрибутів
- •Короткі теоретичні відомості
- •Хід роботи
- •Хід роботи
- •Хід роботи
- •Хід роботи
- •Завдання
- •Контрольні питання
- •Лабораторна робота № 9
- •Короткі теоретичні відомості
- •Хід роботи
- •Завдання
- •Контрольні питання
- •Список літератури
- •39614, М. Кременчук, вул. Першотравнева, 20
Хід роботи
У растрових системах прямі лінії будуються за допомогою пікселів, а розмір кроку в горизонтальному і вертикальному напрямках обмежується розбіжністю пікселів. Це означає, що потрібно "провести вибірку" точок прямої лінії з дискретними значеннями і визначити пікселі, найближчі до даної прямої для кожного елементу вибірки. У середовищі VC розглянемо алгоритми перетворення стандартів розгортки прямої.
1.
Цифровий
диференційний аналізатор (ЦДА)
— це алгоритм перетворення стандартів
розгортки прямої лінії, оснований на
обчисленні або
за
рівнянням
або
за
рівнянням
.
Пряма розбивається на одиничні відрізки
по одній
координаті, а для іншої координати
визначаються відповідні цілі значення,
найближчі до даної прямої.
#include <stdlib.h>
#include <math.h>
inline int round (const float а) {
return int (а + 0.5); }
void lineDDA (int x0, int y0, int xEnd, int yEnd){
int dx = xEnd-x0, dy = yEnd-y0, steps, k;
float xIncrement, yIncrement, x = x0, y = y0;
if (abs (dx) > abs (dy))
steps = abs (dx);
else
steps = abs (dy);
xIncrement = float (dx) / float (steps);
yIncrement = float (dy) / float (steps);
setPixel (round (x), round (y));
for (k =0; k < steps; k++){
x += xIncrement;
y += yIncrement;
setPixel (round (x), round (y));
}
}
2. Растровий алгоритм створення прямих ліній розроблений Брезенхемом (Bresenham), у ньому обчислюються тільки цілочислові значення приростів. Крім того, алгоритм побудови прямих Брезенхема можна адаптувати для зображення кіл та інших кривих.
Реалізація алгоритму побудови прямої лінії Брезенхема для тангенса кута нахилу в діапазоні 0 < т < 1 наведена в наступній процедурі. Тут вводяться координати кінців відрізка, а пікселі відображаються від лівого кінця до правого.
#include <stdlib.h>
#include <math.h>
/* Процедура побудови відрізка (Брезенхема) для |m|<1,0.*/
void lineBres (int x0, int y0, int xEnd, int yEnd){
int dx = abs (xEnd-x0), dy = abs(yEnd-y0);
int p = 2 * dy - dx;
int twoDy = 2 * dy, twoDyMinusDx = 2 * (dy-dx);
int x, y;
/*Визначається, який кінець взяти як початкове *положення. */
if (x0 > xEnd) {
x = xEnd;
y = yEnd;
xEnd = x0;
}
else {
x = x0;
y = y0;
}
setPixel (x, y);
while (x < xEnd) {
х++;
if (P < 0)
р += twoDy;
else {
y++;
р += twoDyMinusDx;}
setPixel (x, y);
}
}
/* Процедура для відображення точки*/
Void setPixel (int xCoord, int yCoord){
glBegin (GL_POINTS);
glVertex2i(xCoord, yCoord);
glEnd();
}
Завдання
Вивчити теоретичний| матеріал| щодо| теми лабораторної| роботи|.
Відповісти на контрольні| запитання|.
Зробіть звіт про результати роботи кожного прикладу|зразка| програми, розглянутого|розглядувати| в лабораторній роботі.
Побудуйте на площині три довільні точки.
Перевірте роботу алгоритмів побудови прямих, додавши необхідні дані.
Контрольні питання|
Що таке ЦДА?
Чим відрізняються алгоритми побудови прямої лінії?
Які функції OPENGL використовуються для побудови відрізків та ліній?
Як побудувати точку та масив точок?
Для чого призначена функція glVertex?
Література: [3–6].
Лабораторна робота № 5
Тема. Робота з бітовими образами
Мета роботи: ознайомитися з функціями бітового відображення, функціями піксельного відображення та растровими операціями на прикладі побудови кіл та еліпсів.
Короткі теоретичні відомості
Для побудови кола можна використовувати алгоритм побудови методом середньої точки. Побудова зводиться до того, що лінія розбивається на одиничні інтервали і на кожному кроці визначаються координати пікселів, які знаходяться щонайближче до заданого кола. При відомому радіусі r і координатах центра кола на екрані (хс, ус) спочатку можна організувати алгоритм так, щоб розрахувати координати пікселів навколо кола з центром на початку координат (0, 0). Після цього кожне розраховане положення (х, у) переміщається у відповідну йому точку на екрані, для цього хс додається до х, ус — до у. На дузі кола від х = 0 до х = у у першому квадранті тангенс кута нахилу кривої змінюється з 0 до –1. Таким чином, у цьому октанті можна брати одиничний крок у додатному напрямку координати х і на основі параметра схвалення рішення визначати, який з пікселів у кожному стовпці знаходиться ближче по вертикалі до заданого кола. Після цього знаходяться координати пікселів у решті семи октантів. Алгоритм включає наступні кроки:
Увести радіус r і координати центра кола (хс, ус), потім задати координати першої точки на колі, центр якого знаходиться на початку координат: (x0,y0)=(0,r).
Знайти початкове значення параметра схвалення рішення: p0=5/4-r.
Для кожного значення хk, починаючи з k = 0, виконати наступну перевірку.
Якщо pk < 0, то наступна точка на колі з центром у точці (0, 0) буде (хk+1,уk) та pk+1=pk+2xk+1+1.
Інакше наступною точкою на колі буде (хk + 1, уk — 1) і pk+1=pk+2xk+1+1-
-2yk+1 де 2xk+1=2xk+2 та 2yk+1=2yk -2.
Знайти симетричні точки в решті семи октантів.
Перемістити всі розраховані пікселі з координатами (х, у) на коло з центром у точці з координатами (хс, ус) і відмітити точки з координатами
x=x+xc, y=y+yc.
Повторювати етапи з 3-го по 5-й до тих пір, поки не буде х у.
Еліпс можна також описати як модифіковане коло, радіус якого змінюється від максимального значення в одному напрямку до мінімального значення в перпендикулярному напрямку.
Точне визначення еліпса можна дати, скориставшись відстанями від будь-якої точки еліпса до двох фіксованих точок, які називаються його фокусами. Сума цих двох відстаней однакова для всіх точок еліпса. Якщо відстані від двох фокусів до будь-якої точки Р = (х, у) еліпса позначити d1 і d2, тоді загальне рівняння еліпса можна записати як d1+ d2=const.
Функція бітового відображення OPENGL.
Масив бінарного узору задається за допомогою функції:
glBitmap(width, height, x0, y0, xOffset, yOffset, bitShape);
Параметрами width і height функції є відповідно кількість стовпців і рядків у масиві bitShape. Кожному елементу масиву bitShape присвоюється значення 1 або 0. Значення 1 указує на те, що відповідний піксель слід зображати заздалегідь заданим кольором. Інакше бітове відображення не змінює значення пікселя. (Як варіант, значення 1 може вказувати, що заданий колір слід накласти на код кольору, записаний у буфері кадру в цьому положенні). Параметри х0 і у0 визначають точку, яку слід розглядати як "початок координат" прямокутного масиву. Ця точка відліку задається щодо лівого нижнього кута масиву bitShape, а значення х0 і у0 можуть бути як додатними, так і від’ємними. Потрібно задати положення буфера кадру, з якого починається накладення даного узору. Це положення називається поточним растровим положенням, і зображення бітового масиву полягає в перенесенні його початку координат (х0, у0) в поточне растрове положення. Після зображення бітового масиву значення, що присвоюються параметрам xOffset і yOffset, використовуються як зсуви координат для оновлення поточного растрового положення у буфері кадру.
Значення координат х0, у0, xOffset і yOffset, а також поточне растрове положення зберігаються у вигляді чисел з плаваючою комою. Координати у вигляді чисел з плаваючою комою дозволяють розміщувати бітове відображення через довільні інтервали.
Щоб задати координати поточного растрового положення, застосовується наступна процедура:
glRasterPos* ()
Параметри й індекси аналогічні тим, які використовуються у функції glVertex. Поточне растрове положення задається в зовнішніх координатах, а потім перетвориться в екранні координати за допомогою зміни точки спостереження. За замовчанням значення поточного растрового положення збігається з початком відліку (0, 0, 0) зовнішньої системи координат.
Кольором бітового відображення є поточний колір на момент виклику команди glRasterPos. Будь-які подальші зміни кольору не впливають на бітовий масив.
Кожен рядок прямокутного бітового масиву записується у вигляді чисел, розмір яких кратний 8 бітам, де бінарні дані організовані у вигляді 8-бітових символів без знака. Фігуру також можна описати за допомогою сітки будь-якого іншого зручного розміру. Коли узор накладається на пікселі в буфері кадру, усі значення бітів за межами останнього стовпця ігноруються.
Приклад коду накладення бітового узору на певну ділянку буфера кадру.
GLubyte bitShape [20] = {Oxlc, 0x00, Oxlc, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, Oxff, 0x80, 0x7f, 0x00, ОхЗе, 0x00, Oxlc, 0x00, 0x08, 0x00};
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
/* Встановлюється режим зберігання пікселів. */
glRasterPos2i (30, 40);
glBitmap (9, 10, 0.0, 0.0, 20.0, 15.0, bitShape);
Значення масиву bitShape задаються по рядках, починаючи з нижнього краю прямокутної сітки узору. Потім встановлюється режим зберігання бітового відображення за допомогою стандартної процедури OPENGL glPixelStorei. Значення 1 у цій функції вказує на те, що задані значення слід розташовувати по межах байтів. За допомогою функції glRasterPos встановлюється поточне растрове положення з координатами (30, 40). Функція glBitmap вказує, що бітовий узор задається у вигляді масиву bitShape і що цей масив складається з 9 стовпців і 10 рядків. Координати точки відліку цього узору — (0.0, 0.0), тобто вона знаходиться у лівому нижньому куту сітки.