Algorytmy grafiki rastrowej. Mirosław Głowacki Wykład z Grafiki Komputerowej

Podobne dokumenty
Algorytmy grafiki rastrowej. Mirosław Głowacki Wykład z Grafiki Komputerowej

WYKŁAD 3 WYPEŁNIANIE OBSZARÓW. Plan wykładu: 1. Wypełnianie wieloboku

Grafika komputerowa Wykład 2 Algorytmy rastrowe

Definicja obrotu: Definicja elementów obrotu:

KGGiBM GRAFIKA INŻYNIERSKA Rok III, sem. VI, sem IV SN WILiŚ Rok akademicki 2011/2012

Metody numeryczne I Równania nieliniowe

Rysowanie precyzyjne. Polecenie:

Plan wykładu. Wykład 3. Rzutowanie prostokątne, widoki, przekroje, kłady. Rzutowanie prostokątne - geneza. Rzutowanie prostokątne - geneza

Matematyka licea ogólnokształcące, technika

PRÓBNA MATURA ZADANIA PRZYKŁADOWE

Funkcja kwadratowa. f(x) = ax 2 + bx + c = a

Funkcja kwadratowa. f(x) = ax 2 + bx + c,

PRÓBNA MATURA ZADANIA PRZYKŁADOWE

FUNKCJA LINIOWA - WYKRES. y = ax + b. a i b to współczynniki funkcji, które mają wartości liczbowe

FUNKCJE I RÓWNANIA KWADRATOWE. Lekcja 78. Pojęcie i wykres funkcji kwadratowej str

Obcinanie prymitywów. Mirosław Głowacki Wydział Inżynierii Metali i Informatyki Przemysłowej AGH

Obliczenia iteracyjne

Przykład Łuk ze ściągiem, obciążenie styczne. D A

FUNKCJA LINIOWA, RÓWNANIA I UKŁADY RÓWNAŃ LINIOWYCH

KONKURS ZOSTAŃ PITAGORASEM MUM. Podstawowe własności figur geometrycznych na płaszczyźnie

Arkusz maturalny nr 2 poziom podstawowy ZADANIA ZAMKNIĘTE. Rozwiązania. Wartość bezwzględna jest odległością na osi liczbowej.

FUNKCJA LINIOWA - WYKRES

6. FUNKCJE. f: X Y, y = f(x).

3. FUNKCJA LINIOWA. gdzie ; ół,.

Rozwiązania zadań. Arkusz maturalny z matematyki nr 1 POZIOM PODSTAWOWY

Geometria. Hiperbola

Rozwiązywanie równań nieliniowych

Łożysko z pochyleniami

RÓWNANIA NIELINIOWE Maciej Patan

Liczby zespolone. x + 2 = 0.

. Funkcja ta maleje dla ( ) Zadanie 1 str. 180 b) i c) Zadanie 2 str. 180 a) i b)

1 Równania nieliniowe

Geometria. Rozwiązania niektórych zadań z listy 2

Kolektor. Zagadnienia. Wyciągnięcia po profilach, Lustro, Szyk. Wykonajmy model kolektora jak na rys. 1.

PRZEKROJE RYSUNKOWE CZ.1 PRZEKROJE PROSTE. Opracował : Robert Urbanik Zespół Szkół Mechanicznych w Opolu

Zad.3. Jakub Trojgo i Jakub Wieczorek. 14 grudnia 2013

1) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 16) 17) 18) 19) 20) 21) 22) 23) 24) 25)

Funkcja liniowa i prosta podsumowanie

Funkcje wymierne. Funkcja homograficzna. Równania i nierówności wymierne.

AUTOCAD teoria i zadania z podstaw rysowania Rysowanie linii, prostej, półprostej, punktu, trasy, polilinii. Zadania geodezyjne.

str 1 WYMAGANIA EDUKACYJNE ( ) - matematyka - poziom podstawowy Dariusz Drabczyk

Ćwiczenia nr 7. TEMATYKA: Krzywe Bézier a

WYKŁAD 10. kodem pierwotnym krzywej jest ciąg par współrzędnych x, y kolejnych punktów krzywej: (x 1, y 1 ), (x 2, y 2 ),...

Grafika Komputerowa. Algorytmy rastrowe

SIMR 2016/2017, Analiza 2, wykład 1, Przestrzeń wektorowa

Informatyk i matematyk: dwa spojrzenia na jedno zadanie (studium przypadku) Krzysztof Ciebiera, Krzysztof Diks, Paweł Strzelecki

1 Wstęp teoretyczny. Temat: Obcinanie odcinków do prostokąta. Grafika komputerowa 2D. Instrukcja laboratoryjna Prostokąt obcinający

Wprowadzenie Metoda bisekcji Metoda regula falsi Metoda siecznych Metoda stycznych RÓWNANIA NIELINIOWE

Wstęp do metod numerycznych Rozwiazywanie równań algebraicznych. P. F. Góra

KURS WSPOMAGAJĄCY PRZYGOTOWANIA DO MATURY Z MATEMATYKI ZDAJ MATMĘ NA MAKSA. przyjmuje wartości większe od funkcji dokładnie w przedziale

A. fałszywa dla każdej liczby x.b. prawdziwa dla C. prawdziwa dla D. prawdziwa dla

Grafika Komputerowa Materiały Laboratoryjne

