Serwis Edukacyjny w I-LO w Tarnowie Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2025 mgr Jerzy Wałaszek |
SPIS TREŚCI |
|
Podrozdziały |
Niektóre z omawianych w artykule zagadnień stają się bardziej zrozumiałe po zastosowaniu grafiki komputerowej. Dlatego postanowiłem wyposażyć kilka przykładowych programów w bibliotekę graficzną BGI ( ang. Borland Graphic Interface ). Jest ona na dzisiejsze czasy już przestarzała, jednak posiada bardzo istotne zalety: łatwość instalacji oraz prostotę używania. Możliwości biblioteki BGI nie są dzisiaj imponujące, jednak na nasze potrzeby wystarczają zupełnie. Poniższy opis dotyczy instalacji biblioteki BGI w środowisku Windows.
Zainstaluj środowisko CodeBlocks.
Pobierz na swój komputer archiwum bgi.zip.
Rozpakuj to archiwum w dowolnym miejscu na swoim dysku. Otrzymasz katalog bgi:
Wewnątrz katalogu bgi znajdują się cztery pliki:
Pliki graphics.h oraz winbgim.h przekopiuj do katalogu include wewnątrz swojej instalacji CodeBlocks. Jeśli nie zmieniałeś miejsca docelowego dla CodeBlocks, to katalog ten znajdziesz w:
C:\Pliki programów (x86)\CodeBlocks\MinGW\include
Plik libbgi.a przekopiuj do katalogu lib, który znajdziesz wewnątrz katalogu MinGW:
C:\Program files (x86)\CodeBlocks\MinGW\lib
Uruchom CodeBlocks i utwórz nowy projekt konsoli. Z menu wybierz opcję:
W oknie dialogowym Global compiler settings przejdź na zakładkę Linker settings:
W sekcji Link libraries kliknij na dole przycisk Add i w okienku ładowania pliku wybierz plik libbgi.a z katalogu lib, do którego go przekopiowałeś.
Do pola tekstowego w sekcji Other linker options przekopiuj poniższy tekst:
-lbgi -lgdi32 -lcomdlg32 -luuid -loleaut32 -lole32
Zatwierdź zmiany przyciskiem OK.
Do edytora przekopiuj poniższy program:
Przykładowy program w języku C++
#include <iostream> #include <graphics.h> using namespace std; int main() { int gd = DETECT, gm; int x = 320, y = 240, r; initgraph(&gd, &gm, NULL); for(r = 25; r <= 125 ; r += 20) circle(x, y, r); getch(); closegraph(); return 0; } |
Skompiluj i uruchom program. Otrzymasz okno z rysunkiem:
Naciśnij dwa razy klawisz Enter ( pierwsze naciśnięcie zamyka okno graficzne, drugie zamyka okno konsoli ).
Aby nie powtarzać konfiguracji środowiska przy każdym nowym programie graficznym, zapisz swój projekt jako szablon. Z menu wybierz opcję:
Pojawi się okno dialogowe z prośbą o podanie nazwy szablonu:
Podaj taką nazwę, aby się kojarzyła z grafiką. U mnie będzie to bgi. Po zatwierdzeniu nazwy przyciskiem OK, pojawi się okno informujące o powodzeniu operacji:
CodeBlocks jest gotowe do używania biblioteki graficznej BGI. Nowy projekt tworzysz przez wybranie w kreatorze opcji User templates:
Wtedy zobaczysz nazwy dostępnych szablonów. Wybierasz bgi ( u ciebie może mieć inną nazwę ) i klikasz w przycisk Go:
Następnie wybierasz miejsce na swoim dysku, gdzie ma zostać utworzony projekt:
Pamiętaj, iż katalog projektu nie jest tutaj tworzony automatycznie. Musisz kliknąć w przycisk Utwórz nowy folder i wybrać nazwę dla katalogu, w którym zostanie umieszczony wybrany szablon projektu:
Projekt zostanie utworzony i w edytorze pojawi się program rysujący okręgi. To wszystko.
Bibliotekę BGI da się również zainstalować w Linuksie, jednak jest to zadanie dla raczej zaawansowanych użytkowników. Jeśli znasz dobrze język angielski ( jeśli nie, to naucz się go koniecznie ), zaglądnij tutaj:
https://askubuntu.com/questions/525051/how-do-i-use-graphics-h-in-ubuntu
Opiszmy kilka potrzebnych nam funkcji dostępnych w bibliotece graficznej BGI. W implementacji dla Windows biblioteka ta otrzymała kilka dodatkowych funkcji, których nie było w oryginale lub ich działanie było ograniczone. Związane są one z własnościami środowiska graficznego współczesnych komputerów.
Bibliotekę BGI ( ang. Borland Graphics Interface ) stworzyła znana firma Borland w czasach panowania systemu DOS. Dlatego jej funkcje są dostosowane do możliwości tego systemu oraz do możliwości graficznych dostępnych w owym czasie kart grafiki ( CGA, Hercules, EGA, VGA, itp. ). Dzisiaj te możliwości wyglądają marnie, lecz wykorzystanie współczesnych kart grafiki komplikuje program i wymaga nauki dosyć zaawansowanych bibliotek graficznych. Tutaj BGI ma niewątpliwą zaletę dla początkujących programistów oraz studentów. Z tego powodu bibliotekę BGI wciąż się wykorzystuje na wielu uczelniach.
Oto kilka przykładowych obrazków na różnych kartach graficznych wczesnych komputerów IBM-PC:
CGA |
Hercules |
EGA |
VGA |
Filozofia pracy z biblioteką BGI jest następująca:
Każdy program korzystający z biblioteki BGI musi mieć dołączony plik nagłówkowy graphics.h. Inicjujemy system graficzny przez wywołanie funkcji initgraph() lub initwindow(). Następnie wykonujemy różne operacje graficzne w utworzonym oknie, po czym zamykamy system graficzny za pomocą funkcji closegraph().
void initgraph(int *graphdriver, int *graphmode, char *pathtodriver); |
Funkcja inicjuje system graficzny biblioteki BGI.
graphdriver | – | numer sterownika graficznego:
Oryginalnie numer ten używany był do załadowania z dysku sterownika karty graficznej zainstalowanej w komputerze użytkownika. W obecnej wersji jest on używany jedynie do określenia maksymalnych rozmiarów tworzonego okna graficznego ( każda karta grafiki posiadała określoną rozdzielczość ). Najczęściej wykorzystuje się wartość DETECT, która ustawia rozmiar okna na maksymalny rozmiar dla wykrytego sterownika. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
graphmode | – | tryb graficzny dla wybranego sterownika:
Liczba kolorów nie jest istotna, ponieważ obecna implementacja BGI w Windows zawiera możliwość rysowania w dowolnym kolorze. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pathtodriver | – | ścieżka do pliku sterownika graficznego na dysku. Parametr ten nie jest używany w Windows i może być dowolnym tekstem. |
int initwindow(int width, int height, const char* title="Windows BGI", int left=0, int top=0, bool dbflag=false, closeflag=true); |
Funkcja dostępna w wersji BGI dla systemu Windows, nie było jej w takiej postaci w oryginalnej bibliotece Borlanda. Inicjuje bibliotekę BGI i otwiera ona okno graficzne o wybranych parametrach. Funkcja initwindow() wymaga tylko dwóch pierwszych parametrów, pozostałe są opcjonalne. Jeśli je pominiesz w wywołaniu, to przyjmą standardowe wartości. Zalecamy stosowanie tej funkcji zamiast initgraph(). Funkcja zwraca numer otwartego okna. Użytkownik może otwierać wiele okien, a numer służy do wyboru aktywnego okna. W oryginalnej bibliotece BGI można było otworzyć tylko jedno okno.
width | – | szerokość obszaru rysunkowego okna w pikselach. |
height | – | wysokość obszaru rysunkowego okna w pikselach. |
title | – | tytuł tworzonego okna. |
left, top | – | współrzędne lewego górnego narożnika okna |
dbflag | – | wartość true włącza podwójne buforowanie. |
closeflag | – | wartość true umożliwia użytkownikowi zamknięcie okna przez kliknięcie myszką w ikonę [x] na pasku tytułowym. |
void closegraph(int wid=ALL_WINDOWS); |
W oryginalnej bibliotece BGI funkcja closegraph() zamykała system graficzny, zwalniała pamięć i powodowała powrót do trybu tekstowego. W wersji dla systemu Windows funkcja posiada dodatkowy parametr, który może przyjąć wartość numeru otwartego okna. W takim przypadku zostaje zamknięte okno o tym numerze. Numer okna otrzymujemy jako wynik funkcji initwindow(). Jeśli w programie będzie otwierane kilka okien, to numer ten należy zapamiętać.
wid | – | numer okna do zamknięcia. Brak tego parametru spowoduje zamknięcie wszystkich okien BGI. |
void setcurrentwindow(int window); |
window | – | numer okna, które ma się stać oknem bieżącym. Numer ten jest wynikiem wywołania funkcji initwindow() |
int getcurrentwindow(); |
Poniższy program otwiera małe okno graficzne, oczekuje na klawisz, po czym zamyka to okno. Aby go uruchomić wykorzystaj szablon aplikacji bgi.
Przykładowy program graficzny
w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Test biblioteki BGI //---------------------------- #include <iostream> #include <graphics.h> using namespace std; int main() { initwindow(240,120,"Test BGI"); getch(); closegraph(); return 0; } |
Jeśli nie chcesz okna konsoli, to z menu wybierz opcję Project/Properties... Pojawi się okno dialogowe z własnościami projektu. Wybierz zakładkę Build targets i na liście Type zmień Console application na GUI application:
Gdy mamy już okno graficzne, to możemy w nim wykonywać różne operacje graficzne. Poniżej opisujemy podstawowe funkcje graficzne – pełny opis biblioteki BGI znajdziesz w sieci.
Kolory w oryginalnej bibliotece BGI były ograniczone do kolorów dostępnych na karcie graficznej komputera. Dla kart wyświetlających grafikę kolorową było to zwykle 16 następujących kolorów:
Nazwa | Wartość | Kolor |
---|---|---|
BLACK | 0 | |
BLUE | 1 | |
GREEN | 2 | |
CYAN | 3 | |
RED | 4 | |
MAGENTA | 5 | |
BROWN | 6 | |
LIGHTGRAY | 7 | |
DARKGRAY | 8 | |
LIGHTBLUE | 9 | |
LIGHTGREEN | 10 | |
LIGHTCYAN | 11 | |
LIGHTRED | 12 | |
LIGHTMAGENTA | 13 | |
YELLOW | 14 | |
WHITE | 15 |
Podane powyżej nazwy stałych oraz ich wartości liczbowe można wciąż używać w implementacji biblioteki BGI dla Windows, jednakże nowoczesne karty graficzne nie są już ograniczone do 16 kolorów. Dlatego w BGI dla Windows kolory w operacjach graficznych można również określać za pomocą składowych kolorów R ( ang. red – składowa czerwona ), G ( ang. green – składowa zielona ), B ( ang. blue – składowa niebieska ). Jeśli popatrzysz na ekran swojego monitora przez mocne szkło powiększające, to zobaczysz, że na jego powierzchni znajdują się punkty świecące tylko jednym z trzech kolorów składowych:
Pojedynczy piksel składa się z trzech takich punktów. Kolor piksela zależy od natężenia barw składowych. Do określania tego koloru w bibliotece BGI mamy makro COLOR(R,G,B). Zamienia ono wartości natężenia składowych koloru na kolor wynikowy. Składowe R, G i B mogą przyjmować wartości od 0 do 255:
R | G | B | Kolor |
---|---|---|---|
0 | 0 | 0 | |
0 | 0 | 204 | |
0 | 204 | 0 | |
0 | 204 | 204 | |
204 | 0 | 0 | |
204 | 0 | 204 | |
204 | 204 | 0 | |
204 | 204 | 204 | |
64 | 64 | 64 | |
0 | 0 | 255 | |
0 | 255 | 0 | |
0 | 255 | 255 | |
255 | 0 | 0 | |
255 | 0 | 255 | |
255 | 255 | 0 | |
255 | 255 | 255 |
void setcolor(int color); |
Ustawia bieżący kolor rysowania dla operacji graficznych.
color | – | wartość koloru może być podana jako liczba od 0 do 15, jako stała BLACK, BLUE, GREEN, ..., WHITE lub jako makro COLOR(). |
int getcolor(void); |
Zwraca wartość bieżąco używanego koloru. Jest to ta sama wartość, którą przekazano w parametrze funkcji setcolor().
Słowo piksel pochodzi z języka angielskiego ( ang. pixel ): pixel = picture element. Jest to najmniejszy, niepodzielny element obrazu, który przyjmuje jednolity kolor Powierzchnia robocza okna graficznego składa się z prostokątnej siatki pikseli, którą nazywamy rastrem ( ang. raster ):
W rastrze piksele ułożone są w poziome wiersze i pionowe kolumny. Ilość kolumn i wierszy określa rozmiar rastra ( np.: 1024 x 768 ). Piksele są zdefiniowane w rastrze poprzez ich współrzędne: numer kolumny oraz numer wiersza:
Na przykład:
Piksel A ma współrzędne (0,0) Piksel B ma współrzędne (2,4) Piksel C ma współrzędne (3,1) |
Jeśli przyrównamy to do osi układu współrzędnych, to numer kolumny będzie odpowiadał współrzędnej x, a numer wiersza będzie odpowiadał współrzędnej y. Oś OY jest skierowana w dół. Współrzędne nie przyjmują wartości ujemnych:
void putpixel(int x, int y, int color); |
Na pozycji (x,y) rysuje piksel w podanym kolorze.
x,y | – | współrzędne, na których ma zostać postawiony piksel |
color | – | wartość koloru może być podana jako liczba od 0 do 15, jako stała BLACK, BLUE, GREEN, ..., WHITE lub jako makro COLOR(). |
int getwindowheight(void); |
Zwraca łączną wysokość w pikselach bieżącego okna.
int getwindowwidth(void); |
Zwraca łączną szerokość w pikselach bieżącego okna.
int getmaxx(void); |
Zwraca największą wartość współrzędnej x w bieżącym oknie.
int getmaxy(void); |
Zwraca największą wartość współrzędnej y w bieżącym oknie.
Poniższy program wypełnia obszar graficzny okna pikselami o przypadkowych kolorach. Okno zamknij ikoną [x] na pasku tytułowym.
Przykładowy program graficzny
w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Piksele //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; int main() { int xmax,ymax; // Inicjujemy generator pseudolosowy srand(time(NULL)); // Otwieramy okno graficzne initwindow(400,300,"Piksele"); // Odczytujemy rozmiar obszaru roboczego okna xmax = getmaxx() + 1; ymax = getmaxy() + 1; // Pętla nieskończona while(1) { // Rysujemy piksel o przypadkowym kolorze putpixel(rand() % xmax, rand() % ymax, COLOR(rand() & 0xff, rand() & 0xff, rand() & 0xff)); } closegraph(); return 0; } |
Wynik:
Kolejny program uzależnia składowe koloru piksela od jego pozycji w oknie. Program działa w nieskończonej pętli, zamknij go kliknięciem w ikonę [x] na pasku tytułowym.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Piksele //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; int main() { int xmax,ymax; // Inicjujemy generator pseudolosowy srand(time(NULL)); // Otwieramy okno graficzne initwindow(200,200,"Piksele"); // Odczytujemy rozmiar obszaru roboczego okna xmax = getmaxx() + 1; ymax = getmaxy() + 1; int crs,cre,cgs,cge,cbs,cbe; // Kolory narożników int x,y; // Pozycja piksela int cr,cg,cb; // Kolor na pozycji piksela int r,rmax; rmax = (xmax - 1) * (xmax - 1) + (ymax - 1) * (ymax - 1); // Pętla nieskończona while(1) { // Generujemy kolory dla dwóch narożników. // Lewy górny crs = rand() & 0xff; cgs = rand() & 0xff; cbs = rand() & 0xff; // Prawy dolny cre = 255 - crs; cge = 255 - cgs; cbe = 255 - cbe; // Rysujemy piksele for(y = 0; y < ymax; y++) for(x = 0; x < xmax; x++) { // Wyliczamy kolor w punkcie (x,y) r = x * x + y * y; cr = crs + r * (cre - crs) / rmax; cg = cgs + r * (cge - cgs) / rmax; cb = cbs + r * (cbe - cbs) / rmax; // Stawiamy piksel putpixel(x,y,COLOR(cr,cg,cb)); } } closegraph(); return 0; } |
Wynik:
Za pomocą pikseli można narysować dowolną figurę geometryczną, jednakże nie jest to wcale takie proste. Już narysowanie zgrabnego odcinka wymaga dosyć skomplikowanego algorytmu, dlatego każda szanująca się biblioteka graficzna posiada odpowiednie funkcje.
void line(int x1, int y1, int x2, int y2); |
Rysuje odcinek od punktu (x1,y1) do punktu (x2,y2) za pomocą pikseli o bieżącym kolorze. Kolor ustawia się funkcją setcolor().
x1,y1 | – | współrzędne początku odcinka |
x2,y2 | – | współrzędne końca odcinka |
Poniższy program wypełnia okno przypadkowymi odcinkami. Program działa w nieskończonej pętli, zamknij go kliknięciem w ikonę [x] na pasku tytułowym.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Odcinki //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; int main() { int xmax,ymax; // Inicjujemy generator pseudolosowy srand(time(NULL)); // Otwieramy okno graficzne initwindow(400,400,"Odcinki"); // Odczytujemy rozmiar obszaru roboczego okna xmax = getmaxx() + 1; ymax = getmaxy() + 1; // Pętla nieskończona while(1) { // Ustawiamy przypadkowy kolor rysowania setcolor(COLOR(rand() & 0xff, rand() & 0xff, rand() & 0xff)); // Rysujemy odcinek w oknie line(rand() % xmax, rand() % ymax, rand() % xmax, rand() % ymax); } closegraph(); return 0; } |
Wynik:
Następny program jest ciekawszy. Za pomocą odcinków tworzy prostą grafikę. Program działa w nieskończonej pętli, zamknij go kliknięciem w ikonę [x] na pasku tytułowym.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Odcinki //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; int main() { int xmax,ymax,x,cr,cg,cb,er,eg,eb; // Inicjujemy generator pseudolosowy srand(time(NULL)); // Otwieramy okno graficzne initwindow(400,400,"Odcinki"); // Odczytujemy rozmiar obszaru roboczego okna xmax = getmaxx(); ymax = getmaxy(); // Generujemy kolor startowy cr = rand() & 0xff; cg = rand() & 0xff; cb = rand() & 0xff; // Generujemy kolor docelowy er = rand() & 0xff; eg = rand() & 0xff; eb = rand() & 0xff; // Pętla nieskończona while(1) { // Ustawiamy kolor setcolor(COLOR(cr,cg,cb)); // Modyfikujemy składowe kolorów if(cr > er) cr--; if(cr < er) cr++; if(cg > eg) cg--; if(cg < eg) cg++; if(cb > eb) cb--; if(cb < eb) cb++; if(cr == er) er = rand() & 0xff; if(cg == eg) eg = rand() & 0xff; if(cb == eb) eb = rand() & 0xff; // Rysujemy figurę x = 0; while(x <= xmax) { line(0,0,x,ymax); line(0,ymax,x,0); line(xmax,0,x,ymax); line(xmax,ymax,x,0); x += 10; } } closegraph(); return 0; } |
Wynik:
Łamana jest figurą zbudowaną z ciągu odcinków. W łamanej punkt końcowy jednego odcinka jest punktem startowym następnego. Łamaną można narysować przy pomocy wywołań funkcji line(), lecz w bibliotece BGI istnieje prostszy sposób.
void moveto(int x, int y); |
Ustawia bieżącą pozycję graficzną w punkcie (x,y). Funkcja nie rysuje nic na obszarze graficznym.
x,y | – | współrzędne pozycji, od której rozpocznie się rysowanie |
void lineto(int x, int y) |
Rysuje odcinek od bieżącej pozycji graficznej do punktu (x,y). Po narysowaniu odcinka punkt (x,y) staje się nową pozycją bieżącą.
x,y | – | współrzędne końca odcinka |
Poniższy program wykorzystuje podane funkcje moveto() i lineto() do narysowania ciekawej figury geometrycznej. Program działa w nieskończonej pętli, zamknij go kliknięciem w ikonę [x] na pasku tytułowym.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Łamana //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; int main() { int xmax,ymax,cr,cg,cb,er,eg,eb; // Inicjujemy generator pseudolosowy srand(time(NULL)); // Otwieramy okno graficzne initwindow(600,400,"Łamana"); // Odczytujemy rozmiar obszaru roboczego okna xmax = getmaxx() + 1; ymax = getmaxy() + 1; // Generujemy kolor startowy cr = rand() & 0xff; cg = rand() & 0xff; cb = rand() & 0xff; // Generujemy kolor docelowy er = rand() & 0xff; eg = rand() & 0xff; eb = rand() & 0xff; // Tworzymy N punktów na powierzchni graficznej const int N = 50; // Liczba punktów na obwodzie elipsy int x[N],y[N]; for(int i = 0; i < N; i++) { x[i] = rand() % xmax; y[i] = rand() % ymax; } // Pętla nieskończona while(1) { // Ustawiamy kolor setcolor(COLOR(cr,cg,cb)); // Modyfikujemy składowe kolorów if(cr > er) cr--; if(cr < er) cr++; if(cg > eg) cg--; if(cg < eg) cg++; if(cb > eb) cb--; if(cb < eb) cb++; if(cr == er) er = rand() & 0xff; if(cg == eg) eg = rand() & 0xff; if(cb == eb) eb = rand() & 0xff; // Rysujemy figurę moveto(x[0],y[0]); for(int i = 1; i < N; i++) lineto(x[i],y[i]); } closegraph(); return 0; } |
Wynik:
Kolejne funkcje umożliwiają rysowanie tych samych figur poczynając od wybranego punktu, ponieważ posługują się one współrzędnymi względnymi:
void moverel(int dx, int dy); |
Ustawia bieżącą pozycję graficzną w punkcie w odległości dx ( w poziomie ) i dy ( w pionie ) od poprzednio ustawionej pozycji graficznej. Funkcja nie rysuje nic na obszarze graficznym.
dx,dy | – | odległości w poziomie i w pionie od bieżącej pozycji graficznej |
void linerel(int dx, int dy); |
Rysuje odcinek od bieżącej pozycji graficznej do punktu odległego w poziomie o dx i w pionie o dy. Po narysowaniu odcinka punkt końcowy staje się nową pozycją bieżącą.
dx,dy | – | odległości w poziomie i w pionie od bieżącej pozycji graficznej |
Dodatkowo opiszmy kilka przydatnych funkcji biblioteki BGI:
void setbkcolor(int color); |
Ustawia kolor tła okna.
color | – | wartość koloru może być podana jako liczba od 0 do 15, jako stała BLACK, BLUE, GREEN, ..., WHITE lub jako makro COLOR(). |
int getbkcolor(void); |
Zwraca wartość bieżącego koloru tła.
void cleardevice(void); |
Zamalowuje całe okno kolorem tła i ustawia bieżącą pozycję graficzną w lewym górnym narożniku okna na współrzędnych (0,0).
color | – | wartość koloru może być podana jako liczba od 0 do 15, jako stała BLACK, BLUE, GREEN, ..., WHITE lub jako makro COLOR(). |
void delay(int millisec); |
Wstrzymuje wykonywanie programu na zadany okres czasu w milisekundach ( tysięcznych częściach sekundy ). Funkcja umożliwia tworzenie prostych animacji.
millisec | – | wartość opóźnienia. |
Poniższy program rysuje trójkąty w różnych miejscach okna graficznego. Program działa w nieskończonej pętli, zamknij go kliknięciem w ikonę [x] na pasku tytułowym.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Łamana //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; const int N = 50; // Liczba trójkątów int main() { int xmax,ymax,x[3],y[3],i,j; // Inicjujemy generator pseudolosowy srand(time(NULL)); // Otwieramy okno graficzne initwindow(600,400,"Trójkąty"); // Odczytujemy rozmiar obszaru roboczego okna xmax = getmaxx() + 1; ymax = getmaxy() + 1; // Pętla nieskończona while(1) { // Generujemy wierzchołki trójkąta for(i = 0; i < 2; i++) { x[i] = rand() % 200 - 100; y[i] = rand() % 200 - 100; } x[2] = -x[0] - x[1]; y[2] = -y[0] - y[1]; // Czyścimy treść okna cleardevice(); // Na przypadkowych pozycjach rysujemy N trójkątów for(i = 0; i < N; i++) { // Kolor trójkąta setcolor(COLOR(rand() & 0xff,rand() & 0xff,rand() & 0xff)); // Pozycja startowa moveto(rand() % xmax, rand() % ymax); // Rysujemy 3 odcinki for(j = 0; j < 3; j++) linerel(x[j],y[j]); } // Czekamy pół sekundy delay(500); } closegraph(); return 0; } |
Wynik:
Biblioteka BGI umożliwia odczyt naciśniętych klawiszy oraz pozycji i stanu przycisków myszki.
int kbhit(void); |
Funkcja zwraca wartość różną od zera, jeśli w buforze klawiatury oczekuje kod naciśniętego klawisza. Okno graficzne musi posiadać skupienie, inaczej biblioteka BGI nie ma kontroli nad klawiaturą. Funkcja przydaje się wtedy, gdy twoja aplikacja wyświetla jakąś animację, której nie chcesz przerywać oczekiwaniem na naciśnięcie klawisza przez użytkownika. Przykład użycia znajdziesz w programie poniżej.
int getch(void); |
Funkcja odczytuje kod naciśniętego klawisza i zwraca go jako swój wynik. Jeśli w buforze klawiatury nie oczekuje kod, to funkcja wstrzymuje działanie programu do momentu, aż użytkownik naciśnie klawisz. W pewnych wypadkach może to być niepożądane, ponieważ następuje zatrzymanie wykonywania programu. Rozwiązaniem jest użycie funkcji getch() wspólnie z funkcją kbhit():
... if(kbhit()) // Sprawdzamy, czy naciśnięto klawisz { key = getch(); // Odczytujemy kod naciśniętego klawisza ... // Przetwarzamy ten kod } ... |
Ten sposób nie powoduje zatrzymania programu, można go zatem stosować w prostych grach.
Jeśli naciśniętym klawiszem jest klawisz specjalny, to funkcja getch() zwróci wartość zero. W takim przypadku ponowne wywołanie getch() da nam kod naciśniętego klawisza specjalnego. Kody te są następujące:
#define KEY_HOME 71 #define KEY_UP 72 #define KEY_PGUP 73 #define KEY_LEFT 75 #define KEY_CENTER 76 #define KEY_RIGHT 77 #define KEY_END 79 #define KEY_DOWN 80 #define KEY_PGDN 81 #define KEY_INSERT 82 #define KEY_DELETE 83 #define KEY_F1 59 #define KEY_F2 60 #define KEY_F3 61 #define KEY_F4 62 #define KEY_F5 63 #define KEY_F6 64 #define KEY_F7 65 #define KEY_F8 66 #define KEY_F9 67 |
... key = getch(); // Odczytujemy kod klawisza if(!key) // Klawisz specjalny? { key = getch(); // Odczytujemy kod klawisza specjalnego ... // Przetwarzamy klawisz specjalny } else { ... // Przetwarzamy klawisz normalny } ... |
Jeśli naciśnięto klawisz normalny, to funkcja zwraca jego kod ASCII.
void getmouseclick(int kind, int& x, int& y); |
Funkcja odczytuje stan myszki dla zdarzenia, którego kod przekazujemy w parametrze kind. Jeśli dane zdarzenie wystąpiło i nie zostało jeszcze przetworzone, to w zmiennych x i y funkcja umieści współrzędne kursora myszki w chwili zdarzenia. Jeśli zdarzenie nie wystąpiło, to w x i y umieszczone zostają wartości -1. Funkcja nie czeka na wystąpienie zdarzenia. Rodzaje zdarzeń zdefiniowane są za pomocą stałych:
WM_MOUSEMOVE
WM_LBUTTONDBLCLK
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MBUTTONDBLCLK
WM_MBUTTONDOWN
WM_MBUTTONUP
WM_RBUTTONDBLCLK
WM_RBUTTONDOWN
WM_RBUTTONUP
bool ismouseclick(int kind); |
Funkcja zwraca wartość true, jeśli wystąpiło zdarzenie myszki podanego typu ( patrz powyżej ). Współrzędne x,y położenia kursora myszki w momencie zdarzenia można następnie odczytać za pomocą funkcji getmouseclick().
Poniższy program jest prostym edytorem graficznym. Umożliwia on rysowanie myszką w oknie. Kolor rysowanych linii wybieramy klawiszami: R (czerwony ), G ( zielony ), B (niebieski ) i W ( biały ). Zawartość okna czyścimy naciśnięciem prawego przycisku myszki. Linie rysujemy naciskając lewy przycisk myszki.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Klawiatura i myszka //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; int main() { // Inicjujemy generator pseudolosowy srand(time(NULL)); // Otwieramy okno graficzne initwindow(600,600,"Klawiatura/myszka"); // Zmienne int key; // klawisz int x,y; // Współrzędne kursora myszki bool drawing = FALSE; // Rysowanie setcolor(WHITE); // Pętla nieskończona while(1) { if(kbhit()) // Sprawdzamy, czy naciśnięto klawisz { key = getch(); // Tak, pobieramy kod klawisza switch(toupper(key)) { case 'W': setcolor(WHITE); break; case 'R': setcolor(LIGHTRED); break; case 'G': setcolor(LIGHTGREEN); break; case 'B': setcolor(LIGHTBLUE); break; default: break; } } // Sprawdzamy, czy wciśnieto prawy przycisk myszki getmouseclick(WM_RBUTTONDOWN,x,y); if(x != -1) { drawing = FALSE; cleardevice(); } // Sprawdzamy, czy wciśnięto lewy przycisk myszki getmouseclick(WM_LBUTTONDOWN,x,y); if(x != -1) { drawing = TRUE; moveto(x,y); } // Sprawdzamy, czy zwolniono lewy przycisk myszki getmouseclick(WM_LBUTTONUP,x,y); if(x != -1) { drawing = FALSE; lineto(x,y); } // Sprawdzamy, czy należy rysować if(drawing) { // Sprawdzamy, czy myszka wykonała ruch getmouseclick(WM_MOUSEMOVE,x,y); if(x != -1) lineto(x,y); } } closegraph(); return 0; } |
Wynik:
Często na utworzonej grafice będziesz chciał umieszczać jakieś napisy. Do tego celu biblioteka BGI posiada kilka funkcji. W języku C++ jesteśmy przyzwyczajeni do używania strumieni przy wyprowadzaniu tekstu. W BGI zdefiniowany jest globalny strumień wyjścia bgiout, który pracuje podobnie do strumienia cout. Jednakże nie wyświetla on wprowadzonego tekstu od razu w oknie graficznym, jak robi to strumień wyjścia konsoli cout, lecz umieszcza go w swojej wewnętrznej pamięci. Do wyświetlenia zawartości strumienia bgiout mamy dwie funkcje:
extern ostringstream bgiout; void outstream(ostringstream& out=bgiout); void outstreamxy(int x, int y, ostringstream& out=bgiout); |
Funkcje wyświetlają w oknie graficznym zawartość strumienia out typu ostringstream. Jeśli pominiesz strumień out na ich liście parametrów, to zostanie standardowo użyty strumień bgiout. Różnica pomiędzy outstream() a outstreamxy() jest taka, iż pierwsza funkcja wyświetla zawartość strumienia out na bieżącej pozycji graficznej, a druga robi to na pozycji (x,y). Obie funkcje czyszczą zawartość strumienia po jej wyświetleniu.
out | – | strumień typu ostringstream. Brak tego parametru spowoduje użycie strumienia bgiout. |
x,y | – | pozycja w oknie, na której zostanie wyświetlona zawartość strumienia out. |
Poniższy program tworzy przykładową grafikę z tekstem. Po naciśnięciu klawisza następuje zmiana. Program działa w nieskończonej pętli, zamknij go kliknięciem w ikonę [x] na pasku tytułowym.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Grafika i tekst //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; extern ostringstream bgiout; int main(void) { // Zmienne int xmax,ymax,x1,y1,x2,y2; // Inicjujemy generator pseudolosowy srand(time(NULL)); // Tworzymy okno graficzne initwindow(600, 400,"Tekst"); xmax = getmaxx(); ymax = getmaxy(); // Pętla nieskończona while(1) { // Czyścimy okno cleardevice(); // Generujemy początek odcinka x1 = xmax / 4 + rand() % 100; y1 = ymax / 4 + rand() % 100; // Generujemy koniec odcinka x2 = (3 * xmax / 4) - rand() % 100; y2 = (3 * ymax / 4) - rand() % 100; // Rysujemy odcinek w kolorze żółtym setcolor(YELLOW); line(x1,y1,x2,y2); // Kolor tekstu jasnozielony setcolor(LIGHTGREEN); // Współrzędne początku bgiout << "początek:" << endl << "(" << x1 << "," << y1 << ")"; outstreamxy(x1 - 36,y1 - 36); // Kolor tekstu jasnoczerwony setcolor(LIGHTRED); // Współrzędne końca bgiout << "koniec:" << endl << "(" << x2 << "," << y2 << ")"; outstreamxy(x2 - 24,y2 + 4); // Kolor tekstu biały setcolor(WHITE); // Czekamy na klawisz bgiout << "Naciśnij dowolny klawisz..."; outstreamxy(0,0); getch(); } closegraph( ); return 0; } |
Wynik:
Do wyświetlania łańcuchów znakowych mamy w bibliotece BGI dwie funkcje:
void outtext(char *textstring); void outtextxy(int x, int y, char *textstring); |
Funkcje wyświetlają podany łańcuch tekstowy textstring w oknie graficznym. Funkcja outtext() wyświetla tekst od bieżącej pozycji graficznej. Funkcja outtextxy() wyświetla tekst od pozycji (x,y).
textstring | – | łańcuch tekstu do wyświetlenia |
x,y | – | pozycja w oknie, na której zostanie wyświetlony tekst. |
Poniższy program wypełnia treść okna przypadkowymi literami od A do Z. Program działa w nieskończonej pętli, zamknij go kliknięciem w ikonę [x] na pasku tytułowym.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Tekst //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; extern ostringstream bgiout; int main(void) { // Zmienne int xmax,ymax; char t[2]; t[1] = 0; // Znak EOT, czyli koniec tekstu // Inicjujemy generator pseudolosowy srand(time(NULL)); // Tworzymy okno graficzne initwindow(600, 400,"Tekst"); xmax = getmaxx(); ymax = getmaxy(); // Pętla nieskończona while(1) { // Generujemy znak od A do Z t[0] = 'A' + rand() % ('Z' - 'A' + 1); // Kolor znaku setcolor(1 + rand() % 15); // Piszemy znak outtextxy(rand() % xmax, rand() % ymax, t); } closegraph( ); return 0; } |
Wynik:
Opisane funkcje tekstowe współdziałają z funkcjami, które w bibliotece BGI ustawiają różne parametry tekstu, takie jak kolor liter, pozycja w oknie, krój czcionki, rozmiar, kierunek, długość i wysokość w pikselach oraz sposób wyrównywania.
void setcolor(int color); |
Ustawia bieżący kolor liter.
color | – | wartość koloru może być podana jako liczba od 0 do 15, jako stała BLACK, BLUE, GREEN, ..., WHITE lub jako makro COLOR(). |
void setbkcolor(int color); |
Ustawia kolor tła liter.
color | – | wartość koloru może być podana jako liczba od 0 do 15, jako stała BLACK, BLUE, GREEN, ..., WHITE lub jako makro COLOR(). |
void moveto(int x, int y); |
Ustawia początkową pozycję do wyświetlenia tekstu dla funkcji, które nie ustawiają tej pozycji samodzielnie.
x,y | – | współrzędne pozycji, od której rozpocznie się rysowanie tekstu |
void moverel(int dx, int dy); |
Ustawia bieżącą pozycję graficzną w punkcie w odległości dx ( w poziomie ) i dy ( w pionie ) od poprzednio ustawionej pozycji graficznej. Funkcja nie rysuje nic na obszarze graficznym.
dx,dy | – | odległości w poziomie i w pionie od bieżącej pozycji graficznej |
void settextstyle(int font, int direction, int charsize); |
Funkcja ustawia krój czcionki, kierunek wypisywania tekstu oraz rozmiar znaków.
font | – | stała określająca krój czcionki, którą użyją
funkcje wyświetlające tekst. Ustawienie nowego kroju działa przy
następnym wyświetleniu tekstu. Tekst już wyświetlony w oknie nie
zmienia się. W Windows kroje są pobierane z zestawu czcionek
systemowych. Rozpoznawane stałe mają wartości od 0 do 10:
|
||||||||||||||||||||||||||||||||||||
direction | – | kierunek wypisywania liter. Dostępne są dwie opcje:
|
||||||||||||||||||||||||||||||||||||
charsize | – | określa wielkość czcionek. Dozwolone wartości są od 0 do 10, gdzie 0 oznacza rozmiar użytkownika, 1 oznacza wielkość standardową, 2 oznacza wielkość podwójną, itd. |
void setusercharsize(int multx, int divx, int multy, int divy); |
Funkcja pozwala skalować czcionki wektorowe. Ponieważ biblioteka BGI używa tylko liczb całkowitych, to skalowanie definiowane jest przez dwie liczby: mnożnik i dzielnik. Na przykład, jeśli chcesz uzyskać czcionkę o szerokości w osi x 1/3 normalnej i wysokości w osi y 4/5 normalnej, to stosujesz wywołanie:
settextstyle(xxx,HORIZ_DIR,0); setusercharsize(1,3,4,5);
Szczerze mówiąc nie jest to poprawnie zaimplementowane w Windows, działa tylko w kierunku poziomym. W kierunku pionowym nie ma zmian.
multx,divx | – | mnożnik i dzielnik do skalowania w osi x |
multy,divy | – | mnożnik i dzielnik do skalowania w osi y |
int textwidth(char *textstring); int textheight(char *textstring); |
Z uwagi na skalowanie czcionek tekst może zajmować różne miejsce w obszarze okna. Te funkcje zwracają długość ( textwidth() ) lub wysokość ( textheight() ) tekstu w pikselach przy bieżących parametrach wyświetlania tekstu,
textstring | – | łańcuch tekstu, którego długość lub wysokość zostanie zwrócona |
void settextjustify(int horiz, int vert); |
Funkcja określa sposób pozycjonowania tekstu przez funkcje wyświetlające tekst w oknie graficznym. Pozycjonowanie wykonywane jest względem bieżącej pozycji graficznej.
horiz | – | określa pozycjonowanie tekstu w poziomie względem
bieżącej pozycji graficznej. Może przyjmować następujące wartości:
|
||||||||||||
vert | – | określa sposób pozycjonowania tekstu w pionie
względem bieżącej pozycji graficznej:
|
Poniższy program wyświetla w oknie graficznym teksty o różnych ustawieniach. Prześledź go dokładnie. Program działa w nieskończonej pętli, zamknij go kliknięciem w ikonę [x] na pasku tytułowym. Program oczekuje na dowolny klawisz przy zmianach wyświetlanych treści.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Tekst //---------------------------- #include <iostream> #include <graphics.h> using namespace std; int main(void) { // Zmienne char * f[] = {(char *)"Standard", (char *)"Triplex", (char *)"Small", (char *)"Sans Serif", (char *)"Gothic", (char *)"Script", (char *)"Simplex", (char *)"Triplex Script", (char *)"Complex", (char *)"European", (char *)"Bold"}; int i,x,y,s = 0; // Tworzymy okno graficzne initwindow(600, 500,"Tekst"); // Pętla nieskończona while(1) { switch(s++) { case 0: setbkcolor(BLUE); cleardevice(); setcolor(YELLOW); x = getmaxx() / 2; y = 64; for(i = DEFAULT_FONT; i <= BOLD_FONT; i++) { if(i == SMALL_FONT) settextstyle(i,HORIZ_DIR,4); else settextstyle(i,HORIZ_DIR,1); settextjustify(CENTER_TEXT,TOP_TEXT); outtextxy(x,y,f[i]); y += 16 + textheight(f[i]); } break; case 1: setbkcolor(RED); cleardevice(); setcolor(WHITE); x = 120; y = getmaxy() / 2; for(i = DEFAULT_FONT; i <= BOLD_FONT; i++) { if(i == SMALL_FONT) settextstyle(i,VERT_DIR,4); else settextstyle(i,VERT_DIR,1); settextjustify(LEFT_TEXT,CENTER_TEXT); outtextxy(x,y,f[i]); x += 16 + textheight(f[i]); } break; case 2: setbkcolor(BLACK); cleardevice(); setcolor(LIGHTRED); y = 16; for(i = DEFAULT_FONT; i <= BOLD_FONT; i++) { x = 16; settextstyle(i,HORIZ_DIR,0); settextjustify(LEFT_TEXT,TOP_TEXT); setusercharsize(1,1,1,1); moveto(x,y); outtext(f[i]); setusercharsize(2,3,1,1); outtext((char *)" : A"); setusercharsize(1,1,1,1); outtext((char *)"A"); setusercharsize(2,1,1,1); outtext((char *)"A"); setusercharsize(3,1,1,1); outtext((char *)"A"); setusercharsize(4,1,1,1); outtext((char *)"A"); y += 16 + textheight("Ay"); } break; } if(s == 3) s = 0; // Czekamy na klawisz getch(); } closegraph( ); return 0; } |
Wyniki:
Uwagi: implementacja wyświetlania tekstów w bibliotece BGI dla Windows ( Windows 10 64-bitowe ) nie jest najlepsza. Czcionka Small jest normalnie wyświetlana jako zbyt mała i napisy stają się zupełnie nieczytelne. Dlatego w programie wybrałem dla niej wielkość 4. Czcionki Script i Triplex Script drukowane są identycznie. Tak samo czcionki Triplex, Simplex i European. Nie sprawdzałem działania tego programu w innych systemach Windows, bo nie mam do nich teraz dostępu.
Uwagi: przy druku pionowym w bibliotece BGI są błędy przy czcionce Small i Sans Serif. Small nie jest wcale drukowana, a Sans Serif drukowana jest poziomo.
Uwagi: przy rozmiarze użytkownika czcionka standardowa nie zmienia się wcale, czcionki Smal i Sans Serif drukowane są źle.
Oprócz pikseli i odcinków biblioteka BGI zawiera funkcje rysujące różne figury geometryczne. Tutaj krótko opiszemy kilka z nich.
void drawpoly(int numpoints, int *polypoints); |
Funkcja rysuje łamaną zbudowaną zbudowaną z odcinków łączących podane wierzchołki.
numpoints | – | liczba wierzchołków łamanej |
polypoints | – | wskazanie tablicy liczb całkowitych, która zawiera pary współrzędnych wierzchołków łamanej. |
Poniższy program jest przykładem prostej animacji łamanej. Program działa w nieskończonej pętli, zamknij go kliknięciem w ikonę [x] na pasku tytułowym.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Obiekty //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; const int N = 20; // Liczba wierzchołków łamanej int main(void) { // Zmienne int xy[2 * N],dxy[2 * N],xmax,ymax,i,j; int cr,cg,cb,dr,dg,db; // Inicjujemy generator pseudolosowy srand(time(NULL)); // Tworzymy okno graficzne initwindow(500, 400,"Łamane"); xmax = getmaxx() + 1; ymax = getmaxy() + 1; // Inicjujemy tablice wierzchołków for(i = 0; i < N; i++) { j = i + i; xy[j] = rand() % xmax; do dxy[j] = 3 - rand() % 7; while(!dxy[j]); j++; xy[j] = rand() % ymax; do dxy[j] = 3 - rand() % 7; while(!dxy[j]); } // inicjujemy kolory składowe cr = rand() & 0xff; cg = rand() & 0xff; cb = rand() & 0xff; do dr = 3 - rand() % 7; while(!dr); do dg = 3 - rand() % 7; while(!dg); do db = 3 - rand() % 7; while(!db); // Pętla nieskończona while(1) { // Ustawiamy kolor setcolor(COLOR(cr,cg,cb)); // Rysujemy łamaną drawpoly(N,xy); // modyfikujemy kolory cr += dr; if((cr < 0) || (cr > 255)) { dr = -dr; cr += dr; } cg += dg; if((cg < 0) || (cg > 255)) { dg = -dg; cg += dg; } cb += dr; if((cb < 0) || (cb > 255)) { db = -db; cb += db; } // Modyfikujemy współrzędne wierzchołków for(i = 0; i < N; i++) { j = i + i; xy[j] += dxy[j]; if((xy[j] < 0) || (xy[j] >= xmax)) dxy[j] = -dxy[j]; j++; xy[j] += dxy[j]; if((xy[j] < 0) || (xy[j] >= ymax)) dxy[j] = -dxy[j]; } // Opóźnienie 1/20 sekundy delay(20); } closegraph( ); return 0; } |
Wynik:
Jeśli łamana ma tworzyć figurę zamkniętą, to ostatni wierzchołek w tablicy musi być równy pierwszemu wierzchołkowi. Wynika z tego, iż tablica musi zawierać o jeden wierzchołek więcej. Prosta modyfikacja powyższego programu tworzy trójkąty:
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Obiekty //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; const int N = 3; // Liczba wierzchołków łamanej int main(void) { // Zmienne int xy[2 * (N + 1)],dxy[2 * N],xmax,ymax,i,j; int cr,cg,cb,dr,dg,db; // Inicjujemy generator pseudolosowy srand(time(NULL)); // Tworzymy okno graficzne initwindow(500, 400,"Trójkąty"); xmax = getmaxx() + 1; ymax = getmaxy() + 1; // Inicjujemy tablice wierzchołków for(i = 0; i < N; i++) { j = i + i; xy[j] = rand() % xmax; do dxy[j] = 3 - rand() % 7; while(!dxy[j]); j++; xy[j] = rand() % ymax; do dxy[j] = 3 - rand() % 7; while(!dxy[j]); } xy[6] = xy[0]; xy[7] = xy[1]; // inicjujemy kolory składowe cr = rand() & 0xff; cg = rand() & 0xff; cb = rand() & 0xff; do dr = 3 - rand() % 7; while(!dr); do dg = 3 - rand() % 7; while(!dg); do db = 3 - rand() % 7; while(!db); // Pętla nieskończona while(1) { // Ustawiamy kolor setcolor(COLOR(cr,cg,cb)); // Rysujemy łamaną drawpoly(N + 1,xy); // modyfikujemy kolory cr += dr; if((cr < 0) || (cr > 255)) { dr = -dr; cr += dr; } cg += dg; if((cg < 0) || (cg > 255)) { dg = -dg; cg += dg; } cb += dr; if((cb < 0) || (cb > 255)) { db = -db; cb += db; } // Modyfikujemy współrzędne wierzchołków for(i = 0; i < N; i++) { j = i + i; xy[j] += dxy[j]; if((xy[j] < 0) || (xy[j] >= xmax)) dxy[j] = -dxy[j]; j++; xy[j] += dxy[j]; if((xy[j] < 0) || (xy[j] >= ymax)) dxy[j] = -dxy[j]; } xy[6] = xy[0]; xy[7] = xy[1]; // Opóźnienie 1/20 sekundy delay(20); } closegraph( ); return 0; } |
Wynik:
void setfillstyle(int pattern, int color); |
Funkcja ustawia sposób wypełniania figur oraz kolor wypełnienia.
patern | – | stała określająca sposób wypełniania obszaru
figury. Dozwolone są następujące wartości:
|
||||||||||||||||||||||||||||||||||||||||||
color | – | kolor wypełnienia jako stała 0...15, BLACK...WHITE lub jako kolor RGB ustawiany przez makro COLOR(). |
void setfillpattern(char *upattern, int color); |
Funkcja ustawia wypełnienie zdefiniowane przez użytkownika oraz jego kolor.
upattern | – | jest wskaźnikiem tablicy 8-bajtowej, która określa matrycę 8 × 8 bitów z wzorem wypełnienia. Każdy bajt tablicy jest jednym, 8-bitowym wierszem matrycy wypełnienia. |
color | – | kolor wypełnienia jako stała 0...15, BLACK...WHITE lub jako kolor RGB ustawiany przez makro COLOR(). |
void fillpoly(int numpoints, int *polypoints); |
Funkcja rysuje wielokąt zdefiniowany przez numpoints wierzchołków (wielokąt jest automatycznie zamykany) wykorzystując bieżący kolor rysowania. Następnie wypełnia go zgodnie z bieżącym sposobem wypełniania.
upattern | – | jest wskaźnikiem tablicy 8-bajtowej, która określa matrycę 8 × 8 bitów z wzorem wypełnienia. Każdy bajt tablicy jest jednym, 8-bitowym wierszem matrycy wypełnienia. |
color | – | kolor wypełnienia jako stała 0...15, BLACK...WHITE lub jako kolor RGB ustawiany przez makro COLOR(). |
Poniższy program generuje wielokąt zbudowany z zadanej liczby wierzchołków, po czym wypełnia go poszczególnymi rodzajami wypełnienia. Poszczególne etapy są wyzwalane naciśnięciami klawiszy.
Przykładowy program
graficzny w języku C++
// BGI // (C)2020 mgr Jerzy Wałaszek // Metody numeryczne // Obiekty //---------------------------- #include <iostream> #include <graphics.h> #include <cstdlib> #include <ctime> using namespace std; const int N = 10; // Liczba wierzchołków wielokąta int main(void) { // Zmienne char * s[] = {(char *)"EMPTY_FILL", (char *)"SOLID_FILL", (char *)"LINE_FILL", (char *)"LTSLASH_FILL", (char *)"SLASH_FILL", (char *)"BKSLASH_FILL ", (char *)"LTBKSLASH_FILL", (char *)"HATCH_FILL", (char *)"XHATCH_FILL", (char *)"INTERLEAVE_FILL", (char *)"WIDE_DOT_FILL", (char *)"CLOSE_DOT_FILL", (char *)"USER_FILL"}; char f[] = { 0x00, // 00000000 0x7E, // 01111110 0x42, // 01000010 0x5A, // 01011010 0x5A, // 01011010 0x42, // 01000010 0x7E, // 01111110 0x00}; // 00000000 int p[2 * N]; int i,j,xmax,ymax; // Inicjujemy generator pseudolosowy srand(time(NULL)); // Tworzymy okno graficzne initwindow(600, 400,"Wieloboki"); xmax = getmaxx() + 1; ymax = getmaxy() + 1; // Generujemy wierzchołki for(i = 0; i < N; i++) { j = i + i; p[j++] = rand() % xmax; p[j] = 32 + rand() % (ymax - 32); } // Wyświetlamy wielobok z kolejnymi wypełnieniami for(i = EMPTY_FILL; i <= USER_FILL; i++) { // Czyścimy okno cleardevice(); // Kolor tła setbkcolor(BLUE); // Kolor Linii setcolor(WHITE); // Rodzaj i kolor wypełnienia if(i != USER_FILL) setfillstyle(i,YELLOW); else setfillpattern(f,LIGHTRED); // Rysujemy wielobok fillpoly(N,p); // Wyświetlamy nazwę wypełnienia setcolor(LIGHTCYAN); setbkcolor(BLACK); settextstyle(TRIPLEX_FONT,HORIZ_DIR,2); settextjustify(CENTER_TEXT,TOP_TEXT); moveto(xmax / 2, 5); outtext(s[i]); // Czekamy na klawisz getch(); } closegraph( ); return 0; } |
Wynik:
void setlinestyle(int linestyle, unsigned upattern, int thickness); |
Funkcja ustawia sposób rysowania linii w bibliotece BGI.
linestyle | – | parametr określa styl linii. Może przyjąć
następujące wartości:
|
||||||||||||||||||
upattern | – | jeśli styl linii został określony jako USERBIT_LINE, to parametr ten jest traktowany jako 16 bitowy wzorzec do rysowania linii Bit ustawiony na 1 jest rysowany w aktualnym kolorze rysowania, bit ustawiony na 0 rysowany jest w kolorze tła. Jeśli styl linii jest inny od USERBIT_LINE, to wartość parametru upattern jest ignorowana. | ||||||||||||||||||
thickness | – | parametr określa grubość linii. Przyjmuje tylko
dwie wartości:
|
void rectangle(int left, int top, int right, int bottom); |
Funkcja rysuje czworokąt wykorzystując bieżący kolor oraz bieżący styl linii.
left,top | – | współrzędne lewego górnego narożnika prostokąta. |
right,bottom | – | współrzędne prawego dolnego narożnika prostokąta. |
void bar(int left, int top, int right, int bottom); |
Funkcja wypełnia prostokątny obszar za pomocą bieżącego stylu i koloru wypełnienia. Funkcja nie rysuje linii brzegowej.
left,top | – | współrzędne lewego górnego narożnika obszaru. |
right,bottom | – | współrzędne prawego dolnego narożnika obszaru. |
void circle(int x, int y, int radius); |
Funkcja rysuje okrąg. Używa aktualnego koloru oraz grubości linii. Styl linii nie jest używany.
x,y | – | współrzędne środka okręgu |
radius | – | promień okręgu. |
void fillellipse(int x, int y, int xradius, int yradius); |
Funkcja rysuje elipsę wykorzystując bieżący kolor linii oraz grubość linii ( styl linii nie jest używany ), po czym wypełnia ją wg bieżącego stylu i koloru wypełnienia.
x,y | – | współrzędne środka elipsy |
xradius | – | promień elipsy w osi x. |
yradius | – | promień elipsy w osi y. |
Na tym kończymy opis biblioteki BGI. Mamy nadzieję, iż podane tutaj informacje pozwolą skutecznie wykorzystywać to proste narzędzie we własnych programach.
Poniżej umieściliśmy alfabetyczne zestawienie funkcji biblioteki BGI opisanych w tym rozdziale. Z funkcji tych będziemy korzystać w następnych rozdziałach w tym artykule. W bibliotece BGI jest dużo więcej różnych funkcji, a jeśli cię to zainteresowało, to ich opis znajdziesz w witrynie ( w języku angielskim ):
Borland Graphics Interface (BGI) for Windows
Biblioteka BGI dla Windows nie jest w pełni dopracowana (szczególnie jeśli chodzi o wyświetlanie tekstów ) i nie stanowi konkurencji dla profesjonalnych bibliotek graficznych, np. SDL2, OpenGL lub DirectX. Jednak jej zaletą jest prostota instalacji i stosowania, dlatego nadaje się szczególnie dobrze do naszych celów. Dzięki niej możesz łatwo wyposażać swoje programy w prosty interfejs graficzny do celów prezentacji wyników obliczeń. W następnym rozdziale opisujemy sposoby tworzenia wykresów funkcji matematycznych za pomocą biblioteki BGI, które wykorzystamy do prezentacji wyników obliczeń.
void bar(int left, int top, int right, int bottom); void circle(int x, int y, int radius); void cleardevice(void); void closegraph(int wid=ALL_WINDOWS); void delay(int millisec); void drawpoly(int numpoints, int *polypoints); void fillpoly(int numpoints, int *polypoints); int getbkcolor(void); int getch(void); int getcolor(void); int getcurrentwindow(); int getmaxx(void); int getmaxy(void); void getmouseclick(int kind, int& x, int& y); int getwindowheight(void);void initgraph(int *graphdriver, int *graphmode, char *pathtodriver); int getwindowwidth(void); int initwindow(int width, int height, const char* title="Windows BGI", int left=0, int top=0, bool dbflag=false, closeflag=true); bool ismouseclick(int kind); int kbhit(void); void line(int x1, int y1, int x2, int y2); void linerel(int dx, int dy); void lineto(int x, int y); void moverel(int dx, int dy); void moveto(int x, int y); void outstream(ostringstream& out=bgiout); void outstreamxy(int x, int y, ostringstream& out=bgiout); void outtext(char *textstring); void outtextxy(int x, int y, char *textstring); void putpixel(int x, int y, int color); void rectangle(int left, int top, int right, int bottom); void setbkcolor(int color); void setcolor(int color); void setcurrentwindow(int window); void setfillstyle(int pattern, int color); void setlinestyle(int linestyle, unsigned upattern, int thickness); void settextjustify(int horiz, int vert); void setfillpattern(char *upattern, int color); void settextstyle(int font, int direction, int charsize); void setusercharsize(int multx, int divx, int multy, int divy); int textheight(char *textstring); int textwidth(char *textstring); |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2025 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.