Програмування комп'ютерної графіки розрахункова робота

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
О
Факультет:
ЗІ
Кафедра:
Кафедра КСА

Інформація про роботу

Рік:
2024
Тип роботи:
Розрахункова робота
Предмет:
Програмування комп’ютерної графіки
Варіант:
3

Частина тексту файла (без зображень, графіків і формул):

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА” Кафедра КСА Пояснювальна записка до розрахункової роботи з курсу "Програмування комп'ютерної графіки" Перевірив: старший викладач Іванюк О.О. 1.1 Завдання Побудувати графік функції заданої таблично. Масштаб розмітки осей координат графіка повинен відповідати реальним результатам розрахунків. Параметри для побудови графіка визначені у таблиці 2. Необхідно передбачити плаваючий центр координат – основну частину екрану мають займати ті чверті, в яких знаходиться графік функції. ЗАВДАННЯ по графіку Таблиця 1 № варіанту Функція f(x) Діапазон зміни аргументу  3 z = tg(x) [-0.49*π ; 0.49*π]  Таблиця 2 № варіанту Тип лінії для побудови Товщина лінії Колір лінії  3  4 Red   1.2 Завдання Створити на екрані комп’ютера графічне вікно і сформувати в ньому рухоме зображення. Вікно розмістити у верхньому правому куті екрану. Навести межі вікна. Параметри зображення задані в пікселях. Графік і вікно з рухомим зображенням повинні присутні на екрані одночасно. ЗАВДАННЯ по анімації № варіанту Структура зображення Пояснення  23  Коло з чотирма спицями скочується по сходинках. Параметри: а = 40, L=70, d = 18.   2.1 Розрахунок функціональних залежностей для побудови графіка Оскільки реальні координати графіка функції, що виводиться на екран можуть бути або значно більшими, або значно меншими за машинні координати екрану монітору, не- обхідно визначити значення масштабних коефіцієнтів стискання або розтягу для функції, що виводиться на екран. Протабулюємо задану функцію на проміжку зміни аргументу з метою визначення максимального та мінімального значень функції і аргумента : xmax , xmin, zmax, zmin. Знайдемо значення масштабуючих коефіцієнтів: kx = (rectright - 50) / (xmax - xmin); kz = (rect.bottom - 50) / (zmax - zmin); де: rectright, rect.bottom – координати меж вікна. Використовуючи обчислені коефіцієнти побудуємо графік функції і осі координат, нанесемо розмітку. 2.2 Розрахунок матриці перетворень для рухомого зображення Для побудови зображень на екрані комп'ютера використовуються операції переносу, масптабування, повороту та їх композиції. У своєму завданні я вирішив скористатись формулами розрахунку повороту в полярних координатах. Це передусім повязано з простотою їх використання. Розрахунок повороту в полярних координатах можна виразити наступним чином : x = rd * sin(angle) + Mx y = -rd * cos(angle) + My де: angle – кут повороту; М(х,у) – точка відносно якої відбувається операція повороту. rd – радіус вектор. У циклі програми, який реалізує рух обєкта прямолінійно я скористався цими ж формулами: circleX = rd * sin(angle2) + rect.right - mx + step; circleY = -rd * cos(angle2) + rect.top + my; де: (rect.right – mx, rect.top + my) – координати точки відносно якої відбувається рух. Обчислення координати рухомої точки обчислюються при постійному значенні angle2 = 90 °: sin(angle2) = cos(angle2) = 1 Тому точка не повертається, а рухається прямолінійно. Координати вершин спиць, і координати цента при падінні обєкта обчислюються при змінному значенні кута angle. Тому в цьому випадку відбувається поворот точки на певний кут. 3. Список індетифікаторів програми Побудова графіка функції: rect – структура, в якій записані розміри екрана. rect.bottom, rect.right – нижня та права сторона вікна, відповідає за розміри клієнтського вікна. rect.top, rect.left – верхня та ліва сторона вікна, рівна 0. rectright – зміння яка задає ширину області для побудови графіка функції. str[192] – массив символів. kx, kz – коефініент перетворення координат. x0, z0 – мінімальне значення графіка в машинних координатах по осях x та y відповідно. x – змінна, з інтервалом зміни від x1 до x2 з кроком h. z – значення функції. lx, lz – довжина осі по x та z відповідно. sx, sz – ціле значення від розбиття осі на 10 частин по x та z відповідно. tx, tz – змінна, значення якої відповідає довжині додатної осі по x та від’ємної по z відповідно. xc, zc – центр графіка в точці x=0 по осях x та z відповідно. Плаваючий центр координат. xx, zz – змінна, яка відповідає за розбиття графіка на 10 частин по осях x та z відповідно. xmax , xmin, zmax, zmin – мінімальне та максимальне значення функції по осях x та z відповідно. txp, txm, tzp, tzm – змінні, які визначають положення тексту розмітки осей у додатному та від’мному напрямках x та z відповідно. Побудова анімації: j, k – змінні які використовуються в циклах if() i for(). rd – радіус кола зі спицями. h – крок. аngle – кут, який використовується в формулі прямолінійного руху кола. аngle2 – кут, який використовується в формулах які описують обертання спиць і падіння кола. step – крок, з яким рухається коло. circleX, circleY – координати центра кола. dxc1, dyc1, dxc2, dyc2, dxc3, dyc3, dxc4, dyc4 – координати точок спиць при обертанні навколо центра кола, ці точки лежать на дузі кола. mx, my – коефіцієнти, які разом із rect задають положення рухомого зображення. Використовуються в формулах прямолінійного руху кола. gx, gy – коефіцієнти які разом із rect задають положення рухомого зображення. Використовуються в формулах падіння кола. Команди і функції: GetClientRect(&rect) – команда для запису розмірів екрана в структуру rect. swprintf_s() – записує значення змінної в масив str. TextOut() – виводить значення змінної по заданих координатах. MoveTo(x, y) – переміщує поточну вершину, зміння x, y визначають координати нової поточнох вершини. LineTo(x, y) – будує лінію з поточної вершини у точку з еоординатами x, y. Rectangle(int x1, int y1, int x2, int y2) - малює прямокутник, x1, у1 задають координати верхнього лівого куга, a x2, у2 правого нижнього кута прямокутника. Ellipse(int x1, int y1, int x2, int y2) - малює еліпс, x1, у1 задають координати верхнього лівого куга, a x2, у2 правого нижнього кута прямокутника який визначає розміри еліпса. При використанні функцій «перо» , колір контуру еліпса задається «пером». Створює і задає перо з параметрами: CPen «імя»; «імя».CreatePen(«стиль пера», «товщина пера», «колір RGB»); dc.SelectObject(&«імя»). 5. Текст програми #include "stdafx.h" #include "PKG_V2.0.h" #include "ChildView.h" #define _USE_MATH_DEFINES //для використання M_PI #include <math.h> #ifdef _DEBUG #define new DEBUG_NEW #endif CChildView::CChildView() { } CChildView::~CChildView() { } BEGIN_MESSAGE_MAP(CChildView, CWnd) ON_WM_PAINT() END_MESSAGE_MAP() 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() { CPaintDC dc(this); RECT rect; GetClientRect(&rect); ////Побудова графіка функції//////////////////////////////////////////////////// wchar_t str[192]; double kx, kz, x0, z0, x, z, lx, lz, sx, sz, xc, zc, tx, tz, xx, zz, t; double xmax = 0, xmin = 0, zmax = 0, zmin = 0, txp = 0, txm = 0, tzp = 0, tzm = 0; double x1 = -0.49*M_PI, x2 = 0.49*M_PI, hh = 0.0005; double rectright = rect.right - 270; // Табулювання заданої функції на проміжку зміни аргументу з метою визначення максимального та мінімального значень функції for (x = x1; x <= x2; x = x + hh) { z = tan(x); if (zmin > -z) { zmin = -z; } else if (zmax<-z) { zmax = -z; } if (xmin>x) { xmin = x; } else if (xmax < x) { xmax = x; } } //знаходимо значення функції в точці x=0 x = 0; z = tan(x); //знаходимо коефіцієнти і центр реальних координат kx = (rectright - 50) / (xmax - xmin); kz = (rect.bottom - 50) / (zmax - zmin); x0 = xmin*kx - 25; z0 = zmin*kz - 25; xc = x*kx - x0; zc = -z*kz - z0; //Побудова осей //побудова Z dc.MoveTo(xc, rect.top + 10); dc.LineTo(xc, rect.bottom - 10); //побудова Х dc.MoveTo(rect.left + 10, zc); dc.LineTo(rectright - 10, zc); dc.MoveTo(xc - 5, rect.top + 15); // стрілка осі Z dc.LineTo(xc, rect.top + 10); dc.LineTo(xc + 5, rect.top + 15); dc.MoveTo(rectright - 15, zc - 5); // стрілка осі Х dc.LineTo(rectright - 10, zc); dc.LineTo(rectright - 15, zc + 5); //розмітка осей const CString Z("Z"), X("X"), O("0"); dc.TextOutW(xc - 20, rect.top + 5, Z); dc.TextOutW(rectright - 20, zc + 5, X); dc.TextOutW(xc + 5, zc + 5, O); lx = (rectright - 10) - (rect.left + 10); //довжини осей lz = (rect.bottom - 10) - (rect.top + 10); sx = floor(lx / 15); sz = floor(lz / 15); tx = rectright - fabs(x0); tz = rect.bottom - fabs(z0); xx = (xmax - xmin) / 15; zz = (zmax - zmin) / 15; //розмітка осі Х for (t = sx; t <= -x0 - 30; t = t + sx) //в відємному напрямі { txm = txm - xx; dc.MoveTo(xc - t, zc - 5); dc.LineTo(xc - t, zc + 5); swprintf_s(str, 50, L"%.1f", txm); dc.TextOut(xc - t - 10, zc + 5, str); } for (t = sx; t <= tx - 30; t = t + sx)//в додатньому напрямі { txp = txp + xx; dc.MoveTo(xc + t, zc - 5); dc.LineTo(xc + t, zc + 5); swprintf_s(str, 50, L"%.1f", txp); dc.TextOut(xc + t - 10, zc + 5, str); } //розмітка осі Z for (t = sz; t <= -z0 - 15; t = t + sz)//в додатньому напрямі { tzp = tzp + zz; dc.MoveTo(xc - 5, zc - t); dc.LineTo(xc + 5, zc - t); swprintf_s(str, 50, L"%.1f", tzp /57, 29578); dc.TextOut(xc + 10, zc - t - 10, str); } for (t = sz; t <= tz - 15; t = t + sz)//в відємному напрямі { tzm = tzm - zz; dc.MoveTo(xc - 5, zc + t); dc.LineTo(xc + 5, zc + t); swprintf_s(str, 50, L"%.1f", tzm / 57, 29578); dc.TextOut(xc + 10, zc + t - 10, str); } CPen dRED; dRED.CreatePen(PS_DASH, 1.9, RGB(255, 0, 0)); dc.SelectObject(&dRED); //побудова графіка for (x = x1; x <= x2; x = x + hh) { z = tan(x); if (x == x1) { dc.MoveTo(x*kx - x0, -z*kz - z0); } dc.LineTo(x*kx - x0, -z*kz - z0); } //Побудова анімації///////////////////////////////////////////////////////////// int j, k; double rd = 9, h = 0.3; double angle, step, circleX, circleY; double dxc1, dyc1, dxc2, dyc2, dxc3, dyc3, dxc4, dyc4; double mx, my, gx, gy; double angle2 = 3.1415 / 2; dc.SelectStockObject(BLACK_PEN); dc.Rectangle(rect.right - 263, rect.top + 12, rect.right - 12, rect.top + 176); dc.MoveTo(rect.right - 235, rect.top + 41); dc.LineTo(rect.right - 215, rect.top + 41); dc.LineTo(rect.right - 215, rect.top + 81); dc.LineTo(rect.right - 145, rect.top + 81); dc.LineTo(rect.right - 145, rect.top + 121); dc.LineTo(rect.right - 75, rect.top + 121); dc.LineTo(rect.right - 75, rect.top + 161); dc.LineTo(rect.right - 39, rect.top + 161); for (int g = 0; g < 7;g++) { for (j = 0; j <= 2; j++) { if (j == 0) { k = 1; mx = 243.5; my = 33; gx = 208; gy = 32; } if (j == 1) { k = 2; mx = 200; my = 73; gx = 138; gy = 72; } if (j == 2) { k = 2; mx = 129.37; my = 113; gx = 68.73; gy = 112; } //рух вправо for (angle = 0; angle <= 3.1415 * k; angle += h / 8) { step = angle * 8; circleX = rd * sin(angle2) + rect.right - mx + step; circleY = -rd * cos(angle2) + rect.top + my; dxc1 = rd * sin(angle) + circleX; dyc1 = -rd * cos(angle) + circleY; dxc2 = rd * sin(angle + 3.1415 / 2) + circleX; dyc2 = -rd * cos(angle + 3.1415 / 2) + circleY; dxc3 = rd * sin(angle + 3.1415) + circleX; dyc3 = -rd * cos(angle + 3.1415) + circleY; dxc4 = rd * sin(angle + 3.1415 + 3.1415 / 2) + circleX; dyc4 = -rd * cos(angle + 3.1415 + 3.1415 / 2) + circleY; dc.SelectStockObject(BLACK_PEN); dc.Ellipse(circleX - rd, circleY - rd, circleX + rd, circleY + rd); dc.MoveTo(circleX, circleY); dc.LineTo(dxc1, dyc1); dc.MoveTo(circleX, circleY); dc.LineTo(dxc2, dyc2); dc.MoveTo(circleX, circleY); dc.LineTo(dxc3, dyc3); dc.MoveTo(circleX, circleY); dc.LineTo(dxc4, dyc4); Sleep(10); dc.SelectStockObject(WHITE_PEN); dc.Ellipse(circleX - rd, circleY - rd, circleX + rd, circleY + rd); dc.MoveTo(circleX, circleY); dc.LineTo(dxc1, dyc1); dc.MoveTo(circleX, circleY); dc.LineTo(dxc2, dyc2); dc.MoveTo(circleX, circleY); dc.LineTo(dxc3, dyc3); dc.MoveTo(circleX, circleY); dc.LineTo(dxc4, dyc4); } //падіння for (angle = 0; angle <= 3.1415 / 2; angle += h / 20) { step = angle * 8; circleX = rd * sin(angle) + rect.right - gx + step / 1.5; circleY = -rd * cos(angle) + rect.top + gy + rd + step*2.5; dxc1 = rd * sin(angle - 3.1415 / 2) + circleX; dyc1 = -rd * cos(angle - 3.1415 / 2) + circleY; dxc2 = rd * sin(angle + 3.1415) + circleX; dyc2 = -rd * cos(angle + 3.1415) + circleY; dxc3 = rd * sin(angle + 3.1415 + 3.1415 + 3.1415 / 2) + circleX; dyc3 = -rd * cos(angle + 3.1415 + 3.1415 + 3.1415 / 2) + circleY; dxc4 = rd * sin(angle + 3.1415 * 2) + circleX; dyc4 = -rd * cos(angle + 3.1415 * 2) + circleY; dc.SelectStockObject(BLACK_PEN); dc.Ellipse(circleX - rd, circleY - rd, circleX + rd, circleY + rd); dc.MoveTo(circleX, circleY); dc.LineTo(dxc1, dyc1); dc.MoveTo(circleX, circleY); dc.LineTo(dxc2, dyc2); dc.MoveTo(circleX, circleY); dc.LineTo(dxc3, dyc3); dc.MoveTo(circleX, circleY); dc.LineTo(dxc4, dyc4); Sleep(10); dc.SelectStockObject(WHITE_PEN); dc.Ellipse(circleX - rd, circleY - rd, circleX + rd, circleY + rd); dc.MoveTo(circleX, circleY); dc.LineTo(dxc1, dyc1); dc.MoveTo(circleX, circleY); dc.LineTo(dxc2, dyc2); dc.MoveTo(circleX, circleY); dc.LineTo(dxc3, dyc3); dc.MoveTo(circleX, circleY); dc.LineTo(dxc4, dyc4); } } } } 6.Отриманий результат  7.ВИСНОВОК Виконавши завдання даної роботи я набув практичних навиків в складанні програми для побудови зображень на екрані комп’ютера в середовищі Microsoft Visual Studio C++ 2008. Ключовим моментом у програмуванні анімації є точне визначення матриць руху чи обертання реперних точок фігури та максимально точне обчислення координат подальшого положення фігури з метою уникнення похибок, які можуть суттєво погіршити результат. Суть анімації – зміна положення предмета з “затиранням” попереднього положення. 4. Блок-схема програми        
Антиботан аватар за замовчуванням

12.04.2016 18:04-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!