sprawko 1 grafika

WOJSKOWA AKADEMIA TECHNICZNA

Laboratorium z przedmiotu

Grafika komputerowa

SPRAWOZDANIE

Laboratorium nr 1

Wykonanie: Justyna Kozon

Grupa: I9X5S1

Data wykonania ćwiczenia:18.11.2010

  1. Treść wykonywanych zadań.

Zestaw 15.

1. Napisać algorytm sterujący generatorem adresu odczytu w celu uzyskania efektu

przesuwania obrazu wzdłuż przekątnej ekranu w kierunku dolnego prawego

wierzchołka.

2. Napisać algorytm sterujący generatorem adresu odczytu w celu uzyskania efektu

zasłaniania poziomego obrazu w kierunku lewej krawędzi ekranu.

3. Napisać algorytm sterujący generatorem adresu odczytu w celu uzyskania efektu

przesuwania obrazu wzdłuż przekątnej ekranu w kierunku dolnego lewego wierzchołka.

  1. Wstęp teoretyczny.

Aby rozwiązać to zadanie należy wiedzieć w jaki sposób działa urządzenie rastrowe. Generuje ono piksele obrazu nie w dowolnej kolejności, ani nawet w takiej w jakiej życzyłby sobie użytkownik lub programista, ale w kolejności wcześniej ustalonej i niezmiennej. Mianowicie obraz generowany jest piksel po pikselu od lewej strony do prawej i wierszami w kierunku dolnej krawędzi ekranu. Gdy zostanie wygenerowany ostatni piksel (w prawym dolnym rogu) następuje przejście do początku wyświetlania i rozpoczyna się proces tworzenia kolejnej klatki. Programista może jedynie sterować generatorem adresu odczytu i dzięki temu decydować jakiej barwy piksel pojawi się na kolejnym miejscu, które będzie wyświetlało urządzenie rastrowe.

W dostępnym dla nas symulatorze efektów mamy dostępne dwie funkcje, które umożliwiały nam wykonanie przeznaczonych dla nas zadań:

-ReadPixel(i, j); - wybiera piksel o współrzędnych (i, j) z mapy obrazu wczytanego do programu

-ReadTlo(N); - rysuje piksel czarny.

Mapa obrazu jest mapą bitową i posiada następujące współrzędne:

j → <1;L> - numer wiersza

i → <1;K> - numer kolumny.

Odczytywanie przykładowego piksela wygląda w następujący sposób:

W programie używamy także zmiennej p, która jest aktualnym przesunięciem obrazu (w każdej klatce obraz przesunięty jest o p pikseli w daną stronę). Gdy p=0 mamy do czynienia z obrazem niezmienionym. Z każdą klatką p jest zwiększane o 1 i obraz powoli się przesuwa.

  1. Sposoby rozwiązania zadań i kody źródłowe.

-- algorytm sterujący generatorem adresu odczytu w celu uzyskania efektu

przesuwania obrazu wzdłuż przekątnej ekranu w kierunku dolnego prawego

wierzchołka.

W rozwiązaniu tego zadania przydatny będzie rysunek pomocniczy:

Mamy na nim wyróżnione 4 obszary: A, B, C i D. Obszary A i B symbolizują nasz obraz, który przesuwamy, natomiast obszary C i D fragmenty tła.

Analizę najłatwiej rozpocząć od obszaru A. Musimy określić jego wielkość oraz wartości pikseli, które zostaną odczytane z pamięci obrazu i wyświetlone. Jak widać poziomo obszar A zajmuje K-p pikseli (czyli jest to ilość wszystkich pikseli w linii minus te już przesunięte). Odczytywać będziemy od 1 piksela obrazu, gdyż lewy górny róg obszaru A jest lewym górnym rogiem obrazu z pamięci. Podobnie wygląda sytuacja w pionie, z jedną tylko różnicą, że zajmuje on w pionie L-p pikseli (L jest liczbą wierszy obrazu).

Następnie przechodzimy do analizy obszaru B. Jest to przesunięta część obrazu z pamięci. Zajmuje ona obszar o rozmiarze p x p. Aby określić odczytywane piksele w pionie musimy sobie wyobrazić, który to będzie fragment naszego rysunku.

Widać teraz, że w poziomie odczytywane piksele zaczynają się od miejsca zakończenia odczytywania pikseli w poziomie obszaru A, a kończą wraz z końcem linii. Analogiczna jest sytuacja w pionie. Wynika z tego, że poziomo granice B wyglądają następująco: K-p+1→K, a pionowo L-p+1→L.

Kolejny obszar to obszar C. Widać z rysunku pomocniczego, że poziomo jego granice wyglądają tak jak granice poziome obszaru A, a pionowo tak jak granice pionowe obszaru B. Jednak dla ułatwienia granicę poziomą możemy określić jako 1→p, ponieważ wiemy, że taką wysokość mają obszary B i C (ze względu na to, że odczytywać będziemy piksele tła mniej ważne jest, z których pikseli obrazu zostaną odczytane, ważna jest ich ilość).

