Лабораторна робота № 8

Тема. Контроль видимості елементів зображення

 

Вступ

Аналіз результатів виконання попередньої лабораторної роботи показує, що в зображенні можуть виникнути некоректності, пов'язані з відображенням елементів, які повинні бути в глибині чи невидимі, поверх елементів, які знаходяться ближче до спостерігача. Причина некоректності відсутність аналізу відносно розміщення елементів по об'єму простору і методів усунення невидимих ліній. Лінії відображались на екрані у відповідності з чітко заданою послідовністю в програмі, а не з їх природною послідовністю розміщення по глибині моделюючого простору.

Завдання контролю видимості (усунення невидимих ліній) виявилась для машинного вирішення досить складним і потребуючим підвищеної витрати машинного часу й оперативної пам'яті. Основна причина в тому, що в загальному випадку кожен із елементів змодельованого в тривимірному просторі об'єкта може бути закритий, під час спостереження, будь-яким іншим елементом. Тому під час збільшення кількості елементів кількість їх взаємних співставлень збільшується в квадраті. До теперішнього часу розроблений ряд методів і алгоритмів вирішення подібного завдання: алгоритм Галімберті і Монтанарі, алгоритм Варнока, алгоритм Уоткінса, алгоритм Ньюелла, Ньюелла і Санча, алгоритм плаваючого горизонту, алгоритм Роберта, алгоритм Вейлера-Азертона і ін. Для прикладу коротко розглянемо сутність алгорптма Уоткінса, а потім алгоритму Ньюелла, Ньюелла і Санча.

Алгоритм Уоткінса застосовується в терміналах із телевізійною розгорткою зображення. Відображаючий об'єкт подумки розсікається площинами, перпендикулярними поверхні екрану, паралельними одна одній і проходячими по стрічках розгортки. Кожна така площина визначає сукупність відрізків прямих, являючи собою результат перетину граней відображаючого об'єкта з даною площиною. Для формування зображення в кожній площині аналізується ця сукупність відрізків і визначається їх положення відносно користувача. Оскільки відрізки, розміщені спереду, закривають повністю чи частково відрізки, розміщені ззаду, то досить накреслити на лінії розгортки тільки частини відрізків, які видно спостерігачу.

Ідея алгоритму Ньелла, Ньюелла і Санча досить проста. Спочатку визначається порядок розміщення всіх граней зображаючого об'єкта по віддаленості від спостерігача. Далі всі грані почергово зображаються на екрані в порядку їх наближення до спостерігача, що приводить до природного відображення перекриттів граней.