KORESPONDENCYJNY KURS Z MATEMATYKI. PRACA KONTROLNA nr 1

Ekstrema globalne funkcji

TWORZENIE OBIEKTÓW GRAFICZNYCH

========================= Zapisujemy naszą funkcję kwadratową w postaci kanonicznej: 2

Przekształcanie wykresów.

Materiały pomocnicze z programu AutoCAD 2014.

GEOMETRIA ELEMENTARNA

- biegunowy(kołowy) - kursor wykonuje skok w kierunku tymczasowych linii konstrukcyjnych;

MECHANIKA 2 KINEMATYKA. Wykład Nr 5 RUCH KULISTY I RUCH OGÓLNY BRYŁY. Prowadzący: dr Krzysztof Polko

1. A 2. A 3. B 4. B 5. C 6. B 7. B 8. D 9. A 10. D 11. C 12. D 13. B 14. D 15. C 16. C 17. C 18. B 19. D 20. C 21. C 22. D 23. D 24. A 25.

ZAGADNIENIA PROGRAMOWE I WYMAGANIA EDUKACYJNE DO TESTU PRZYROSTU KOMPETENCJI Z MATEMATYKI DLA UCZNIA KLASY II

Wprowadzenie do rysowania w 3D. Praca w środowisku 3D

Macierze. Rozdział Działania na macierzach

Definicja i własności wartości bezwzględnej.

9. Podstawowe narzędzia matematyczne analiz przestrzennych

narzędzie Linia. 2. W polu koloru kliknij kolor, którego chcesz użyć. 3. Aby coś narysować, przeciągnij wskaźnikiem w obszarze rysowania.

Przykład projektowania łuku poziomego nr 1 z symetrycznymi klotoidami, łuku poziomego nr 2 z niesymetrycznymi klotoidami i krzywej esowej ł

Przedmiotowe zasady oceniania i wymagania edukacyjne z matematyki dla klasy drugiej gimnazjum

Zadania do samodzielnego rozwiązania zestaw 11

Projekt Era inżyniera pewna lokata na przyszłość jest współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego


RZUT CECHOWANY DACHY, NASYPY, WYKOPY

W. Guzicki Zadanie 21 z Informatora Maturalnego poziom rozszerzony 1

I V X L C D M. Przykłady liczb niewymiernych: 3; 2

WYMAGANIA EDUKACYJNE Z MATEMATYKI DLA KLASY TRZECIEJ NA ROK SZKOLNY 2011/2012 DO PROGRAMU MATEMATYKA Z PLUSEM

11. Znajdż równanie prostej prostopadłej do prostej k i przechodzącej przez punkt A = (2;2).

FUNKCJA KWADRATOWA. 1. Definicje i przydatne wzory. lub trójmianem kwadratowym nazywamy funkcję postaci: f(x) = ax 2 + bx + c

PLANIMETRIA CZYLI GEOMETRIA PŁASZCZYZNY CZ. 1

MATEMATYKA KLASY III gimnazjum LICZBY I WYRAŻENIA ALGEBRAICZNE

PRÓBNY ARKUSZ MATURALNY Z MATEMATYKI

1 + x 1 x 1 + x + 1 x. dla x 0.. Korzystając z otrzymanego wykresu wyznaczyć funkcję g(m) wyrażającą liczbę pierwiastków równania.

FUNKCJE. Rozwiązywanie zadań Ćw. 1-3 a) b) str Ćw. 5 i 6 str. 141 dodatkowo podaj przeciwdziedzinę.

METODY NUMERYCZNE. Wykład 4. Numeryczne rozwiązywanie równań nieliniowych z jedną niewiadomą. prof. dr hab.inż. Katarzyna Zakrzewska

PRÓBNY EGZAMIN MATURALNY Z MATEMATYKI poziom rozszerzony

Animowana grafika 3D. Opracowanie: J. Kęsik.

Wstęp Pierwsze kroki Pierwszy rysunek Podstawowe obiekty Współrzędne punktów Oglądanie rysunku...

Metody numeryczne w przykładach

Rachunek całkowy - całka oznaczona

ZESPÓŁ SZKÓŁ W OBRZYCKU

Geometria wykreślna. 5. Obroty i kłady. Rozwinięcie wielościanu. dr inż. arch. Anna Wancław. Politechnika Gdańska, Wydział Architektury

Lecture Notes in Computer Graphics. 2D graphics

Zajęcia nr 1 (1h) Dwumian Newtona. Indukcja. Zajęcia nr 2 i 3 (4h) Trygonometria

LUBELSKA PRÓBA PRZED MATURĄ

Propozycja szczegółowego rozkładu materiału dla 4-letniego technikum, zakres podstawowy. Klasa I (60 h)

FUNKCJE. Kurs ZDAJ MATURĘ Z MATEMATYKI MODUŁ 5 Teoria funkcje cz.1. Definicja funkcji i wiadomości podstawowe

Geometria analityczna

EGZAMIN MATURALNY Z MATEMATYKI

ROZWIĄZYWANIE RÓWNAŃ NIELINIOWYCH

Transkrypt:

Algorytmy grafiki rastrowej Mirosław Głowacki Wykład z Grafiki Komputerowej

Konwersja odcinków Mirosław Głowacki Wykład z Grafiki Komputerowej

