Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Коссак графіка.doc
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
6 Мб
Скачать
☆

View(0,90);

axis([-0.5 2 -0.5 2])

Рис. 5.18. Одиничний куб Рис. 5.19. Результат

Відповідно, можна побудувати функцію, яка дає матрицю центральної проекції:

function M = cen_proj(d)

M = [1 0 0 0;

0 1 0 0;

0 0 0 0;

0 0 1/d 1];

Використовуємо цю функцію разом з командою hgtransform, то немає необхідності нормалізувати нові координати, оскільки це виконуватиметься автоматично.

Нехай початкову форму описують такі оператори, які задають форму 1, що зображена на рисунку 5.18:

vertex = [0 1 1 0 0 0 1 1;

0 0 1 1 1 0 0 1;

0 0 0 0 1 1 1 1];

facesm = [1 2 3 4;5 6 7 8;3 4 5 8;1 2 7 6;2 3 8 7;1 4 5 6];

View(3)

h = patch('Vertices',vertex','Faces',facesm,'FaceVertexCData', [0 0 1],'FaceColor','flat')

Центральну проекцію з центром проектування в точці (0,0,-2) (d = 10) можна отримати, як результат наступного М–файла у вигляді форм 2 і 3, які зображені на рис. 5.20 і 5.21.

ax = axes;

vertex = [0 1 1 0 0 0 1 1;

0 0 1 1 1 0 0 1;

0 0 0 0 1 1 1 1];

facesm = [1 2 3 4;5 6 7 8;3 4 5 8;1 2 7 6;2 3 8 7;1 4 5 6];

h=patch('Vertices',vertex','Faces',facesm,'FaceVertexCData', [0 0 1],'FaceColor','flat')

t = hgtransform('Parent',ax);

set(h,'Parent',t);

M = cen_proj(2);

set(t,'Matrix',M);

axis([-0.5 2 -0.5 2])

Рис. 5.20.Форма 2. Рис. 5.21 Форма 3.

5.4. Вирізання

Система Matlab має відповідні функції, які можуть задовольнити будь-які потреби. Вирізання не відрізняється від інших функцій. Проте тут необхідно визначити розміри вікна, що можна зробити за допомогою команди axis. Коли вікно означено, можна лише спостерігати за його змістом. Якщо ж збільшувати розміри вікна, то можна побачити частини рисунка, які спочатку були приховані. В такий спосіб Matlab виконує свого роду автоматичне вирізання, яке можливе лише у разі прямокутного вирізання.

Постає питання: чи можливо виконати будь-яке обрізання? Так, можливо лише в тому випадку, якщо створити відповідний m–файл. Тут створені функції будуть працювати лише для окремих випадків побудови рисунків.

Такі дії можна виконувати за двома підходами. Перший полягає у тому, що треба мати постійно доступними всі необхідні дані й застосовувати відповідні функції для отримання результату. Другий – ґрунтується на тому, що форму, яку будемо обрізати, треба мати збереженою в файлі рисунку, підтримуваного Matlab, і використовувати зміну кольорів пікселів поза ділянкою обрізання. Нижче наведено деякі алгоритми обрізання з використанням різних підходів.

5.4.1. Алгоритми вирізання

Для досягнення ефекту вирізання використовують відомі алгоритми, спеціально розроблені з цією метою. Найвідоміші з них такі:

  • середньої точки

  • Коена–Сазерленда

  • Лянга–Барського.

Уведення цих алгоритмів у Matlab є не легким завданням, оскільки весь час треба мати доступною велику кількість інформації, записану в коректній формі. Для ліпшого розуміння розглянемо задачу вирізання і шляхи її розв’язування. Ця специфічна проблема спочатку виглядає складною, однак насправді вона є тривіальним випадком без особливих ускладнень, бо об’єкт складається лише з сегментів ліній, а вікно обрізання прямокутне.

Розглянемо приклад, який допоможе ліпше зрозуміти ці алгоритми. В колі, радіусом R рівномірно розташуємо N точок:

при R=15см., N=30.

Пов’яжемо кожну пару зі всіма іншими , j=1,2…,N, i≠j. Якщо i≥j, то точка не буде пов’язана з , оскільки це вже зроблено в протилежному напрямі. Отриманий рисунок буде обрізаний квадратом зі стороною 15 см. і центром, який збігається з центром кола.

Цю проблему можна вирішити розв’язуватися різними шляхами. Перший полягає в використанні алгоритму Лянга–Барського за допомогою трьох М–файлів, у яких усі елементи задані а сторони вікон є паралельні осям та . Програмний код цих трьох файлів для розв’язування задачі такий:

function crop(n)

AK = [];

%--- Creation and planning of initial form -----

korif(1,1:n) = 15 * cos ((2 * pi * (0:(n-1))/ n));

korif(2,1:n) = 15 * sin ((2 * pi * (0:(n-1))/n));

for i = 1 : (n-1)

for j = (i + 1) : n

AK = [AK;[korif(:,i)' korif(:,j)']];

end

end

clf

hold on

for i = 1 : size(AK,1)

plot([AK(i,1) AK(i,3)],[AK(i,2) AK(i,4)])

end

axis equal

%--------- Coordinates of window -------------------

q = (15 * sqrt(2)) /2;

w=[q q -q q;-q q -q -q;-q -q q -q;q -q q q];

%------------- Beginning of process of clipping-----------

for i=1:4

pause(1)

figure(i+1)

k = 1;

while k <= size(AK,1)

e1 = emfanes(w(i,:),AK(k,[1 2]));

e2 = emfanes(w(i,:),AK(k,[3 4]));

if e1 + e2 == 2

k = k + 1;

elseif e1 + e2 == 0

AK(k,:) = [];

elseif e1 == 0

AK(k,[1 2]) = ST(w(i,:),AK(k,:));

k = k + 1;

elseif e2 == 0

AK(k,[3 4]) = ST(w(i,:),AK(k,:));

k = k + 1;

end

end

%--------------- Planning individual graphic -----------

hold on

for i = 1 : size(AK,1)

plot([AK(i,1) AK(i,3)],[AK(i,2) AK(i,4)])

end

axis equal

end

function P = ST(L1,L2)

P = [0 0];

dx = L2(3) - L2(1);

dy = L2(4) - L2(2);

if L1(1) == L1(3)

P(1) = L1(1);

P(2) = L2(2) + (dy * (P(1) - L2(1)) / dx);

else

P(2) = L1(2);

P(1) = L2(1) + (dx * (P(2) - L2(2)) / dy);

end

function e = emfanes(L,P)

if L(1) == L(3)

if L(4) > L(2)

if P(1) <= L(1)

e = 1;

else

e = 0;

end

else

if P(1) >= L(1)

e = 1;

else

e = 0;

end

end

else

if L(3) > L(1)

if P(2) >= L(2)

e = 1;

else

e = 0;

end

else

if P(2) <= L(2)

e = 1;

else

e = 0;

end

end

end

Описанівище функції виконують таке:

  • Функція Crop малює рисунок з n вершинами так:

1) утворює матрицю (під назвою AK), яка містить усі координати вершин, що пов’язані між собою;

2) створює координатні вікна;

3) викликає інші функції для отримання вирізання.

  • Функція ST обчислює постійно точки перетину ліній.

  • Функція emfanes перевіряє, чи точка P лежить на видимій півплощині. Повертає 1, якщо точка видима, і 0 в іншому випадку.

Для того, щоб розв’язати задачу, достатньо в командній стрічці Matlab записати таку команду:

>>crop(30);

Результат програми зображено на рис. 5.22. Такий підхід не є універсальним, бо залежить від вхідних даних про об’єкт. Тому постає питання: якщо треба вирізати деяку картинку, для якої немає достатньої кількості відомих елементів, то чинити?

Рис. 5.22. Результат обрізання