Як зазначалося вище, контроль видимості є досить складним завданням і потребує великої обчислювальної потужності від комп'ютера. Вказані алгоритми реалізуються зазвичай спеціально розробленими графічними програмними пакетами чи спеціально створеними графічними мікропроцесорами, що обладнуються спеціалізованими комп'ютерами, які називаються графічними станціями (ще одна їх відмінність від інших комп'ютерів − великий екран).

Опис середовища програмування

У міру складності вирішення завдання контролю видимості елементів обмежимося найпростішим варіантом, який передбачає, що користувач сам визначає умови коректного відображення моделюючого об'єкта на екрані і явно це фіксує в ревізуючій програмі.

Приклад програми. Аналіз прикладу, реалізованого в попередній лабораторній роботі, показує, що некоректність має місце під час співпадання на екрані зображень лінії 1 і 2. При цьому лінія 2 знаходиться далі по осі X, але зображається поверх лінії 1 згідно з фіксованим порядком алгоритму програми. Для ускладнення завдання задамо зсув всієї системи по осі X на 120 пікселів, що приводить і до перекриття віссю Y лінії 2 в процесі обертання. Усунути некоректність можна зміною порядку викреслювання ліній 1, 2 і вісі Y. Поки значення координати X лінії 2 позитивне зберігається порядок, встановлений в попередній лабораторній роботі, а при від'ємних значеннях лінія 2 відображається після лінії 1 і осі Y. Для зменшення лістингу програми вводиться процедура відображення кожної лінії і осі Y.

Лістинг програми

Program Lr9;

uses {підключення потрібних модулів}

Graph, Crt;

var

GraphDriver:integer; {номер графічного драйвера}

GraphMode:integer; {номер графічного підрежиму}

mx, my:word; {параметри масштабування зображення}

k:real; {коефіцієнт масштабування зображення}

х11, х12, у11, у12, z11, z12:integer; {координати лінії 1 в локальній системі координат}

х21, х22, у21, у22, z21, z22:integer; {початкові координати лінії 2 в локальній системі координат}

х21у, х22у, у21у, у22у, z21y, z22y:real; {координати лінії 2 в локальній системі координат після повороту навколо осі Y}

х11m, x12m:integer; {координати кінців лінії 1 по осі X після зсуву }

x21m, x22m:integer; {координати кінців лінії 2 по осі X після зсуву}

dx, dy:integer; {зміщення глобальної тривимірної системи координат відносно координатної системи екрана}

ay:real; {кут повороту лінії 2 відносно осі Y в радіанах}

i:integer; {змінна циклу}

sx:real; {зсув локальної тривимірної системи координат відносно глобальної}

ns:byte; {номер графічної сторінки}

procedure KY; {процедура викреслювання осі Y}

begin

SetColor(15); {установка кольору для зображення осі}

SetLineStyle(0, 0, 1); {установка товщини ліній для зображення координатної осі}

Line(320, 200, 580, 316);

Line(580, 316, 574, 308);

Line(580, 316, 569, 316);

end;

procedure L1; {процедура викреслювання лінії 1}

begin

SetLineStyle(0, 0, 3); {установка товщини ліній для зображення переміщуючихся елементів}

SetColor(8); {установка кольору лінії 1}

Line(dx+Round(0.71*(у11-х11m)), dy+Round(k*0.82*(-z11+0.5*(x11m+у11))),         dx+Round(0.71*(у12-х12m)), dy+Round(k*0.82*(-z12+0.5*(x12m+y12))));

end;

procedure L2; {процедура викреслювання лінії 2}

begin

SetLineStyle(0, 0, 3); {установка товщини ліній дня зображення переміщуючихся елементів}

SetColor(13); {установка кольору лінії 2}

Line(dx+Round(0.71*(у21у-х21m)), dy+Round(k*0.82*(-z21y+0.5*(x21m+у21у))), dx+Round(0.71 *(y22y-x22m)), dy+Round(k*0.82*(-22y+0.5*(x22m+y22y))));

end;

begin

GraphDriver:=3;

GraphMode:=l;

InitGraph(GraphDriver, GraphMode,"); {запуск графічного режиму}

GetAspectRatio(mx, my); {визначення параметрів масштабування}

k;=mx/my; {визначення коефіцієнта масштабування}

dx:=320; {задання положення глобальної тривимірної системи координат відносно координатної системи екрана}

dy:=200;

sx:=50; {задания початкового положення локальної тривимірної системи координат відносно глобальної}

ns;=0; {установка номера активної графічної сторінки}

SetTexJustify(0,0); {установка стилю вирівнювання тексту}

SetTextStyle(0, 0, 1); {установка стилю тексту}

х11:=0; {координати лінії 1 в локальній системі координат}

y11:=0;

z11:=0;

x12:=0;

у12:= 100;

z12:=0;

x21:=-50; {координати лінії 2 в локальній системі координат}

у21:=0;

z21:=0;

х22:=-50;

у22:=100;

z22:=0;

for і:=0 to 360 do {цикл по куту повороту лінії 2 навколо лінії 1}

begin

ау:=3.14*і/180; {переведення кута повороту в радіани}

if ns=0 then {зміна активної і видимої графічних сторінок}

begin

SetActivePage(0);

SetVisualPage(1)

end

else

begin

SetActivePage(1);

SetVisualPage(0)

end;

SetBkColor(9); {установка кольору фону зображення}

ClearDevice; {очищення активної сторінки}

SetColor(15); {установка кольору для зображення координатних осей}

SetLineStyle(0, 0, 1); {установка товщини ліній для зображення координатних осей}

Line(320, 200, 320, 10); {відображення координатних осей X и Z}

Line(320, 10, 315, 20);

Line(320, 10, 325, 20);

Line(320, 200, 60, 316);

Line(60, 316, 66, 308);

Line(60, 316, 71, 316);

SetColor(4); {установка кольору для відображення назв осей}

OutTextXY(587, 316, 'Y'); {відображення назв осей}

OutTextXY(310, 10, 'Z');

OutTextXY(50, 316, 'X');

x11m:=Round(x11+sx); {координати лінії 1 по осі X після чергового зсуву}

х12m:=Round(x12+sx);

x21y:=x21*cos(ay)+z21*sin(ay); {розрахунок координат лінії 2 в локальній тривимірній системі після повороту навколо осі Y}

у21у:=у21;

z21y:=-x21 *sin(ay)+z21*cos(ay);

x22y:=x22*cos(ay)+z22*sin(ay);

y22y:=y22;

z22y:=-x22*sin(ay)+z22*cos(ay);

x21m:=Round(x21y+sx); {координати лінії 2 після чергового зсуву по осі X}

x22m:=Round(x22y+sx);

if x21m>0 then {порядок викреслювання елементів при позитивних значеннях координати X лінії 2}

begin

KY;

L1;

L2;

end

else

begin {порядок викреслювання елементів при від'ємних значеннях координати X лінії 2}

L2;

L1;

KY;

еnd;

if ns=0 then {зміна номера активної графічної сторінки}

ns:=1

else

ns:=0;

sx:=sx+0.333; {перетворення зсуву локальної тривимірної системи відносно глобальної по осі X}

Delay(100); {затримка зображення на кожному кроці переміщення}

End;

Readln; {зупинка зображення до натиснення будь-якої кнопки}

Closegraph; {вихід із графічного режиму}

end.

Варіанти завдань. Проаналізувати результат виконання попередньої лабораторної роботи на предмет некоректності зображення. За відсутності останньої потрібно змінити завдання так, щоб з'явилась потреба в контролі видимості елементів. Визначити умову(и) коректного зображення моделюючого об'єкта.

 

Зміст звіту

1)                    Зміст завдання;

2)                    лістинг програми:

3)                    надруковане зображення.

 

Контрольні питання

1.                     Чи можна розв'язати завдання, розглянуту як приклад, без застосування апарату процедур?

2.                     Який з розглянутих алгоритмів контролю видимості елементів: Уоткінса чи Ньюелла, Ньюелла і Санча, − більш ефективний (потребує менших обчислювальних затрат) під час виконання даної лабораторної роботи?

3.                     Яка з тривимірних проекцій потребує найменших обчислювальних затрат під час контролю видимості елементів?

4.                     Які комп'ютери називаються графічними робочими станціями?

5.                     За яким математичним законом збільшується кількість взаємних співставлень моделюючих елементів на екрані об'єкта?