Konwersja odcinków Algorytmy konwersji odcinków obliczają współrzędne pikseli leżących na lub blisko idealnej, nieskończenie cienkiej linii prostej nałożonych na siatkę dwuwymiarowego rastra Sekwencja pikseli powinna leżeć możliwie blisko odcinka rzeczywistego i tworzyć możliwie prostą linię Dla odcinków o nachyleniu z przedziału [ 1, 1] tylko jeden piksel w każdej kolumnie, dla pozostałych tylko jeden piksel w wierszu

Konwersja odcinków Wszystkie odcinki powinny być rysowane ze stałą jasnością niezależnie od długości i orientacji i tak szybko jak to możliwe Powinna istnieć możliwość rysowania odcinka grubszego niż 1 o osi symetrii pokrywającej się z odcinkiem idealnym. Wygląd takich odcinków musi zależeć od atrybutów linii oraz stylu pióra i spełniać wymagania ilustracji dobrej jakości

Odcinki o grubości 1 - przykłady konwersji odcinków 20 18 16 14 12 10 8 6 Odcinki pionowe, poziome i o nachyleniu m = 1 są szczególnymi przypadkami, gdyż przechodzą dokładnie przez środek pikseli 4 2 0 0 2 4 6 8 10 12 14 16 18 20

Odcinek po konwersji

Podstawowy algorytm przyrostowy Najprostsza strategia polega na: obliczeniu nachylenia odcinka m jako y/ x, zwiększaniu wartości x o 1 zaczynając od punktu położonego maksymalnie z lewej strony, obliczaniu y i = m x i + B dla kolejnych x i Wyświetlaniu piksela x i, Round y i Jest to strategia nieefektywna, gdyż w każdej iteracji wykonywane jest zmiennopozycyjne mnożenie, dodawanie i wywoływanie funkcji Round

Podstawowy algorytm przyrostowy Mnożenie można wyeliminować jeśli zauważymy, że y i+1 = mx i+1 + B = m x i + x + B = = y i + m x Teraz jeśli x = 1, to y i+1 = y i + m Wobec tego jednostkowej zmianie x towarzyszy zmiana y o m nachylenie odcinka Wartości kolejnego punktu leżącego na prostej teoretycznej (nie chodzi tu o punkty uzyskane w wyniku rasteryzacji) definiowane są rekurencyjnie

Podstawowy algorytm przyrostowy (x i + 1,Round(y i + m)) Idealna prosta (x i,y i ) (x i + 1,y i + m) (x i,round(y i )) Poprzedni piksel Potencjalne punkty dla bieżącego piksela

Podstawowy algorytm przyrostowy Obliczenia przyrostowe rozpoczynają się od (x 0, y 0 ) Należy zauważyć, że obliczenia nie biorą pod uwagę przesunięcia odcinka linii prostej względem osi OY, tzn. współczynnika B prostej. Jeśli m > 1 to jednostkowemu krokowi w kierunku OX towarzyszy krok w kierunku osi OY większy niż 1 Należy wówczas zamienić miejscami x i y, tzn. zwiększać o jednostkę współrzędną y oraz x o wartość x = y/m = 1/m

