Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych. Autor artykułu: mgr Jerzy Wałaszek, wersja1.0 |
©2008 mgr
Jerzy Wałaszek |
Poprzednie tematy, które należy przerobić przed przystąpieniem do tej lekcji:
01 - Instalacja biblioteki SDL dla Dev-C++
02 - Powierzchnia graficzna w SDL - stawianie punktów
03 - Tworzenie biblioteki graficznej mylib
04 - Stawianie punktów i rysowanie linii poziomych oraz
pionowych
Pliki biblioteczne i projektowe do pobrania: | Parametry dla konsolidatora |
mylib.h mylib.cpp main.cpp |
-lmingw32 -mwindows -lSDLmain -lSDL |
Na tej lekcji poznasz sposoby pracy z pikselami na powierzchni graficznej. Przy okazji utworzysz ciekawą grafikę komputerową.
Przed przystąpieniem do ćwiczeń utwórz nowy katalog. W katalogu utwórz nowy projekt SDL. Jako główny plik programu wybierz main.cpp z linku powyżej. Na początku programu dodaj wpis:
#include <cmath>
W naszej bibliotece mamy do dyspozycji funkcje stawiające punkt na powierzchni graficznej plot(x,y,color) oraz wyliczającej kolor ze składowych rgb(R,G,B).
Wykorzystamy te funkcje do otrzymania różnych ciekawych efektów. Na pierwszy ogień idzie funkcja sinus. Co o niej wiesz?
Jest to funkcja okresowa, tzn. jej wartości powtarzają się dla
argumentów różniących się wielokrotnością okresu 2π:
sin(x) = sin(x ± 2π) = sin(x ± 2 •
2π) = sin(x ± 3 • 2π) = sin(x ± 4 • 2π) = ... = sin(x ± k • 2π).
Wartości funkcji mieszczą się w przedziale <-1,1>.
Załóżmy, iż chcielibyśmy otrzymać w oknie SDL wykres jednego okresu funkcji sinus. Wykres musimy odpowiednio przeskalować, aby objął całe okno:
Oryginalny wykres funkcji sinus | Wykres przeskalowany do okna SDL |
W oknie SDL będziemy używali współrzędnych okna. Współrzędne wykresu muszą być zatem odwzorowane we współrzędne okna SDL:
Przedział <0,2π> w przedział <0,w-1>, gdzie w jest szerokością okna odczytaną ze struktury SDL_Surface screen.
Przedział <-1,1> w przedział <0,h-1>, gdzie h jest szerokością okna odczytaną ze struktury SDL_Surface screen.
Dodatkowo zwróć uwagę, iż układ współrzędnych SDL jest odwrócony do góry nogami w stosunku do układu współrzędnych kartezjańskich. Musimy ten fakt uwzględnić w naszych obliczeniach. Zastosujemy następujące wzory przeliczeniowe:
x = 2π • i / (w - 1), gdzie i przebiega wartości od 0 do w-1.
Wyliczoną wartość x podstawiamy do funkcji sinus i otrzymujemy jej wartość y. Wartość y przeliczamy na współrzędną ekranową ye wg wzoru:
ye = (1 - y) / 2 • (h - 1)
Ostatecznie do szablonu aplikacji SDL wstawiamy następujący fragment kodu:
for(int i = 0; i < screen->w; i++) plot(i,(Uint32)((1 - sin(6.28 * i / (screen->w - 1))) / 2 * (screen->h - 1)),0xFFFFFF); |
Rzutowanie (Uint32) ma na celu konwersję wyniku z typu double na typ argumentu Uint32. Pominięcie go spowoduje wygenerowanie ostrzeżenia przez kompilator, a ja lubię, gdy kompilacja przebiega bez żadnych komunikatów ostrzegawczych.
Efektem programu jest okno SDL z wykresem jednego okresu funkcji sinus:
Teraz dokonajmy prostej modyfikacji programu. Rysowanie sinusoidy powtórzymy 100 razy skalując wartość funkcji kolejno przez współczynniki od 0,01 do 1 co 1/100. W tym celu kod obejmujemy kolejną pętlą, w której będziemy generować wartość współczynnika f. Instrukcję plot musimy nieco zmodyfikować, aby uwzględniała współczynnik f:
for(double f = 0.01; f <= 1; f += 0.01) for(int i = 0; i < screen->w; i++) plot(i,(Uint32)((1 - f * sin(6.28 * i / (screen->w - 1))) / 2 * (screen->h - 1)),0xFFFFFF); |
Wykorzystajmy współczynnik f do modyfikacji koloru kolejnych sinusoid. W tym celu wykorzystamy funkcję rgb() z odpowiednimi składowymi koloru:
for(double f = 0.01; f <= 1; f += 0.01) for(int i = 0; i < screen->w; i++) plot(i,(Uint32)((1 - f * sin(6.28 * i / (screen->w - 1))) / 2 * (screen->h - 1)), rgb((Uint32)(f*255),255-(Uint32)(f*255),255)); |
Poeksperymentuj z różnymi wartościami kolorów. Uzależnij je również od współrzędnej na osi x. Można w ten sposób otrzymać ciekawe efekty graficzne:
A tutaj mamy nieco zaawansowany przykład - skalujemy wykres funkcji sin(x + fx2) również względem współrzędnej x. Otrzymany wykres odbijamy w pionie i poziomie i otrzymujemy interesującą grafikę - spróbuj zmienić wymiary okna oraz zagęścić zmiany współczynnika f:
double x,y; Uint32 color; for(double f = 0.005; f <= 1; f += 0.005) for(int i = 0; i < screen->w; i++) { x = 6.28 * i / (screen->w - 1); y = (1 - f * sin(x + f * x * x / 2)) / 2 * (screen->h - 1); color = rgb(255-(Uint32)((double)(i * 255)/(screen->w - 1)), (Uint32)(f * 255), (Uint32)((double)(i * 255)/(screen->w - 1))); plot(i,(Uint32)((i * y)/(screen->w - 1)),color); plot(i,screen->h - 1 - (Uint32)((i * y)/(screen->w - 1)),color); plot(screen->w - i - 1,(Uint32)((i * y)/(screen->w - 1)),color); plot(screen->w - i - 1,screen->h - 1 - (Uint32)((i * y)/(screen->w - 1)),color); } |
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe