GRAFIKA KOMPUTEROWA
Sprawozdanie z pracy laboratoryjnej numer 1. |
---|
Temat |
Prowadzący |
Autor |
Grupa |
Data wykonania |
Zestaw |
Treść zadania:
Zestaw 15:
Napisać algorytm sterujący generatorem adresu odczytu w celu uzyskania efektu zasłaniania poziomego obrazu w kierunku lewej strony ekranu.
Napisać algorytm sterujący generatorem adresu odczytu w celu uzyskania efektu przesuwania pionowego obrazu w kierunku górnej krawędzi ekranu.
Napisać algorytm sterujący generatorem adresu odczytu w celu uzyskania efektu przewijania obrazu wzdłuż przekątnej ekranu w kierunku górnego lewego wierzchołka.
2. Wstęp teoretyczny:
W technice rastrowej generowanie obrazów przebiega piksel po pikselu. W przypadku monitorów CRT przebiega to jak na poniższym schemacie:
Rys1. Przedstawiający kierunek rysowania kolejnych pikseli obrazu.
Początkowo strumień elektronów kierowany jest w lewy górny róg ekranu a następnie jest przemieszczany w prawą stronę i w ten sposób generowany jest pierwszy wiersz obrazu. Następnie następuje przejście od lewej strony nowego wiersza. Cykl ten powtarza się, aż do momentu napotkania prawego dolnego rogu ekranu, po czym następuje powrót do początku ekranu. Tak też powstają kolejne klatki naszego obrazu.
Zatem jak widzimy programista nie może w dowolnej chwili wybrać sobie miejsca, w którym rysowany jest piksel, wszystko musi być rysowane w odpowiedniej kolejność ja na załączonym Rys1.
3. Cel ćwiczenia i sposób rozwiązania:
Celem ćwiczenia było napisanie 3 algorytmów sterujących generatorem adresu odczytu w celu uzyskania określonych efektów. W istocie algorytmy te zostały zaimplementowane w programie, który symulował działanie urządzenia rastrowego. Mianowicie wczytywał on plik graficzny, po czym wyświetlał go w jednym oknie, zaś drugie pełniło rolę symulowanego ekranu.
Rys2. Przedstawiający ekran programu(po lewej stronie widoczny jest wczytywany plik graficzny, po prawej- symulacja).
Zadanie należało wykonać w środowisku programistycznym Microsoft Visual Studio. Do wykonania poleceń konieczna była znajomość funkcji:
-ReadPixel(i, j); - odczytuje i wysyła do urządzenia zobrazowania wartość komórki mapy bitowej o adresie (i, j).
-ReadTlo(N); - wysyła do urządzenia zobrazowania piksel o kolorze określonym zmienną kolor.
Za pomocą funkcji ReadTlo(N); programista miał wpływ na kolor piksela, który przesyłał na linie.
W programie, poza tym, występują stałe:
– K – szerokość ekranu,
– L – wysokość ekranu.
Obraz przechowywany jest w mapie bitowej OBRAZ[i,j]:
i → <1;K> - adres kolumny w mapie bitowej,
j → <1;L> - adres wiersza w mapie bitowej
Rys2. Przedstawiający sposób wybierania piksela z bitmapy.
W programie występuje też zmienna p. Można ją rozumieć jako aktualną klatkę. W ciągu jednego cyklu p, na ekranie rysowanych jest K*L pikseli.
4.1. Implementacja algorytmu realizującego efekt zasłaniania poziomego obrazu w kierunku lewej strony ekranu.
Implementację naszego algorytmu możemy podzielić na 2 etapy, jak na rysunku poniżej:
Kod programu:
public void Efekt1()
{
if (p >= L) p = 0;
for (int j = 1; j <= L; j++)
{
for (int i = 1; I <= K – p ; i++)
ReadPixel(i, j);
for (int i = 1; I <= p; i++)
ReadTlo(N);
}
}
Algorytm realizujący pierwszy efekt został zaimplementowany w postaci metody publicznej Efekt1(). Zmienna p zwiększana jest o 1 po wygenerowaniu każdej klatki animacji. W kontekście tego algorytmu mówi ona ile kolumn o długości K pikseli zostało zastąpionych tłem.
Wartość tej zmiennej na początku jest równa 0, co oznacza że generowany jest cały obraz. Gdy osiągnie ona wartość L, a zatem wygenerowane zostaną wszystkie kolumny tła, jest ona zerowana.
Zewnętrzna pętla for odpowiedzialna jest za odczytanie wszystkich wierszy ekranu. Pierwsza z pętli wewnętrznych za pomocą funkcji ReadPixel() odczytuje z pamięci pierwsze K- p pikseli z pamięci i wypełnia nimi pierwsze K- p pikseli aktualnie generowanego wiersza. Druga z pętli wewnętrznych za pomocą metody publicznej ReadTlo(); wypełnia tłem pozostałe p pikseli aktualnie generowanego wiersza.
4.2. Efekt:
5.1. Implementacja algorytmu realizującego efekt przesuwania pionowego obrazu w kierunku górnej krawędzi ekranu:
Implementację naszego algorytmu możemy podzielić na 2 etapy, jak na rysunku poniżej:
Kod:
public void Efekt2()
{
if (p >= L) p = 0;
for (int j = p + 1; j <= L; j++)
for (int i = 1; i <= K; i++)
ReadPixel(i, j);
for (int j = 1; j <= p; j++)
for (int i = 1; i <= K; i++)
ReadTlo(N);
};
W tym przypadku również wykorzystujemy zmienną p. Jednak teraz ma ona za zadanie określenie wysokości tła. Podobnie jak poprzednim razem nasze zadanie dzielimy więc na 2 części. W funkcji Efekt2 przeglądamy tak samo jak w przypadku Efekt1 każdy piksel obrazu. Są tutaj dwie pętle pobierające wiersze. Jedna z nich odpowiedzialna jest na pobieranie wiersza następnego i zapisywanie go w aktualnym. Za każdym razem czynimy to o jeden raz mniej. Za to druga pętla, która wypełnia tłem resztę obrazka wykonuje jeden obieg za każdym razem więcej. W ten sposób uzyskujemy efekt przesuwania obrazka do góry.
5.2. Efekt:
6.1. Implementacja algorytmu realizującego efekt przewijania obrazu wzdłuż przekątnej ekranu w kierunku górnego lewego wierzchołka:
Implementację naszego algorytmu możemy podzielić na 4 etapy, jak na rysunku poniżej:
Kod:
public void Efekt1()
{
if (p >= L) p = 0;
for (int j = 1 + p; j <= L; j++)
{
for (int i = 1 ; i <= K-p ; i++)
ReadPixel(i, j);
for (int i = 1; i <= p ; i++)
ReadTlo(N);
}
for (int j = 1; j <= p ; j++)
{
for (int i = 1 + p ; i <= K ; i++)
ReadTlo(N);
for (int i = 1 ; i <= p ; i++)
ReadPixel(i, j);
}
}
W tej, najbardziej skomplikowanej funkcji zostały wykorzystane dwie pętle zewnętrzne. Pierwsza z nich odpowiada za przesuwanie obrazka w kierunku lewego górnego rogu ekranu oraz rysowanie tła w prawej górnej części ekranu.
Druga pętla odpowiada za rysowanie „dolnego tła” oraz dolnej części obrazka. Pojawianie się tła i przesuwanie obrazka, tutaj również jak poprzednio, odbywa się poprzez wykorzystanie licznika klatek p.
6.2. Efekt:
7.1. Wnioski:
Podsumowując: wszystkie postawione przede mną zadania zostały zrealizowane pomyślnie. W czasie wykonywania ćwiczenia należało zwrócić szczególną uwagę na liczbę generowanych pikseli w każdej klatce animacji. W przypadku rastrowego generowania grafiki każda klatka bowiem składa się z takiej samej ilości pikseli(L x K). Nawet najmniejsze odchylenie od tej reguły od razu powoduje błędną generację całego obrazu i powstawanie zupełnie niespodziewanych wyników działania. Należy jednak zauważyć, że sterowanie generatorem adresu odczytu grafiki źródłowej pozwala na uzyskanie wielu bardzo ciekawych efektów(m.in. przewijanie obrazu, przesuwanie obrazu, zasłanianie obrazu, obrót obrazu, zmniejszenie rozmiaru, lustrzane odbicia). Dzięki umiejętności projektowania i implementowania takich algorytmów, można wytwarzać np. animowane elementy stron WWW czy też wzbogacać funkcjonalność programów do edycji grafiki rastrowej.