Podstawowy algorytm przyrostowy implementacja w C++ void Line ( int x0, int y0, int x1, int y1, int value ) { // Zakłada się, ze -1 < m < 1 // x zmienia się od x0 do x1 z przyrostem jednostkowym int x; float dx, dy, y, m dx = x1 x0; dy = y1 y0; m = dy / dx; y = y0; for (x = x0; x <= x1; x++) { // Ustawienie piksela WritePixel ( x, static_cast<int>(floor(y+0.5)),value); y += m; } }

Algorytm Bresenhama konwersji odcinka Może być stosowany do odcinków o dowolnych rzeczywistych końcach Może być stosowany również do rysowania okręgów całkowitoliczbowych Nie może być stosowana do innych krzywych stożkowych Obliczenia wykonywane są z wykorzystaniem arytmetyki całkowitoliczbowej Przyrostowe obliczanie wartości dla piksela i + 1 na podstawie znanych współrzędnych i tego piksela Zapewnia najlepszą aproksymację dla idealnego odcinka prostej minimalizuje błąd (odległość od linii idealnej)

Algorytm z punktem środkowym, algorytm Bresenhama NE Q M E P = (xp, yp) Poprzedni piksel Potencjalne punkty dla bieżącego piksela Potencjalne punkty dla następnego piksela

Algorytm z punktem środkowym Zakładamy nachylenie odcinka linii prostej pomiędzy 0 i 1 Dla innych nachyleń korzysta się z odpowiednich odbić osi współrzędnych Przyjmujemy, że dolny lewy koniec odcinka ma współrzędne (x 0, y 0 ), a prawy górny (x 1, y 1 )

Algorytm z punktem środkowym, algorytm Bresenhama W poprzednim kroku wybrano punkt P o współrzędnych (x p, y p ) Teraz należy wybrać piksel przesunięty o jednostkę w prawo ( tzw. piksel wschodni E) lub o jednostkę w prawo i jednostkę do góry (piksel północno-wschodni NE) P = (xp, yp) Poprzedni piksel Q NE M E Potencjalne punkty dla bieżącego piksela Potencjalne punkty dla następnego piksela

Algorytm Bresenhama Punkt Q będący punktem przecięcia odcinka z linią x = x p + 1 jest wykorzystywany do wybrania pomiędzy pikselami E i NE Oblicza się odległości w pionie pomiędzy E i Q oraz pomiędzy NE i Q Mniejsza z odległości powoduje wybór odpowiedniego piksela E lub NE P = (xp, yp) Poprzedni piksel Q NE M E Potencjalne punkty dla bieżącego piksela Potencjalne punkty dla następnego piksela

Algorytm z punktem środkowym Analizy dokonuje się w oparciu o punkt środkowy M leżący na linii x = x p + 1 oraz jego położenie w stosunku do punktu Q Jeśli M leży powyżej odcinka linii prostej, to piksel E leży bliżej odcinka, jeśli M leży poniżej odcinka linii prostej, to piksel NE leży bliżej tego odcinka Nie ma znaczenia czy odcinek przebiega pomiędzy pikselami E i NE czy też nie algorytm wybierze najbliższy, nawet spoza tego zakresu Błąd, tzn. pionowa odległość między pikselem i odcinkiem idealnym 1/2 P = (xp, yp) Poprzedni piksel Q NE M E Potencjalne punkty dla bieżącego piksela Potencjalne punkty dla następnego piksela

Algorytm z punktem środkowym Niech odcinek będzie reprezentowany przez funkcję uwikłaną ze współczynnikami a, b i c Jeśli to równanie prostej F x, y = ax + by + c dy = y 1 y 0 dx = x 1 x 0 y = dy dx x B

Algorytm z punktem środkowym Stąd postać funkcji uwikłanej będzie F x, y = dy x dx y + Bdx = 0 Zatem w postaci uwikłanej a = dy b = dx c = B dx

Algorytm z punktem środkowym Dla punktów położonych na odcinku F x, y = 0 Dla punktów poniżej odcinka F x, y > 0 Dla punktów powyżej odcinka F x, y < 0

Algorytm z punktem środkowym Teraz należy jedynie sprawdzić znak funkcji. W tym celu definiujemy zmienną decyzyjną d d = F M = F x p + 1, y p + 1 2 Z definicji d przyjmuje wartość d = a x p + 1 + b y p + 1 2 + c

Algorytm z punktem środkowym d > 0 d < 0 d = 0 Zostaje wybrany piksel NE Zostaje wybrany piksel E Może zostać wybrany dowolny piksel i wybieramy E

Algorytm z punktem środkowym, algorytm Bresenhama NE Q M E P = (xp, yp) Poprzedni piksel Potencjalne punkty dla bieżącego piksela Potencjalne punkty dla następnego piksela

Algorytm z punktem środkowym Pytanie: Co stanie się z położeniem punktu M i wartością d dla następnej linii siatki? Odpowiedź zależy od tego czy uprzednio wybrano piksel E czy też piksel NE

Algorytm z punktem środkowym Jeśli wybrany został piksel E, to M zwiększa swoją odciętą o jeden krok i nie zmienia rzędnej - wtedy d new = F x p + 2, y p + 1 2 = a x p + 2 + b y p + 1 2 + c Poprzednia wartość d wynosiła d old = a x p + 1 + b y p + 1 2 + c

Algorytm z punktem środkowym Stąd wynika fakt d new = d old + a Zatem po wybraniu punktu E, przyrost zmiennej decyzyjnej d wyniesie E = a = dy Nie ma zatem potrzeby bezpośredniego obliczania wartości funkcji F(x, y) w kolejnym kroku

Algorytm z punktem środkowym Jeśli wybrany został piksel NE, to M zwiększa obie swoje współrzędne o jednostkę d new = F x p + 2, y p + 3 2 = a x p + 2 + b y p + 3 2 + c Ponieważ d old = a x p + 1 + b y p + 1 2 + c

Algorytm z punktem środkowym Stąd d new = d old + a + b Zatem po wybraniu punktu NE, przyrost zmiennej decyzyjnej d wyniesie NE = a + b = dy dx Również w tym przypadku nie ma potrzeby bezpośredniego obliczania wartości funkcji F(x, y) w kolejnym kroku

Algorytm z punktem środkowym Pierwszym zaznaczanym pikselem jest początek odcinka, tzn. (x 0, y 0 ). Początkową wartość d wylicza się bezpośrednio dla punktu (x 0 + 1, y 0 + 1/2) F x 0 + 1, y 0 + 1 2 = a x 0 + 1 + b y 0 + 1 2 + c = = ax 0 + by 0 + c + a + b 2 = F x 0, y 0 + a + b 2

Algorytm z punktem środkowym Punkt (x 0, y 0 ) leży na odcinku, więc F(x 0, y 0 ) = 0. d start = a + b 2 = dy dx 2 Korzystając z d start wybieramy drugi piksel, potem liczymy d new i wybieramy trzeci piksel, itd W celu uniknięcia ułamka w d start funkcję F(x, y) mnożymy przez 2 F x, y = 2 ax + by + c Powoduje to konieczność mnożenia każdej stałej, zmiennej decyzyjnej oraz przyrostów E i NE przez 2, nie wpływa to jednak na znak zmiennej decyzyjnej, co jest istotne dla algorytmu i gwarantuje możliwość dodawania całkowitoliczbowego

Algorytm z punktem środkowym implementacja w C, C++ void MidpointLine ( int x0, int y0, int x1, int y1, int value ) { int dx, dy, incre, incrne, d, x, y; dx = x1 x0; dy = y1 y0; d = dy * 2 dx; // Początkowa wartość d incre = dy * 2; // Przyrost przy przejściu do E incrne = ( dy dx ) * 2; // Przyrost przy przejściu do NE x = x0; y = y0; WritePixel ( x, y, value); // Piksel początkowy while ( x < x1 ) { if ( d <= 0 ) { d += incre; x++;} // Wybór E else { d += incrne; x++; y++;} // Wybór NE WritePixel ( x, y, value); // Wybrany najbliższy piksel } }

Algorytm z punktem środkowym 12 Odcinek pomiędzy punktami (5, 8) i (9, 11) rysowany metodą punktu środkowego 11 10 9 8 d = 2 d = 0 d = 6 NE E d = 4 NE NE 7 4 5 6 7 8 9 10

Algorytm konwersji z punktem środkowym Wu i Rokne Opiera się na klasycznym algorytmie punktu środkowego Dwukrotnie zredukowano liczbę decyzji Poszukuje się nie kolejnego pojedynczego piksela, a pary pikseli

Algorytm Wu i Rokne Wu pokazał, że mogą wystąpić cztery kombinacje przy wyborze pary pikseli Wzór 1 Wzór 2 Wzór 3 Wzór 4

Algorytm Wu i Rokne Wu i Rokne pokazali, że wzory 1 i 4 nie mogą wystąpić na tym samym odcinku Jeśli nachylenie odcinka > ½, to nie może wystąpić wzór 1 Jeśli nachylenie odcinka < ½, to nie może wystąpić wzór 4 Testowanie nachylenia odcinka ogranicza wybór do jednego z trzech wzorów: 1, 2, 3 albo 2, 3, 4 Wzór 1 Wzór 3 Wzór 2 Wzór 4

Algorytm Wu i Rokne Przypadek 1: nachylenie odcinka zawiera się w przedziale ( 0, ½ ), co jak wiemy wyklucza wzór 4 Należy wybrać wzór: 1, 2, albo 3. Początkowa wartość zmiennej decyzyjnej, która zapewnia dodawanie całkowitoliczbowe będzie d = 4 a + b 2 = 4dy 2dx

Algorytm Wu i Rokne Potem dla każdego kroku o dwie jednostki rastra, jeśli d < 0, to należy wybrać wzór 1 Jeśli d 0, to należy wybrać wzór: 2 lub 3. Decyduje o tym test d < 2dy. Zwiększanie d przebiega wg reguły: Jeśli d i < 0, (wzór 1) Jeśli d i 0, (wzór: 2 lub 3) d i+1 = d i + 4dy d i+1 = d i + 4dy 2dx

Algorytm Wu i Rokne implementacja w C++ void DoubleStep ( int x0, int y0, int x1, int y1 ){ int current_x, incr_1, incr_2, cond, dx, dy, d; /* Kod wewnętrznej pętli dla przypadku nachylenia z przedziału (0, 1/2). Dla procedury DrawPixels jest potrzebny wzór (patern) i bieżąca wartość odciętej x. W przypadku końca odcinka może być konieczne narysowanie tylko jednego piksela, a nie całego wzoru, gdyż w przeciwnym przypadku konwersja może dać zbyt długi odcinek. */ // inicjalizacja pętli wewnętrznej dx = x1 x0; dy = y1 y0; current_x = x0; incr_1 = 4 * dy; incr_2 = 4 * dy 2 * dx; cond = 2 * dy; d = 4 * dy dx;

Algorytm Wu i Rokne implementacja w C++ (kontynuacja) d = 4 * dy dx; while (current_x < x1) { if (d < 0) { } } DrawPixels ( PATTERN_1, current_x); d += incr_1 // potrzebna jest dalsza konwersja // pierwsza decyzja } else { if (d < cond) // Wybór między 2 i 3 DrawPixels ( PATTERN_2, current_x); else DrawPixels ( PATTERN_3, current_x); d += incr_2; } current_x += 2;

Kolejność punktów końcowych Należy zapewnić, aby odcinek rysowany od P 1 do P 2 zawierał ten sam zestaw pikseli co odcinek rysowany od P 2 do P 1 Zapewnia to niezależność wyglądu odcinka od kolejności podawania jego punktów końcowych Jedyną sytuacją, gdy wybór piksela zależy od kierunku rysowania odcinka jest przypadek, gdy przechodzi on dokładnie przez punkt środkowy i zmienna decyzyjna jest równa zeru Jeśli idąc z lewa na prawo zostałby wybrany piksel E, to na zasadzie symetrii spodziewamy się, że idąc z prawa na lewo dla d = 0 zostanie wybrany piksel W.

Kolejność punktów końcowych Jednak wtedy będzie to piksel leżący o jednostkę wyżej niż miałoby to miejsce przy konwersji z lewa na prawo. Powinien natomiast zostać wybrany piksel SW. Należy zatem zmodyfikować algorytm konwersji z prawa na lewo. Można co prawda każdorazowo dokonywać konwersji z lewa na prawo, ale możliwe jest to tylko przy wykreślaniu linii ciągłej. Dla odcinka rysowanego np. linią przerywaną konieczne jest aby wzór bitowy ( przykładowo 111100) zaczynał się zawsze w początku odcinka, a nie w jego końcu. W ogólnym przypadku należy zatem przeprowadzać konwersję w zadanym kierunku.

Początek odcinka na krawędzi prostokąta obcinającego Algorytm powinien prawidłowo rasteryzować odcinki, które zostały obcięte za pomocą jednego z algorytmów obcinających. Punkt przecięcia ma całkowitą współrzędną x, ale rzeczywistą współrzędną y Piksel [x min, Round(mx min + B)] leżący na krawędzi jest tym pikselem, który byłby narysowany przy pomocy algorytmu przyrostowego dla odcinka nie obciętego (x min, Round(mx min + B)) x = xmin (x min, mx min + B) NE E y = ymin

Początek odcinka na krawędzi prostokąta obcinającego Przy algorytmie z punktem środkowym musimy zatem dla przedstawionego piksela początkowego zainicjalizować zmienną decyzyjną pomiędzy E i NE Strategia ta daje prawidłową sekwencję pikseli w przeciwieństwie do algorytmu, który zakłada dokonywanie konwersji wcześniej obciętego odcinka, co zmienia jego nachylenie

Początek odcinka na krawędzi prostokąta obcinającego Jeśli odcinek przecina linię poziomą, to sytuacja jest bardziej skomplikowana Dla odcinka o niewielkim nachyleniu, w wierszu y = y min będzie kilka pikseli, które odpowiadają dolnej krawędzi prostokąta obcinającego Chcemy, aby każdy z tych pikseli należał do wnętrza obszaru obcinającego. x = x min B A y = y min - 1/2 y = y min - 1 y = y min

Początek odcinka na krawędzi prostokąta obcinającego Zwykle jednak obliczenia analityczne przecięcia odcinka z linią y = y min i późniejsze zaokrąglenie wartości x daje piksel A zamiast B Piksel B leży z prawej strony i nad miejscem, w którym odcinek po raz pierwszy przecina pionową linię siatki ponad punktem środkowym y = y min ½. Współrzędne pierwszego punktu środkowego to (Round x, y min ½) x = x min B A y = y min - 1/2 y = y min - 1 y = y min

Konwersja okręgów Mirosław Głowacki Wykład z Grafiki Komputerowej

Konwersja okręgu Metody mało efektywne: Konwersja ćwiartki okręgu z automatyczną konwersją pozostałej części na zasadzie symetrii Dla uwikłanej postaci równania okręgu: y = ± R 2 x 2 wadliwe, nierównomierne rozmieszczenie pikseli Dla równania okręgu w postaci: (R cos, R sin ) dla z zakresu 0 do 90 o Można usprawnić sposób rysowania lepiej wykorzystując symetrię okręgu. Obliczeń można dokonać jedynie dla segmentu o kącie rozwarcia 45 o

Konwersja okręgu ośmiokrotna symetria (-x, y) (x, y) Ośmiokrotna symetria Jeśli punkt o współrzędnych (x, y) należy do okręgu, to w trywialny sposób można obliczyć położenie siedmiu innych punktów (-y, x) (-y, -x) R/2 0.5 (y, x) (y, -x) (-x, -y) (x, -y)

Ośmiokrotna symetria funkcja CirclePoints void CirclePoints (float x, float y, int value) { WritePixel(x, y, value); WritePixel(y, x, value); WritePixel(y, -x, value); WritePixel(x, -y, value); WritePixel(-x, -y, value); WritePixel(-y, -x, value); WritePixel(-y, x, value); WritePixel(-x, y, value); }

Algorytm z punktem środkowym dla okręgu Bresenham opracował przyrostowy generator okręgu Zastosował metodę przyrostową do współpracy z ploterami Podobny algorytm może zostać oparty o metodę punktu środkowego Algorytm działa dla okręgów o całkowitoliczbowych: promieniu i współrzędnych środka okręgu Rozważa się 45 o drugi oktant okręgu od x = 0 do x = y = R/ 2 Podobnie jak dla odcinka oblicza się funkcję w punkcie środkowym pomiędzy dwoma pikselami i wybiera jeden z nich

Algorytm z punktem środkowym dla okręgu P = (xp, yp) E Siatka pikselowa dla algorytmu z punktem środkowym dla okręgu M SE M E M SE Poprzedni piksel Możliwości wyboru dla bieżącego piksela Możliwości wyboru dla następnego piksela

Algorytm z punktem środkowym dla okręgu Jeśli został wybrany punkt P o współrzędnych (x p, y p ) to jako następny może zostać wybrany E lub SE Funkcja uwikłana F(x, y) będzie miała postać: F x, y = x 2 + y 2 R 2 Funkcja ta będzie miała wartość: zerową na okręgu ujemną wewnątrz i dodatnią na zewnątrz okręgu Jeśli punkt środkowy pomiędzy pikselami E i SE leży na zewnątrz okręgu, to bliższym okręgu jest piksel SE Jeśli punkt środkowy leży wewnątrz okręgu, to bliższym okręgu jest piksel E

Algorytm z punktem środkowym dla okręgu Podobnie jak dla odcinków wyboru dokonuje się na podstawie zmiennej decyzyjnej d d = F x p + 1, y p 1 2 = x p + 1 2 + y p 1 2 2 R 2 Jeśli d < 0 to wybieramy piksel E i następny punkt środkowy będzie w odległości jednego przyrostu wzdłuż osi OX d new = F x p + 2, y p 1 2 = x p + 2 2 + y p 1 2 2 R 2

Algorytm z punktem środkowym dla okręgu Stąd wynika fakt d new = d old + 2x p + 3 Zatem po wybraniu punktu E, przyrost zmiennej decyzyjnej d wyniesie E = 2x p + 3 Nie ma zatem potrzeby bezpośredniego obliczania wartości funkcji F(x, y) w kolejnym kroku

Algorytm z punktem środkowym dla okręgu Jeśli d old 0 to wybieramy piksel SE i następny punkt środkowy będzie w odległości jednego przyrostu wzdłuż osi OX i jednego ujemnego przyrostu wzdłuż osi OY d new = F x p + 2, y p 3 2 = x p + 2 2 + y p 3 2 Stąd wynika fakt d new = d old + 2x p 2y p + 5 Zatem po wybraniu punktu SE, przyrost zmiennej decyzyjnej d wyniesie SE = 2x p 2y p + 5 Również i teraz nie ma zatem potrzeby bezpośredniego obliczania wartości funkcji F(x, y) w kolejnym kroku 2 R 2

Algorytm z punktem środkowym dla okręgu W przypadku linii prostej E i NE miały stałe wartości W przypadku okręgu S i SE zmieniają się w każdym kroku w zależności od wartości współrzędnych (x p, y p ) piksela wybranego w poprzedniej iteracji Punkt P o współrzędnych (x p, y p ) nazywa się zatem punktem odniesienia Ponieważ obliczeń dokonujemy dla promieni całkowitoliczbowych w drugi oktancie okręgu wiemy, że piksel początkowy leży na okręgu w punkcie (0, R) Następny punkt środkowy leży w (1, R ½ ). Wartość funkcji F dla tego punktu wyniesie F 1, R 1 2 = 1 + R2 R + 1 4 R2 = 5 4 R

Implementacja algorytmu w C++ void MidpointCircle(int radius, int value) { int x, y; float d; x = 0; // inicjalizacja y = radius; d = 5./4. - radius; CirclePoints (x, y, value); while (y > x) { if (d < 0) {d += x*2. + 3; x++;} // wybrac E else {d += (x y) * 2. + 5; x++; y--;} // wybrac SE CirclePoints (x, y, value); } }

Algorytm z punktem środkowym dla okręgu wersja całkowitoliczbowa Wadą jest tu konieczność używania arytmetyki zmiennoprzecinkowej ze względu na ułamkową inicjalizację wartości d. Funkcja ta może zostać z łatwością przystosowana do rasteryzacji okręgów, dla których promień bądź współrzędne środka nie są całkowite Należy również opracować wersję w pełni całkowitoliczbową, a więc i szybką Definiujemy nową zmienną decyzyjną h = d 1 4 i podstawiamy w kodzie h + ¼ zamiast d i do inicjalizacji mamy h = 1 R Porównanie d < 0 zostaje zastąpione porównaniem h < ¼ Ponieważ jednak h zaczyna się od wartości całkowitej i zwiększa się o wartości całkowite S i SE możemy porównanie zmienić na h < 0

Implementacja algorytmu w C++ void MidpointCircle(int radius, int value) { int x, y; int d; // w dalszym ciągu używamy d pamiętając, // że ma wartość h x = 0; // inicjalizacja y = radius; d = 1 - radius; CirclePoints (x, y, value); while ( y > x ) { if ( d < 0 ) {d += x * 2 + 3; x++;} // wybrac E else {d += (x y) * 2 + 5; x++; y--; } // wybrac SE CirclePoints (x, y, value); } }

Algorytm z punktem środkowym dla okręgu różnice drugiego rzędu Algorytm z punktem środkowym dla okręgu można jeszcze bardziej przyspieszyć korzystając z metody obliczeń przyrostowych Podobnie jak to miało miejsce dla zmiennej decyzyjnej d wartość każdego wielomianu można obliczać przyrostowo. W rezultacie obliczamy różnice pierwszego i drugiego rzędu w dwóch sąsiednich punktach. Dla wielomianów różnice są wielomianami niższego rzędu.

Algorytm z punktem środkowym dla okręgu różnice drugiego rzędu Jeśli w bieżącej iteracji wybrano E, to kolejny punkt przesuwa się z (x p, y p ) do (x p + 1, y p ) P = (xp, yp) M E M E Dla punktu x p, y p SE Δ Eold = 2x p + 3 M SE Stąd dla (x p + 1, y p ) Δ Enew = 2 x p + 1 + 3 Δ Enew Δ Eold = 2 Poprzedni piksel Możliwości wyboru dla bieżącego piksela Możliwości wyboru dla następnego piksela

Algorytm z punktem środkowym dla okręgu różnice drugiego rzędu Podobnie wartość SE dla punktu (x p, y p ) P = (xp, yp) M E M E Δ SEold = 2x p 2y p + 5 a dla dla (x p + 1, y p ) Poprzedni piksel Δ SEnew = 2 x p + 1 2y p + 5 Δ SEnew Δ SEold = 2 SE Możliwości wyboru dla bieżącego piksela Możliwości wyboru dla następnego piksela M SE

Algorytm z punktem środkowym dla okręgu różnice drugiego rzędu Jeśli w bieżącej iteracji wybrano punkt SE, to analizowany punkt przesuwa się z (x p, y p ) do punktu (x p + 1, y p 1). Wtedy dla następnego punktu E Δ Enew = 2 x p + 1 + 3 Δ Enew Δ Eold = 2 natomiast dla następnego punktu SE Δ SEnew = 2 x p + 1 2 y p 1 + 5 Δ SEnew Δ SEold = 4

Algorytm z punktem środkowym dla okręgu z różnicami drugiego rzędu Inicjalizacja zmiennych decyzyjnych w oparciu o punkt (0, R) Wybór piksela na podstawie znaku zmiennej d obliczonej w poprzedniej iteracji Uaktualnienie zmiennej d o E albo SE korzystając z wartości obliczonych w poprzedniej iteracji Uaktualnienie E i SE z uwzględnieniem przejścia do nowego piksela, korzystając ze stałych różnic Wykonanie przesunięcia

Implementacja algorytmu z różnicami drugiego rzędu w C++ void MidpointCircle(int radius, int value){ int x, y, d, deltae, deltase; x = 0; // inicjalizacja y = radius; d = 1 - radius; deltae = 3; deltase = 5 radius * 2 CirclePoints (x, y, value); while ( y > x ) { if ( d < 0 ) // wybrac E {d += deltae; deltae += 2; deltase += 2; x++;} else // wybrac SE {d += deltase; deltae += 2; deltase += 4; x++; y--;} CirclePoints (x, y, value); } }

Prymitywy pogrubione Mirosław Głowacki Wykład z Grafiki Komputerowej

Prymitywy pogrubione Tworzy się je na zasadzie śledzenia konturów uzyskanych w wyniku konwersji Umowny pędzel tworzący ślad o pewnej szerokości i w wysokości umieszcza się w pikselu powstałym w wyniku konwersji Piksel pokrywa się z jednym z pikseli pędzla: środkowym narożnym w przypadku pędzla prostokątnego

Prymitywy pogrubione Istotne są przy tym: kształt pędzla (kołowy, kwadratowy) orientacja pędzla czy oś pędzla, pierwotnie pionowa, nie zmienia swojej orientacji czy też jest styczna do brzegu prymitywu jak wyglądają końce odcinków co dzieje się w wierzchołku pogrubionego wielokąta jak współdziałają styl linii i styl pióra itp.

Cztery podstawowe metody pogrubiania algorytm powielania pikseli algorytm linii pogrubianej metodą ruchomego pióra o pewnym kształcie i rozmiarach algorytm rysowania dwóch konturów w pewnej odległości i wypełniania środka algorytm aproksymacji linii krzywych łamaną i pogrubiania odcinków łamanej

Powielanie pikseli Polega na zaznaczaniu wielu pikseli sąsiadujących z wyznaczonym poprzez algorytm konwersji Stosowany z powodzeniem przy konwersji odcinków Dla odcinków o nachyleniach od 1 do 1 piksele są powielane w kolumnach Dla pozostałych nachyleń powielane są wiersze Wada - końce odcinków są zawsze pionowe bądź poziome

Powielanie kolumn Pogrubiony odcinek narysowany metodą powielania kolumn.

Wady metody powielania pikseli dla grubych odcinków jest to poważny mankament istnieją zauważalne przerwy przy przecinaniu się odcinków występują braki pikseli w miejscach zmiany kierunku powielania z pionowego na poziomy braki są wyraźnie widoczne dla łuków w postaci przewężeń pomiędzy poszczególnymi oktantami odcinki poziome i pionowe różnią się grubością od odcinków rysowanych pod kątem grubość wynika z rozmiaru w kierunku prostopadłym do linii jeśli odcinek pionowy (poziomy) ma grubość t, to narysowany pod kątem 45 o ma grubość t 2 jeśli liczba pikseli odcinka grubego jest parzysta, to jego oś nie może się pokrywać z osią geometryczną

Okrąg i metoda powielania pikseli Pogrubiony okrąg narysowany metodą powielania kolumn.

Metoda ruchomego pióra Dobre efekty dla odcinka uzyskuje się jeśli środek lub róg pióra o przekroju prostokątnym porusza się wzdłuż odcinka Odcinek ukośny jest podobny do uzyskanego metodą powielania pikseli, ale grubszy na końcach Jeśli pióro ustawione jest zawsze pionowo, to grubość linii zmienia się w funkcji jej nachylenia. W przeciwieństwie do powielania pikseli linie ukośne są grubsze w stosunku do poziomych i pionowych

Metoda ruchomego pióra Pogrubiony odcinek narysowany za pomocą prostokątnego pióra.

Metoda ruchomego pióra Okrąg jest grubszy w okolicach przejść pomiędzy oktantami Problem można wyeliminować stosując obrót prostokąta wzdłuż konturu Lepszą metodą jest zastosowanie pióra o przekroju okrągłym W tym przypadku należy maskować piksele narożne pióra, co nie jest łatwe i efektywne W najprostszych rozwiązaniach piksele są zapisywane wielokrotnie ślad pióra nakłada się na sąsiednie piksele Lepsza metoda polega na wykorzystywaniu segmentów śladu (przecięć liniami poziomymi) do obliczania kolejnych ich położeń Sprowadza się to do określania x min i x max dla kolejnych segmentów podobnie jak przy wypełnianiu prymitywów

Okrąg i metoda ruchomego pióra Pogrubiony okrąg narysowany za pomocą prostokątnego pióra.