W przypadku obszaru D widzimy, że ma on taką wysokość jak obszar A i szerokość p. Rysunek pomocniczy z naniesionymi granicami obszarów wygląda następująco:

W tym momencie mamy już wszystko, aby określić odpowiednio nasze pętle for, którymi będziemy się posługiwać do zrealizowania postawionego zadania. Zewnętrzna pętla związana będzie z wierszami, a wewnętrzne z obszarami ograniczonymi danymi wierszami. Kod źródłowy wygląda następująco:

public void Efekt1()

{ //efekt: przewijanie obrazu wzdłuż przekątnej w kierunku dolnego prawego wierzchołka

if (p >= L) p = 0;

for (int j = L - p + 1; j <= L; j++)

{

for (int i = K - p + 1; i <= K; i++)

ReadPixel(i, j);

for (int i = 1; i <= K - p; i++)

ReadTlo(N);

}

for (int j = 1; j <= L - p; j++)

{

for (int i = 1; i <= p; i++)

ReadTlo(N);

for (int i = 1; i <= K - p; i++)

ReadPixel(i, j);

}

}

Efekty wykonania kodu:

- algorytm sterujący generatorem adresu odczytu w celu uzyskania efektu

zasłaniania poziomego obrazu w kierunku lewej krawędzi ekranu.

Rysunek pomocniczy:

Obszar A jest to nasz obraz w pamięci i w tym przypadku nie będzie się on poruszał. Zwiększać się będzie jedynie obszar B, który będzie „nachodził” z lewej strony na obszar A. W tym przypadku analiza obszarów jest prostsza.

Obszar A pionowo zajmuje wszystkie piksele obrazu zatem od 1→L. Taką samą wysokość na obszar B. Poziomo widać, że A zajmuje od 1→K-p pikseli i w miarę zwiększania p zmniejsza się. Obszar B poziomo zajmuje p pikseli.

Obraz z naniesionymi granicami wygląda następująco:

Konstruując pętle for możemy zwrócić uwagę, że można odrobinę skrócić kod programu określając obszary w poziomie za pomocą instrukcji if(); Zgodnie z tą myślą mamy: jeśli współrzędna ‘i’ jest mniejsza lub równa K-p odczytujemy obrazek, w przeciwnym wypadku odczytujemy piksele tła. Oto kod źródłowy programu:

public void Efekt2()

{

//efekt: zasłanianie poziome obrazu w kierunku lewej krawędzi

if (p >= L) p = 0;

for (int j = 1; j <= L; j++)

{

for (int i = 1; i <= K; i++)

{

if (i <= K - p) ReadPixel(i, j);

else ReadTlo(N);

}

}

}

Efekty wykonania kodu:

- algorytm sterujący generatorem adresu odczytu w celu uzyskania efektu

przesuwania obrazu wzdłuż przekątnej ekranu w kierunku dolnego lewego wierzchołka.

Rysunek pomocniczy:

Tym razem przydatne jest podzielenie obrazu na 3 części. W obszarze A mamy tylko piksele tła. Jego wysokość jest równa przesunięciu p, a szerokość ilości pikseli w poziomie, czyli K.

Kolejny obszar B jest to przesunięty obraz z bitmapy. Można zauważyć, że prawy górny róg obszaru pokrywa się z prawym górnym rogiem obrazu w pamięci. Zatem porównując do oryginalnego obrazu z lewej strony i od dołu brakuje po p pikseli, które zostały usunięte w wyniku przesunięcia obrazu. Dlatego też odczytywanie obrazu z pamięci powinniśmy zacząć w pionie od 1 i skończyć na L-p, a w poziomie od p+1 do K.

Obszar C jak widać ma tę samą wysokość co część B, a szerokość równą p.

Wszystkie te wnioski dla ułatwienia możemy umieścić na rysunku:

Teraz pozostaje już tylko odpowiednio zapisać pętle. Gotowy kod źródłowy wygląda następująco:

public void Efekt3()

{

//efekt: przesuwanie wzdłuż przekątnej ekranu w kierunku dolnego lewego wierzchołka

if (p >= L) p = 0;

for (int j = 1; j <= p; j++)

{

for (int i = 1; i <= K; i++)

ReadTlo(N);

}

for (int j = 1; j <= L - p; j++)

{

for (int i = p + 1; i <= K; i++)

ReadPixel(i, j);

for (int i = 1; i <= p; i++)

ReadTlo(N);

}

}

Efekty wykonania kodu:

Wnioski:

Wszystkie zadania zostały wykonane w poprawny sposób. Przy tworzeniu algorytmów sterujących generatorem adresu odczytu należy zwracać dużą uwagę na liczbę pikseli odczytywanych w jednej linii, gdyż zdublowanie jakiegoś piksela lub pominięcie sprawia, że na ekranie pojawiają się błędy i obraz nie zostaje wyświetlany w poprawny sposób (co wynika z generowania pikseli zgodnie z zasadami działania urządzenia rastrowego). Zadania pokazały, że za pomocą tylko pętli for oraz instrukcji if(); można w prosty sposób wykonać wiele różnych efektów na obrazie.


Wyszukiwarka