Grafika Kompjuterike meteriali per gjenreaten 2013
-
Upload
astrit-jashari -
Category
Documents
-
view
716 -
download
20
description
Transcript of Grafika Kompjuterike meteriali per gjenreaten 2013
Universiteti i Prishtinës
Fakulteti i Inxhinierisë Elektrike dhe Kompjuterike
GRAFIKA KOMPJUTERIKE (Materiali i ligjëratave dhe ushtrimeve)
Adnan Maxhuni
Artan Mazrekaj
Prishtinë, 2013
Grafika kompjuterike
-2-
HYRJE
Grafika kompjuterike është një prej fushave më interesante dhe me rritjen më të shpejtë. Ky lëmi
është bërë një element kryesor për krijimin e interfejsit për shfrytëzuesin, vizualizimin e të dhënave,
televizionin komercial, animacionet e figurave dhe objekteve dy dhe tridimensionale, si dhe shumë e
shumë aplikacione tjera. Janë zhvilluar njësi harduerike por edhe algoritme duke mundësuar kështu
gjenerimin e figurave me shumë efekte grafike dhe trendi është që të realizohen algoritme në principin e
figurave tridimensionale.
Në fillimet e përdorimit, grafika përdorej në disa fusha shumë specifike, si inxhinieri dhe
shkencë. Sot, nuk ka pothuajse fushë në të cilën nuk ka përdorim të grafikës kompjuterike: shkencë,
inxhinieri, arkitekturë, mjekësi, biznes, industri, art, arsim, trajnime, simulime të proceseve fizike, etj.
Së pari, zhvillimi i hovshëm i teknologjisë elektronike, ka mundësuar produkte të shumta
harduerike për produktet grafike. Në anën tjetër, zhvillime të mëdha në standardin për softuerin grafik
kanë ndodhur qysh prej paketit të parë GKS (Graphical Kernel System), të lansuar nga Organizata
Ndërkombëtare e Standardeve (ISO) dhe ANSI (American National Standards Institute). Tani, standardi
PHIGS (Programmer’s Hierarchical Interactive Graphics Standard) është një standard i të dy
organizatave – ISO dhe ANSI. Për më tepër, janë paraqitur një numër i madh i paketave softuerike
industriale, duke përfshirë Silicon Graphics GL (Graphics Library), OpenGL, intefejsin Pixar
RenderMan, interpretuesin PostScript për përshkrimin e faqeve, si dhe një mori të sistemeve dizajnuese
për vizatim, ngjyrosje dhe ndërlidhje objektesh. Zhvillimi i grafikës kompjuterike është si rezultat i
zhvillimeve të mëdha harduerike dhe atyre softuerike: kompjuterë të shpejtë, për të cilët sasia e madhe e
të dhënave të fotografive nuk paraqet më ndonjë problem, si dhe aplikacione për të cilët përpunimi i
shpejtë i të dhënave nuk është pikë e dobët.
Grafika kompjuterike
-3-
Figura 1. Dritarja e një aplikacioni për CAD
Paraqitja vizuale e objekteve në kompjuter është një gjë shumë e rëndësishme. Grafika
kompjuterike, përpos për efekte vizuale, përdoret edhe për simulimin e shumë proceseve dhe teknikave
në lëmenjtë nga më të ndryshmit.
Figura 2. Dritarja e një programi për simulime të qarqeve elektronike
Grafika kompjuterike
-4-
Paketat softuerike për CAD (Computer Aided Design) ofrojnë dizajnimin në një ambient me
shumë dritare, ku secila dritare paraqet madhësi dhe këndvështrime të ndryshme të pjesëve të objektit.
Programet aplikative për CAD dhe dokumentim teknik
Për shkak të nevojave të dizajnimit dhe projektimit në fusha të ndryshme, janë krijuar shumë
programe për grafikë. Softueret që merren me insertimin e objekteve të ndryshme dhe ndërlidhjen mes
tyre, njihen si softuere ndihmuese për grafikë - CAD (Computer-Aided Design). Programet e tilla
zakonisht e kanë të inkorporuar edhe pjesën për dokumentim teknik. Softuere të tilla ka shumë dhe
zakonisht janë të specifikuara për fusha të veçanta. Një softuer i thjeshtë për paraqitje grafike të
objekteve është programi Visio, që tanimë është bërë pjesë e MS Office-it. Një program i ngjashëm dhe
që është në përdorim tash e një kohë të gjatë, është edhe Corel Draw. Këto janë programe të thjeshta
për përdorim, edhepse mundësitë e tyre, në versionet e fundit, janë zgjëruar shumë, duke përfshirë plane
rrugësh, ndërtesash, rrjetash telekomunikuese, paisje mekanike, etj. etj.
Përveq softuerëve që përfshijnë shumë fusha të paraqitjes grafike (si Visio), në përdorim shumë
të madh janë edhe softueret për qëllime më të ngushta, si p.sh. për projektime arkitektonike
(ArchiCAD), për sisteme mekanike (AutoCAD), me shumë nënversione. Programet e këtilla kanë
mundësi shumë të mëdha në fushën për të cilën janë përpiluar. Disa prej këtyre softuerëve madje kanë
edhe elemente të programimit (gjuhëve programuese). Këta softuerë përdoren zakonisht prej
profesionistëve të fushave përkatëse. P.sh. sot janë në shfrytëzim programe shumë të specializuara për
trajnimin e shoferëve të makinave.
Lojrat kompjuterike janë një fushë me shumë imagjinatë sa i përket grafikës kompjuterike. Fusha
e simulimeve në këtë sferë është jashtëzakonisht e gjërë.
Grafika kompjuterike
-5-
Figura 3. Pamje e një figure të një loje kompjuterike
Një lëmi shumë e përhapur dhe e përdorur është edhe ajo e procesimit (përpunimit) të imazheve.
Softuerët për këto qëllime (si p.sh. Photoshop) përmbajnë vegla dhe funksione për përpunim të
fotografiveve dhe imazheve. Procesimi i fotografive dhe imazheve është shumë atraktiv, sidomos në
botën komerciale dhe të arteve vizuale.
Programimi dhe grafika
Programet aplikative, edhepse me mundësi të shumta, janë të kufizuara në përdorimin e veglave
të parapara për përdorim. Grafika me mundësi të pakufizuara dhe vizualizimi i të dhënave në forma nga
më të ndryshmet, merr kuptimin e plotë me përdorimin e gjuhëve programuese. Siç e dijmë, programi
është një varg i rreshtave të instruksioneve. Pothuajse të gjitha gjuhët programuese i kanë të zhvilluara
modulet me procedurat dhe instruksionet për grafikë. Përdorimi i tyre bënë të mundur vizatimet dhe
imazhet nga më të ndryshmet.
Gjuhët programuese si C, C++, C#, Java, Visual Basic, etj. e kanë mjaftë të zhvilluar pjesën e
grafikës. Te gjuhët programuese, funksionet për grafikë janë të vendosuar në modulet përkatëse dhe
thirrja e tyre bëhet brenda programit burimor, si p.sh.:
#include <GL/gl.h>
#include <GL/glu.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
Grafika kompjuterike
-6-
Një softuer me përdorim shumë të gjërë është edhe OpenGL. Për më tepër që ky softuer është
‘open source’. OpenGL është një ‘software interface’ për hardware-in grafik. Ky interfejs përbëhet prej
rreth 150 komandash të ndryshme që mund të shfrytëzohen për specifikim të objekteve dhe
operacioneve të nevojshme për të krijuar aplikacione interaktive tredimensionale.
P.sh. në kodin e mëposhtëm është paraqitur programi përmes të cilit do të vizatohej figura që
është paraqitur pas ekzekutimit të këtij kodi.
#include <whateverYouNeed.h>
main() {
InitializeAWindowPlease();
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f (0.25, 0.25, 0.0);
glVertex3f (0.75, 0.25, 0.0);
glVertex3f (0.75, 0.75, 0.0);
glVertex3f (0.25, 0.75, 0.0);
glEnd();
glFlush();
UpdateTheWindowAndCheckForEvents();
}
Figura 4. Pamja e figurës që fitohet pas ekzekutimit të programit
Gjuhët programuese kanë mundësinë që me përdorimin e urdhërave, të krijohen edhe figura të
lëvizshme apo animacione. P.sh. pjesa e kodit që do të lëvizë një katror nëpër ekran do të ishte:
Grafika kompjuterike
-7-
open_window();
for (i = 0; i < 1000000; i++)
{
clear_the_window();
draw_frame(i);
wait_until_a_24th_of_a_second_is_over();
}
P.sh. Një program (në Turbo Pascal) që do të vizatonte harqe (pjesë të rrethit), me qendër si
numër të rastit do të ishte.
Program Harqet_e_rastesishme;
Uses Graph,Crt;
Const
n=150;
Var
a,b,k: Integer;
(*$I c:\TP\GRAFIKA*)
Begin
GRAFIKA;
Randomize;
Repeat
ClearViewPort;
a:=Random(360);
b:=Random(360);
For k:=1 To n Do
Begin
SetColor(Random(16));
Arc(220+k,200+k,a,b,180);
End;
Delay(500);
Until KeyPressed;
ReadLn;
CloseGraph;
End.
Gjuhët programuese përdorin procedurat për grafikë edhe për ndërtimin e interfejsit grafik, ose si
njihet ndryshe GUI-Graphic User Intarface (p.sh. gjuha Visual Basic, C++, etj.). GUI e bënë
përdorimin e aplikacioneve të ndryshme shumë të lehtë dhe miqësor për shfrytëzuesin, duke përdorur
Grafika kompjuterike
-8-
veglat grafike (butonat, kutitë vërtetuese, menytë, etj.). P.sh. kodi vijues në Qt të C++, krijon dritaren e
paraqitur në vijim.
#include <qapplication.h>
00#include <qlabel.h>
00int main(int argc, char *argv[])
00{
00QApplication app(argc, argv);
00QLabel *label = new QLabel("Tung Qt!", 0);
00app.setMainWidget(label);
00label->show();
00return app.exec();
0 }
Figura 5. Rezultati i programit në Qt
Fushat në të cilat përdoret grafika kompjuterike janë të shumta. Ne do të fokusohemi në
prodhimin e fotografisë, gjegjësisht ngjyrat, gjenerimin e objekteve themelore (primitive), përdorimin e
gjuhës programuese C# për grafikë, si dhe transformimet e objekteve, që paraqesin bazën e
animacioneve.
Njësitë harduerike për paraqitjet grafike
Në rastet më të shpeshta, njësia kryesore dalëse ku shfaqen objektet grafike, është një video
monitor. Puna e shumicës së video monitorëve është e bazuar në dizajnin standard të gypit katodik
CRT (Cathode-Ray Tube).
Figura 6. Ekrani CRT
Grafika kompjuterike
-9-
Ekrani CRT është i ndërtuar prej gypit katodik me fokusim të rrezes së elektroneve, të cilat
godasin sipërfaqën e fosforit. Sipërfaqja e fosforit është e ndërtuar prej pikave. Secila pikë, në të vërtetë
është e përbërë prej tri pikave me ngjyra të ndryshme. Në bazë të intenziteve të rrezeve që bien në këto
pika, formohen ngjyrat e figurës.
Figura 7. Skema e gypit katodik me vakum
Siperfaqet me fosfor janë disa llojesh. Përveç ngjyrave, një karakteristikë tjetër e rëndësishme
është edhe persistenca, që paraqet kohën se sa gjatëdo të emitojë dritë pasi të jetë ndërprerë burimi i
dritës. Persistenca e ekraneve të sotëm është prej 10 deri 60 mikrosekonda. Shpërndarja e intenzitetit të
gjurmës së dritës në sipërfaqen fosforike është Gausiane.
Figura 8. Funksioni i Gausit
Grafika kompjuterike
-10-
Numri maksimal i pikave që mund të shfaqen (pa mbuluar njëra tjetrën) në një CRT njihet si
rezolucion. Rezolucioni varet nga tipi i fosforit, intenziteti që do shfaqet dhe nga fokusimi i rrezes
përmes sistemit të devijimit. Rezolucioni tipik i sistemeve cilësore (të njohura si High-Definition) është
1280 * 1024. Madhësia fizike e ekranit shprehet me gjatësinë e diagonales së ekranit, që në të shumtën
e rasteve është prej 12 deri 27 inça.
Llojet kryesore të monitorëve grafik të zhvilluar në teknologjinë CRT janë ekranet raster-scan,
që bazohen në teknologjinë e televizionit. Në sistemin raster-scan, rrezja e elektroneve lëvizë
(zhvendoset) në vijat horizontale, duke filluar nga këndi i sipërm majtas. Numri i vijave horizontale
(scan line) është i ndryshëm (në shumicën e sistemeve TV është 625). Një pikë e kësaj linje njihet si
piksel (pixel – pictures element). Ndriçimi i pikselit varet nga intenziteti i rrezes, me të cilën goditet ai.
Ndrrimi i ekraneve të sotshëm, që në teknikat e mëhershme ka qenë 25, bëhet me shpejtësi 60 deri 80
herë brenda sekondës. Kjo zakonisht shprehet si frekuencë, me njësinë përkatëse herc (Hz). Sistemet
më të reja këtë shpejtësi e kanë 100 deri 200 Hz.
Burimi i elektroneve në gypin katodik, në të vërtetë përbëhet prej tri tubave, nga një për ngjyrat
bazë: e kuqe (Red), e gjelbër (Green) dhe e kaltër (Blue). Për këtë arsye, ky sistem njihet edhe si RGB.
Intenziteti i këtyre tri rrezeve dirigjohet prej sistemit të brendshëm të monitorit. Fokusimi i këtyre
rrezeve bëhet prej tubit katodik, ndërsa filtrimi i mëtutjeshëm bëhet edhe prej maskës që është e
vendosur përpara rasterit.
Decenien e fundit, monitorët CRT janë zëvendësuar në masë të madhe prej paneleve plasma, apo
si njihen ndryshe si flat. Ekranet e këtilla janë të ndërtuar ashtuqë hapësira ndërmjet dy xhamave është e
mbushur me një lloj gasi.
Sisteme tjera për parqitjen e grafikës janë edhe displejët e njohur si LCD (Liquid-Crystal
Displays), që fillimisht janë përdorur për ekrane të vogla (kalkulatrët, laptopët e vegjël, instrumentet
matëse, etj.). Termi ‘Liquid Crystal’ ka të bëjë me hapësirën që ka një radhitje kristalore të molekulave,
kështuqë lëvizja e tyre i gjason lëngut.
Sistemi Raster-Scan
Sistemi grafik i rasterit interaktiv drejtohet prej njësive të ndryshme të procesimit. Njësia
qëndrore (CPU) dirigjon monitorin përmes njësisë që njihet si Video kontroller (Video Controler ose
Grafika kompjuterike
-11-
Display Controler). Një pjesë fikse e kujtesës së sistemit është e rezervuar për frame buffer-in dhe
video kontrolleri merr direkt qasjen në memorien frame-buffer.
Memoria sistemore, ka në vete memorien Frame Buffer.
Figura 9. Skema bllok e njësisë grafike
Ekrani duhet të rifreskohet 60 herë për sekondë. Për këtë arsye kjo nuk mund të kryhet prej
memories RAM, sepse cikli kohor është shumë i ngadalshëm. Më poshtë kemi paraqitur funksionet
kryesore të video kontrollerit.
Grafika kompjuterike
-12-
Figura 10. Bllok-skema e sistemit Raster-Scan
Si njësi grafike harduerike janë edhe paisjet hyrëse/dalëse që paraqesin hyrjet/daljet në forma të
ndryshme, si: skanerët, printerët, ploterët, etj.
Grafika kompjuterike
-13-
SISTEMI I NGJYRAVE
Grafika në kompjuter përbëhet prej kombinimit të ngjyrave të pikave elementare, që njihen si
piksela (pixels). Nëse imazhit bardh e zi i ndërrohen ngjyrat, ashtuqë ai të përmbajë nuansa të ndryshme
të ngjyrës së hirtë, paraqitja e imazhit në ekran do të përmirësohet. Ngjyra e një objekti varet jo vetëm
nga objekti por edhe nga ndriçimi i objektit, nga ngjyrat e tjera që e rrethojnë atë objekt si dhe nga
sistemi vizual i njeriut. Disa objekte reflektojnë dritën, ndërsa disa të tjera e transmetojnë (gjenerojnë)
atë. Nëse një sipërfaqe e cila reflekton vetëm ngjyrën e pastër të kaltër ndriçohet me ngjyrë të kuqe të
pastër, ngjyra e asaj sipërfaqeje do të duket si e zezë.
DRITA AKROMATIKE
Drita akromatike është ajo që shikohet në ekranin bardh e zi (televizorin apo monitorin e
kompjuterit). Atributi i vetëm i dritës akromatike është intensiteti i dritës. Sasia e dritës mund të
diskutohet në pikëpamje fizike të energjisë, ku përdoret termi intensitet dhe ndriçim, apo në formë
psikologjike të perceptimit të intensitetit, ku përdoret termi ngopje (shkëlqim). Këtu mund të përdoret
një variabël (ndryshore) me vlera të ndryshme, ashtu që vlera 0 e definon ngjyrën e zezë, ndërsa vlera 1
e definon ngjyrën e bardhë. Në këtë rast vlerat në mes 0 dhe 1 përdoren për paraqitjen e vlerave
(nuansave) të ngjyrës së hirtë. Në kuptim të sinjalit që gjeneron intenzitetin e dritës, ngjyra e zezë
paraqet sinjalin me fuqi zero (gjendjen pa sinjal), ndërsa ngjyra e bardhë gjendjen me sinjal të plotë
(100% të fuqisë së tij).
Grafika kompjuterike
-14-
Televizori bardh e zi mund të ketë vlera të ndryshme për një pozitë të pikselit. Printerët
matricorë, ploterët elektrostatikë, etj. mund të kenë vetëm dy vlera të ndryshme: ngjyra e bardhë e letrës
dhe ngjyra e zezë e cila do të ngjyroset nga toneri.
ZGJEDHJA E VLERAVE TE INTENSITETIT
Çdo piksel në ekran paraqitet me një vlerë të intensitetit të dritës. Paraqitja e kësaj vlere, në
sistemin digjital të përpunimit të fotografisë, bëhet me një kombinim të bitave që përdoren për
paraqitje. P.sh. nëse dëshirojmë që të paraqesim 256 intensite të ndryshme të dritës, do të jenë të
nevojshëm 8 bita për paraqitje të një vlere të ngjyrës së pikselit, spese për çdo nivel të vlerë (nivel)
mund të shfrytëzohet një kombinim 8-bitësh (28=256). Selektimi i kësaj vlere bëhet për shkak se çdo
piksel mund të paraqitet me 8 bita. Ndahën vlerat në mënyrë të barabartë në rangun prej 0 në 1
(kuantizohen). Por, syri i njeriut nuk është i ndjeshëm në vlerat absolute të intensitetit por në shkallë
logaritmike. P.sh. syri do të perceptojë vlerat e intensitetit 0.10 dhe 0.11 si vlera të ndryshme për aq sa
do t’i perceptojë vlerat e intensitetit 0.50 dhe 0.55. Në shkallën e ndriçimit apo të intensitetit të
perceptuar diferenca në mes intensiteteve 0.10 dhe 0.11 dhe në mes të intensiteteve 0.50 dhe 0.55 është
e njejtë. Pra, nivelet e intensiteteve duhet të ndahen në mënyrë logaritmike e jo lineare. Kjo është si
rrjedhojë e vetive të syrit të njeriut, i cili ndryshimet e intenzitetit i përjeton në formën logaritmike (jo
lineare). Në të vërtetë, e njëjta ndodhë edhe me shqisat tjera (p.sh. ato të dëgjimit).
Në mënyrë që të gjejmë 256 intensitetet e ndryshme fillohet me intensitetin më të vogël të
mundshëm I0 deri te niveli maksimal me intensitet 1.0, ashtu që intensiteti i caktuar është r-herë më i
madh se intensiteti paraprak. Kjo mund të shihet nga relacionet e mëposhtme:
Grafika kompjuterike
-15-
I0 = I0 ; I1 = rI0; I2 = rI1 = r2I0 ; I3 = rI2 = r
3I0 ; ... I255 = r
255I0 = 1 .............(1)
Prandaj
r = (1/I0)1/255
, Ij = rjI0 = (1/I0)
j/255 Io = I0
(255 – j)/255 për 0≤ j ≤ 255..........(2)
dhe për n + 1 intensitete,
r = (1/I0)1/n
Ij = I0(n – j)/n
për 0≤ j ≤ n (3)
Nëse vlera e n-it është 3 dhe nëse vlera e I0 është 1/8 do të fitohet vlera e r-it 2, ndërsa vlerat e
intensiteteve do të jenë 1/8, 1/4, 1/2 dhe 1.
Vlera minimale e intensitetit I0 për një gyp katodik është ndërmjet 1/200 dhe 1/40 e vlerës
maksimale 1.0. Për këtë arsye vlerat tipike të I0 janë ndërmjet 0.005 dhe 0.025. Vlera minimale nuk
është zero për shkak të reflektimit të dritës nga fosfori i gypit katodik. Raporti në mes vlerës maksimale
dhe minimale të intensiteteve quhet rangu dinamik. Gjetja e vlerave të sakta për një gyp katodik bëhet
me ekspozimin e një katrori të bardhë në fushë të zezë dhe pas kësaj bëhet matja e dy intensiteteve me
fotometër. Kjo bëhet në ambient të errët, ashtu që të mos ketë reflektim të dritës.
Paraqitja precize e intensiteteve të definuara me barazinë (1) është mjaft e vështirë. Kjo mund të
eleminohet me teknikën e quajtur korreksioni gama që përfshin korreksionin e tabelës gjetëse ( lookup
table) të ekranit rasterik me vlera kompensuese.
Problem tjetër që shtrohet është se sa vlera të intenisteteve mjaftojnë, apo sa duhet të jetë numri
që nevojitet për të krijuar një imazh bardh e zi ashtu që nuansat të jenë kontinuale (të pandërprera). Kjo
mund të arrihet kur raporti r është 1.01 ose më i vogël (nëse ky raport është më i vogël, syri nuk mund
t’i dallojë intensitetet Ij dhe Ij+1). Kështu vlera për n mund të gjindet nëse vlerën r e barazojmë me 1.01
në ekuacionin (3)
r = (1/I0)1/n
ose 1.01 = (1/I0)1/n
Pas aplikimit të operacionit të logaritmimit fitohet vlera për n
n = log1.01(1/I0)
Grafika kompjuterike
-16-
Rangu dinamik 1/I0 për disa mediume dhe vlera n është treguar në tabelë. Këto janë vlera teorike
ndërsa praktikisht mund të vijë deri te mjegullimi për shkak të zbehjes së ngjyrës (tonerit) apo zhurmës
së rastësisshme që paraqitet.
Rangu dinamik (1/I0) dhe numri i intensiteteve që nevojiten n = log1.01(1/I0) për disa
mediume
Mediumi Rangu dinamik tipik Numri i niveleve të
intensiteve (n)
Gypi katodik
Fotografitë
Slajdet fotografike
Gazeta e shtypur në bardh e zi
50-200
100
1000
10
400-530
465
700
234
Për shembull, në figurën 11 është paraqitur një fotografi me nuansa kontinuale, ndërsa në figurën
12, fotografia e njejtë e cila është me 4 nivele përkatësisht me 32 nivele të intensiteteve.
Figura 11. Fotografia me nuanca kontinuale
Te rasti me 4 nivele kalimi prej njërit nivel në tjetrin është i dukshëm sepse raporti r ndërmjet
intensiteteve është më i madh se 1.01. Ndërsa te reprodukimi i fotografisë me 32 nivele të intensiteteve
kalimi prej njërit nivel në tjetrin mezi dallohet dhe do të zhduket tërësisht nëse i kemi 64 nivele. Kjo
sugjeron se 64 nivele të intensiteteve do të jetë minimumi në rastin e shtypjes së librave bardh e zi. Në
rastin e gypave katodik rangu dinamik është më i lartë që kërkon shfrytëzim të më shumë niveleve të
intensiteteve.
Grafika kompjuterike
-17-
Figura 12. Efekti i niveleve të intensiteteve në reprodukimin e fotografisë. a) Fotografia e
reprodukuar me 4 nivele të intensiteteve b) Fotografia e reprodukuar me 32 nivele të intesiteteve
APROKSIMIMI I GJYSËMTONEVE
Shumë mediume për paraqitje të fotografisë (monitorë) si dhe paisjet për printim janë me dy
nivele të intensiteteve. Poashtu paisjet rasterike me 2-3 bita për piksel krijojnë intensitete më të vogla se
që dëshirohet. Si mund të rritet rangu i niveleve me të cilat disponohet? Përgjigja është në integrimin
hapësinor që bëhet nga syri i njeriut. Nëse e shikojmë një sipërfaqe të vogël nga një distancë e madhe
syri nuk mund t’i vërejë detalet dhe do të mund t’a vërejë vetëm objektin në përgjithësi.
Figura 13. Gjysmëtonimi e zgjeron numrin e intensiteteve në rastin kur numri i rangut dinamik
është i vogël
Grafika kompjuterike
-18-
Ky efekt përdoret në industrinë e printimit të fotografive bardh e zi në gazeta dhe libra dhe
teknika e tillë quhet gjysëmtonim ( halftoning). Figura 14 tregon një mostër të gjysëmtonuar e cila është
rritur për disa herë. Çdo pjesë e vogël do të printohet me një rreth të vogël të ngjyrës së zezë, sipërfaqja
e të cilit është proporcionale me intensitetin e ngjyrës e zezë të sipërfaqes së fotografisë origjinale.
Mostra do të formojë këndin prej 450 në krahasim me boshtin horizontal dhe këndi i tillë quhet këndi i
ekranit.
Figura 14. Pesë nivele të intensiteteve me 4 mostra 2x2
Paisjet grafike dalëse mund të përafrojnë sipërfaqen e ndryshueshme të rrathëve të reprodukimit
gjysëmtonik. P.sh. sipërfaqja e pikselave 2x2 e një mediumi me 2 nivele mund të shfrytëzohet për të
krijuar 5 nivele të ndryshme të intensitetit në llogari të rezolucionit hapësinor përgjatë çdo boshti.
Mostrat e treguara në figurën 14 mund të shfrytëzohen për të mbushur sipërfaqen 2x2. Figura 15 tregon
fytyrën e digjitalizuar si një sipërfaqe 351x351 dhe e cila do të paraqitet me mostrën 2x2.
Figura 15. Fotografia e digjitalizuar me rezolucion 351x351 dhe e cila është treguar me mostrën
2x2 të figures 14.
Grupi i n*n pikselave me 2 nivele mund të sigurojë (n2 + 1) nivele të intensiteteve. Ekziston një
kompromis në mes të rezolucionit hapësinor dhe rezolucionit të intensiteteve. Kështu, nëse merret
Grafika kompjuterike
-19-
mostra 3x3 atëherë rezolucioni hapësinor do të zvoglohet për 1/3 përgjatë çdo boshti, mirëpo kjo
siguron që të kemi 10 nivele të intensiteteve.
Aproksimimi gjysëmtonik nuk është i kufizuar vetëm në mediumet me 2 nivele. Të marrim se e
kemi një medium me 2 bita për piksel dhe 4 nivele të intensiteve. Teknika e gjysëmtonimit mund të
rrisë numrin e niveleve të intensiteteve. Nëse e kemi mostrën 2x2, atëherë disponojmë me 4 piksela,
secili prej tyre mund të ketë 3 vlera tjera përveq të zezës; ky fakt mundëson që të paraqiten 4 * 3 + 1 =
13 intensitete.
Teknika e paraqitur më lartë supozon se matrica e imazhit që paraqitet është më e vogël se
matrica e paisjes për paraqitje (ekranit). Çka nëse matricat për imazh dhe paisjen për paraqitje në dalje
janë të njejta? Një qasje është që të shfrytëzohet një teknikë e zhvilluar nga Floyd dhe Steinberg e cila
quhet difuzioni i gabimit ( error diffusion). Gabimi (diferenca në mes vlerës së saktë të pikselit dhe
vlerës së përafruar) i shtohet pikselave të cilët gjenden në matricën 2x2 në këtë mënyrë. Pikselit i cili
është në të djathtë i shtohet vlera 7/16 e gabimit. Vlera 3/16 e gabimit i shtohet pikselit poshtë dhe
majtas në krahasim me pikselin që shqyrtohet. Vlera 5/16 i shtohet pikselit të poshtëm ndërsa vlera 1/16
e gabimit i shtohet pikselit poshtë djathas. Kjo strategji bën të mundur shpërndarjen e gabimit. Figura
16 është krijuar nga kjo metodë.
Figura 16. Fotografia e fituar pas përdorimi të algoritmit të Floyd-Steinberg-ut
Nëse është dhënë fotografia S që duhet të paraqitet në matricën e intensiteteve I, vlerat e
ndryshuara në S dhe vlerat e paraqituara në I llogariten për pikselat që skanohen prej linjës së epërme
në imazh duke shkuar poshtë deri te linja më e poshtme. Pseudokodi për këtë teknikë është:
K = Aproksimimi(S[x][y]); // aproksimohet S
I[x][y] = K;// vizatohet pikseli në pozitën (x,y)
Grafika kompjuterike
-20-
gabimi = S[x][y] – K;
// shpërndaje 7/16 të gabimit pikselit djathtas
S[x + 1][y] += 7 * gabimi / 16;
// shpërndaje 3/16 të gabimit pikselit poshtë dhe majtas
S[x - 1][y - 1] += 3 * gabimi / 16;
// shpërndaje 5/16 të gabimit pikselit poshtë
S[x][y - 1] += 5 * gabimi / 16;
// shpërndaje 1/16 të gabimit pikselit poshtë dhe djathtas
S[x + 1][y - 1] += gabimi / 16;
NGJYRAT KROMATIKE
Efektet vizuale të shkaktuara nga ngjyrat janë shumë më të pasura se ato të shkaktuara nga drita
kromatike. Diskutimet për perceptimin e ngjyrave zakonisht përfshijnë tri madhësi të njohura si
ngjyrimi, ngopja dhe ndriçimi ( hue, saturation, lightness). Ngjyrimi (hue) dallon mes ngjyrave si p.sh.
e kuqja, e gjelbërta, e verdha, etj. Ngopja (saturation) tregon se sa ndryshon një ngjyrë nga ngjyra e
hirtë me intensitete të njejta. Ngjyra e kuqe është e ngopur, ngjyra e kaltër e çelur është relativisht e
pangopur. Ngjyrat pastele jane të pangopura, ndërsa ngjyrat e ndezura janë të ngopura. Ndriçimi
(lightness) është nocion që lidhet me intensitetin e perceptuar të objektit të reflektuar. Shkëlqimi
(brightness) është termi që ndonjëherë përdoret në vend të ndriçimit. Shkëlqimi ka të bëjë me
intensitetin e perceptuar të objektit që emeton dritë, si psh. poçi elektrik, dielli apo gypi katodik.
Është e domosdoshme që të specifikohen dhe të bëhet matja e ngjyrave në mënyrë që të
shfrytëzohen në mënyrë precize në grafikën kompjuterike. Kështu njëri nga sistemet që përdoren është
sistemi i radhitjes së ngjyrave të Munsell-it. Ky sistem përfshinë një bashkësi të ngjyrave të publikuara
të organizuara në hapësirën tridimensionale të ngjyrimit (hue), vlerës (që e kemi definuar si ndriçim)
dhe ngopjes. Çdo ngjyrë është emëruar dhe është e renditur ashtu që të ketë distancë të njejtë të
perceptuar në hapsirën e ngjyrave nga ngjyra fqinje.
Artistët shpesh e bëjnë specifikimin e ngjyrave sipas nuansave (tint), hijeve (shade) dhe toneve
(tone) të pigmenteve të ngopura apo të pastërta. Ndarja e ngjyrave sipas nuancës, hijes dhe tonit quhet
metoda e artistit. Nuansa (tint) krijohet kur pigmentit të bardhë i shtohet një pigment i pastër, ashtu që
ngopja e ngjyrës zvoglohet. Hija (shade) krijohet kur pigmentit të zi i shtohet pigmenti i pastër, ashtu që
ndriçimi zvoglohet. Toni është pasojë e shtimit të pigmentit të zi dhe të bardhë në pigmentin e pastër.
Grafika kompjuterike
-21-
Të gjithë këta hapa prodhojnë ngjyra të ndryshme me ngjyrim të njejtë, ndërsa ngopja dhe ndriçimi
ndryshon. Duke i përzier pigmentet e ngjyrës së bardhë dhe të zezë, krijohen nuancat e ngjyrës së hirtë.
Figura 17 tregon relacionin në mes të nuansave, hijeve dhe toneve. Përqindja e pigmenteve që duhet të
përzihet për të përshtatur një ngjyrë mund të shfrytëzohet si specifikim i ngjyrës.
Figura 17. Relacionet ndërmjet nuansës, tonit dhe hijes.
Aspekti psikofizik i ngjyrave
Definimi i ngjyrave sipas metodës së Munsell-it dhe metodës së artistit është definim subjektiv i
ngjyrave. Këto dy metoda varen nga mendimi i vrojtuesit, ndriçueshmëria, madhësia e mostrës, ngjyrat
rrethuese dhe ndriçimi i ambientit përreth. Në mënyrë që të bëhet përshkrimi më objektiv i specifikimit
të ngjyrave do të përdoret pjesa e fizikës që quhet kolorimetri. Nocionet themelore në kolorimetri janë
gjatësia valore dominante, ngacmimi dhe ndriçimi ( luminance).
Gjatësia valore dominante është gjatësia valore e ngjyrës që shihet kur e shikojmë dritën dhe
korrespondon me ngjyrimin (hue). Ngacmimi (excitation purity) korrespondon me ngopjen e ngjyrës,
ndërsa luminanca korrespondon me sasinë apo intensitetin e dritës. Ngacmimi i dritës me ngjyrë është
raporti i ngjyrës së pastër me gjatësi valore dominante ndaj ngjyrës së bardhë që nevojitet për t’a
definuar një ngjyrë. Ngjyra komplet e pastër është 100% e ngopur dhe nuk përmban dritë të bardhë,
ndërsa te përzierjet e ngjyrës së pastër dhe dritës së bardhë ngopja ka vlera ndërmjet 0 dhe 100 %. Drita
e bardhë dhe nuancat e hirta janë të ngopura 0%, prandaj nuk kanë gjatësi valore dominante.
Korrespondenca ndërmjet termave të perceptimit dhe kolorimetrisë janë si vijon:
Termat e përceptuar Termat e kolorimetrisë
Ngjyrimi (hue)
Ngopja (saturation)
Ndriçimi (lightness)
Shkëlqimi (brightness)
Gjatësia valore dominante
Ngacmimi
Luminanca
Lumininca
Grafika kompjuterike
-22-
Drita është energji elektromagnetike spektri i së cilës ka gjatësi valore prej 400-700 nm dhe e cila
perceptohet si ngjyrat prej vjollce, e kaltër, e gjelbër, dhe në fund e kuqe. Sasia e e energjisë për çdo
gjatësi valore paraqitet me distribuimin e energjisë spektrale P(λ), e siç tregohet në figurën 18.
Figura 18. Shpërndarja tipike e energjisë spektrale të dritës – P(λ)
Distribuimi paraqitet me vlera numerike të pafundme, nga një për secilën gjatësi valore në
spektrin e dritës së dukshme. Fatmirësisht, ne mund të përshkruajmë efektin visual të secilit distribuim
spektral në mënyrë më precize me treshen: gjatësia valore dominante, ngacmimi, luminanca. Prej kësaj
rrjedh se shumë distribuime spektrale të energjisë krijojnë të njejtën ngjyrë. Pra relacioni në mes të
distribuimit spektral dhe ngjyrave është relacion shumë-me-një.
Figura 19. Funksionet e përgjigjes spektrale për 3 sensorët e retinës
Teoria e tre-stimuluesve të perceptimit të ngjyrës supozon se retina e syrit ka tre sensorë, me
sensitivitetin maksimal në dritën e kuqe, të gjelbër dhe të kaltër. Eksperimentet e bazuara nga kjo
hipotezë do të krijojnë funksionet me përgjigje spektrale sipas figurës 19. Maksimumi i ngjyrës së
Grafika kompjuterike
-23-
kaltër është 440 nm, për ngjyrën e gjelbër është 545 nm, ndërsa për ngjyrën e kuqe është 580 nm. Sipas
kësaj lakoreje mund të konkludojmë se syri është më pak i ndieshëm në ngjyrën e kaltër se për ngjyrat e
kuqe dhe të gjelbër.
Figura 10. Funksioni i efikasitetit të ndritshmërisë për syrin e njeriut
Figura 20 tregon funksionin e efikasitetit të ndriçimit, ose përgjigjen e syrit në dritën me ndriçim
konstant me ndryshimin e gjatësisë valore. Këtu shihet se sensiviteti maksimal është arritur për dritën
me ngjyrë të verdhë-të gjelbër apo me gjatësi valore rreth 550 nm. Është evidente se kjo lakore është
fituar duke i mbledhur lakoret e figurës 19.
Teoria e tre-stimuluesve është atraktive sepse prej kësaj lirisht mund të konkludohet se ngjyrat
mund të paraqiten me koeficientë pozitivë të shumës së ngjyrave të kuqe, gjelbër dhe të kaltër (këto tri
ngjyra quhet ngjyra primare). Ky supozim është gati plotësisht i saktë: 3 funksionet e ngjyrës në figurën
21 tregojnë sasinë e dritës së kuqe, gjelbër dhe të kaltër që nevojitet nga vrojtuesi në mënyrë që të
përshtatë një ngjyrë me ndriçim konstant për të gjitha vlerat e gjatësisë valore dominante në spektrin e
dritës së dukshme.
Figura 21. Funksionet e përshtatjes së ngjyrave duke treguar sasinë e tri ngjyrave primare që
nevojiten në mënyrë që të përshtatë të gjitha gjatësitë valore të spektrit të dukshëm.
Grafika kompjuterike
-24-
Vlera negative në figurën 21 do të thotë se ngjyra nuk mund të përshtatet duke i mbledhur ngjyrat
primare. Mirëpo nëse njëra nga ngjyrat primare i shtohet mostrës së ngjyrës, mostra e ngjyrës mund të
përshtatet duke i përzier dy ngjyrat tjera primare. Kjo do të thotë se disa nga ngjyrat nuk mund të
paraqiten nga përziersit RGB (red, green, blue) dhe nuk mund të paraqiten në gypin katodik.
Syri i njeriut mund të dallojë qindra mijëra ngjyra të ndryshme në hapësirën e ngjyrave. Kur
ngjyrat dallohen vetëm për nga ngjyrimi (hue) diferenca në gjatësinë valore ndërmjet ngjyrave mund të
jetë më shumë se 10 nm ashtu që ngjyrat të dallohen, por ka raste kur kjo diferencë është më e vogël se
2 nm. Mirëpo te shumica e ngjyrave diferenca në ngjyrim është 4 nm ashtu që ngjyrat të dallohen.
Syri është më pak sensitiv në ndryshimet e ngjyrimit në dritën pak të ngopur, ndërsa sensitiviteti
në ngopje kur ngjyrimi dhe ndriçimi është konstant është më i madh në vlerat ekstreme të spektrit të
dukshëm.
DIAGRAMI KROMATIK I CIE-së
Përshtatja dhe definimi i ngjyrave me përzierjen e 3 ngjyrave primare është qasje mjaft e mirë për
të definuar një ngjyrë, mirëpo nevoja për koeficientë negativë nuk është qasje e përshtatshme. Në vitin
1931 komiteti (CIE) ka definuar 3 standarde primare të quajtura X, Y, dhe Z në mënyrë që të
zëvendësohen ngjyrat e kuqe, gjelbër dhe e kaltër për përshtatje të ngjyrave. Tri funksione
korresponduese për përshtatje të ngjyrave x , y , z janë treguar në figurën 22 dhe këto janë
funksione ndihmëse për të llogaritur se në çfarë sasie duhet përzier X, Y dhe Z për të gjeneruar
distribuimin spektral të cilësdo ngjyrë të dukshme. Vlera primare Y është definuar ashtuqë të ketë
funksion për përshtatje të ngjyrës y e kjo saktësisht e përshtatë funksionin e efikasitetit të luminancës
të figurës 20.
Grafika kompjuterike
-25-
Figura 11. Funksionet e përshtatjes x , y , z për ngjyrat primare X, Y, Z.
Vlera e primarëve X, Y, Z që nevojitet për të përshtatë një ngjyrë me distribuim spektral të
energjisë P(λ) llogaritet:
dxPkX )( ; dyPkY )( ; dzPkZ )( …. (4)
Për objekte vetëndriçuese sikurse gypi katodik, vlera e k-së është 680 lumen/Wat. Për objekte që
reflektohen, vlera e k-së selektohet ashtu që drita e bardhë ka vlerën Y = 100, ndërsa vlerat tjera të Y
janë në rangun prej 0 deri në 100.
Figura 12. Koni i ngjyrave të dukshme në hapësirën CIE të ngjyrave, që paraqitet me vijat që
përhapen prej qendrës. Këtu është paraqitur rrafshi X + Y + Z = 1.
Grafika kompjuterike
-26-
Figura 23 e tregon vëllimin në formë të konit të hapësirës XYZ që përmban ngjyrat e dukshme.
Ky vëllim zgjerohet prej origjinës në oktant pozitiv.
Le të jenë (X, Y, Z) koeficientët që përdoren në primarët e CIE-së për të përshtatur një ngjyrë
sipas barazimit (4). E definojmë kromaticitetin duke i normalizuar ndaj madhësisë (X + Y + Z), që
mund të paramendohet si energjia totale e dritës:
ZYX
Xx
;
ZYX
Yy
;
ZYX
Zz
……………..…(5)
Këtu mund të shihet se x + y + z = 1. Pra x, y dhe z janë në rrafshin (X + Y + Z) të figurës 23.
Nëse e dimë vlerën për x dhe y, vlera e z-it mund të gjindet nga z = 1 – x – y. Mirëpo vlerat X, Y dhe Z
nuk mund të caktohen nga x dhe y. Që të caktojmë njërën nga këto vlera, na duhet edhe një informatë
tjetër, psh. Y që përmban informatën për luminancë. Nëse janë të dhëna (x, y, Y) mund të gjendet vlera
e koeficientëve (X,Y, Z)
X = x * Y / y; Y = Y; Z = (1 – x – y) * Y / y.…………………....(6)
Figura 13. Diagrami kromatik i CIE. Gjatësitë valore janë në nanometra. Pika në mes paraqet
ndriçuesin C
Vlerat për kromacitet varen vetëm nga gjatësia valore dominante dhe ngopja dhe janë të pavaruar
nga energjia e ndriçimit. Duke e vizatuar x dhe y për të gjitha ngjyrat e dukshme, fitohet diagrami i
Grafika kompjuterike
-27-
figurës 24 i cili është projeksioni i rrafshit (X, Y) në rrafshin (X + Y + Z = 1) të figurës 23. Pjesa e
brendshme dhe kufiri i regjionit të figurës 24 paraqet të gjitha ngjyrat kromatike të dukshme. Ngjyrat
100% të pastra të spektrit janë në pjesën e lakuar të kufirit. Ngjyra standarde e bardhë, është e definuar
me ndriçuesin C, dhe në figuren 24 është e shënuar me një pikë të zezë në mes.
Figura 14. Ngjyrat në diagramin kromatik. Gjatësia valore dominante e ngjyrës A është gjatësia
valore e ngjyrës B. Ngjyrat D dhe E janë ngjyra komplementare
Diagrami kromatik i CIE-së është i dobishëm për disa arsye. Psh. këtu lejohet të bëhet matja e
gjatësisë valore dominante dhe ngacmimit të çfarëdo ngjyre duke e përshtatur një ngjyrë me
koeficientët primarë të CIE-së. Të supozojmë se ngjyra e përshtatur është në pikën A të figurës 25. Kur
bëhet mbledhja e 2 ngjyrave, atëherë ngjyra e re gjendet në vijën e drejtë të diagramit kromatik që i
lidhë dy ngjyrat që janë mbledhur. Për këtë shkak ngjyra A mund të mendohet si përzierje e ngjyrës së
bardhë (ndriçuesi C) dhe ngjyrës së pastër spektrale në pozitën B. Për këtë pozita B e definon gjatësinë
valore dominante. Raporti në mes të gjatësisë AC dhe gjatësisë BC në përqindje e definon ngacmimin e
A-së. Sa më afër pika A është pikës C, ngjyra e A-së do të përfshjë më shumë ngjyrë të bardhë dhe do
të jetë më pak e pastër.
Grafika kompjuterike
-28-
Figura 15. Përzierja e ngjyrave. Të gjitha ngjyrat mund të krijohen në linjën IJ duke i përzier ngjyrat I
dhe J. Poashtu të gjitha ngjyrat në trekëndëshin IJK mund të krijohen duke i përzier ngjyrat I, J, K
Ngjyrat komplementare janë ato të cilat nëse përzihen ndërmjet veti do të formojnë ngjyrën e
bardhë (në figura 25 pikat D dhe E). Disa ngjyra (si psh. F në figurës 25) nuk mund të definohen me
gjatësi valore dominante dhe për këtë arsye quhen ngjyra jospektrale. Në këtë rast gjatësia valore
dominante do të jetë kompliment i gjatësisë valore që paraqitet me prerjen e linjës që kalon nëpër F dhe
C dhe lakores në pikën B. Ngacmimi është i definuar në këtë rast si raport i gjatësive (këtu CF me CG).
Ngjyrat të cilat paraqiten me gjatësi valore dominante komplimentare janë ngjyra vjollcë dhe magenta:
këto paraqiten në pjesën e poshtme të diagramit CIE.
Diagrami CIE përdoret edhe për definimin e rangut të ngjyrave ( color gamut) që tregon efektin e
mbledhjes së ngjyrave. Nëse nga figura 26 ngjyrat I dhe J mblidhen atëherë krijohet ngjyra tjetër dhe
ngjyra e krijuar do të varet nga vlerat relative të këtyre dy ngjyrave. Ngjyra e tretë K mund të
shfrytëzohet poashtu me përzierje të ndryshme të ngjyrave I dhe J që të krijojë rangun e ngjyrave në
trekëndëshin IJK, e kjo bëhet duke i ndërruar sasitë relative të këtyre ngjyrave. Nga forma e diagramit
shihet se ngjyrat e kuqe, e gjelbër, dhe e kaltër nuk mund të përzihen me anë të mbledhjes në mënyrë që
të përshtaten të gjitha ngjyrat.
MODELET E NGJYRAVE PËR GRAFIKËN RASTERIKE
Modeli i ngjyrave është një specifikim i sistemit koordinativ tredimensional dhe një nënbashkësi
vizuele në sistemin e koordinatave brenda të cilit shtrihen të gjitha ngjyrat e rangut të veçantë të
Grafika kompjuterike
-29-
ngjyrave. Psh. modeli i ngjyrave RGB është kubi njësi i nënbashkësisë së sistemit koordinativ
tredimensional kartezian.
Qëllimi i modelit të ngjyrave është që të lejohet specifikimi i ngjyrave brenda rangut të disa
ngjyrave. Tri modele hardverike të ngjyrave janë RGB (red, green, blue ose e kuqe, e gjelbër, e kaltër) e
cila përdoret në ekrane me gyp katodik; YIQ që përdoret nga sistemi transmetues televiziv dhe CMY
(cyan, magenta, yellow) e cila përdoret për paisjet printuese. Mirëpo asnjëri prej këtyre modeleve nuk
është i lehtë për t’u shfrytëzuar, sepse ato nuk lidhen direkt me nocionet intuitive të ngjyrave si:
ngjyrimi, ngopja dhe ndritshmëria (hue, saturation, brightness).
MODELI RGB I NGJYRAVE
Modeli RGB i ngjyrave shfrytëzohet në monitorët me gypa katodikë si dhe në grafikën rasterike
dhe e përdorë sistemin koordinativ kartezian. Ngjyrat RGB janë ngjyra primare aditive (mbledhëse), pra
një ngjyrë e caktuar fitohet me mbledhjen e këtyre ngjyrave primare. Figura 27 e tregon kubin njësi i
cili njihet si kubi RGB. Ngjyra e zezë paraqitet me koordinatën (0, 0, 0), ndërsa ngjyra e bardhë është
koordinata (1, 1, 1). Nuancat e ngjyrës së hirtë kanë sasi të njejtë të ngjyrës së kuqe, të gjelbër dhe të
kaltër. Në figurën 27 nuansat e ngjyrës së hirtë janë paraqitur në diagonalen kryesore të kubit dhe janë
të shënuara me vijë me pika të ndërprera.
Rangu i ngjyrave të modelit RGB është i definuar me kromaticitetin e pjesës fosforike të gypit
katodik. Dy gypa katodikë me fosforë të ndryshëm do të përfshijnë rang të ndryshëm të ngjyrave.
Figura 16. Kubi RGB
Grafika kompjuterike
-30-
MODELI CMY I NGJYRAVE
Ngjyrat cian, magenta dhe e verdha janë komplementet e ngjyrave të kuqe, të gjelbër, dhe të
kaltër respektivisht. Nëse përdoren si filtër për të zbritur ngjyrën nga ngjyra e bardhë, ato quhen ngjyra
zbritëse (subtraktive). Modeli CMY është i njejtë si modeli RGB, pra edhe ky shfrytëzon sistemin
kartezian koordinativ, mirëpo ngjyra e bardhë është në origjinën e kubit. Ngjyra e caktuar specifikohet
nga zbritja e ngjyrës së bardhë me ndonjë ngjyrë tjetër.
Figura 17. Ngjyrat primare zbritëse (cian, magenta, e verdha) dhe përzierjet e tyre
Ky model përdoret te ploterët ink-jet dhe ploterët elektrostatikë. Kur një sipërfaqe mbulohet me
ngjyrën cian, drita e kuqe nuk mund të reflektohet nga kjo sipërfaqe. Ngjyra cian e zbret ngjyrën e
bardhë nga ngjyra e kuqe, ku ngjyra e bardhë është shumë e ngjyrave të kuqe, gjelbër dhe të kaltër. Pra
nëse i krahasojmë me ngjyrat primare mbledhëse ngjyra cian është e bardhë minus e kuqe, apo ngjyra e
kaltër e mbledhur me të gjelbërtën. Poashtu magenta absorbon ngjyrën e gjelbërt, ashtu që kjo mund të
shprehet si e kuqe e mbledhur me të kaltër. Ngjyra e verdhë absorbon ngjyrën e kaltër pra është e kuqja
plus e gjelbërta. Nëse sipërfaqja është e mbuluar me ngjyrat cian dhe të verdhë ngjyra e kuqe dhe e
kaltër do të absorbohen, dhe në këtë rast ngjyra e gjelbër mund të reflektohet nga ngjyra e bardhë. Nëse
sipërfaqja është e mbuluar me cian, të verdhë dhe magenta, atëherë ngjyra e kuqe, e gjelbër dhe e kaltër
do të absorbohen, kështu që do të kemi ngjyrë të zezë. Kjo mund të shihet nga figura 28, si dhe nga këto
relacione:
B
G
R
Y
M
C
1
1
1
………….….(7)
Shndërrimi i ngjyrave të modelit RGB në modelin CMY bëhet përmes këtyre formulave:
Grafika kompjuterike
-31-
Y
M
C
B
G
R
1
1
1
……………… (8)
Një model tjetër që përdoret është modeli CMYK dhe ky model e përdor ngjyrën e katërt (K,
ngjyra e zezë). Modeli CMYK përdoret zakonisht në procesin e printimit. Nëse e kemi modelin CMY,
atëherë shndërrimi i ngjyrave të modelit CMY në CMYK bëhet me këto barazi:
K = min(C,M,Y)
C = C – K
M = M – K
Y = Y – K………………………………………………………….. (9)
Modeli YIQ i ngjyrave
Ky model përdoret nga sistemi transmetues televiziv në SHBA dhe është i lidhur me grafikën
rasterike. Ky model është një rikodim i modelit RGB për transmetim efikas dhe për kompatibilitet me
televizorin bardh e zi. Sinjali i rikoduar do të transmetohet me standardin NTSC.
Komponenta Y e modelit YIQ është luminanca: Luminanca është e definuar të jetë e njejtë me
primarin Y të sistemin CIE. Në televizorin bardh e zi vetëm komponenta Y do të paraqitet.
Kromaticiteti do të kodohet nga komponentet I dhe Q. Ky model shfrytëzon sistemin kartezian
koordinativ ashtu që nënbashësia e dukshme është një shumëfaqësh konveks që projektohet në kubin
RGB.
Transformimi nga modeli RGB në YIQ bëhet si vijon:
B
G
R
Q
I
Y
311.0528.0212.0
321.0275.0596.0
114.0587.0299.0
…………………….(10)
Grafika kompjuterike
-32-
Vlerat e rreshtit të parë të kësaj matrice tregojnë për rëndësinë e komponentës së gjelbër dhe të
kuqe, ndëra rreshti i tretë i matricës tregon se sa e parëndësishme është komponenta e kaltër. Kalimi
nga sistemi RGB në YIQ bëhet përmes matricës inverse.
Specifikimi i ngjyrave me modelin YIQ e zgjidhë një problem të trasmetimit të televizionit: dy
ngjyra të ndryshme që paraqiten në televizorin me ngjyra do të duken ndryshe, mirëpo në monitorët
bardh e zi mund të duken të njejta. Ky problem mund të eleminohet duke i specifikuar vlera të
ndryshme të komponentes Y për dy ngjyra.
Modeli YIQ i shfrytëzon mjaft mirë dy veti të sistemit vizual. E para është se syri është më i
ndieshëm në ndërrimet në ndrqim në krahasim me ndryshimet në ngjyrim (hue) apo në ngopje. Apo me
fjalë tjera syri bën diskriminimin hapësinor të informacioneve bardh e zi më shumë se sa diskriminimin
hapësinor të informacioneve me ngjyra. Kjo sugjeron se më shumë bita të brezit frekuencor duhet të
përdoren për paraqitje të komponentës Y se sa të komponenteve I dhe Q, në mënyrë që të sigurohet
rezolucion më i lartë. E dyta është se objektet që mbulojnë një pjesë të vogël të imazhit do të krijojnë
një sensacion të vogël vizuel, që mundëson që të bëhet specifikim i vetëm një dimensioni të ngjyrës.
Kjo sugjeron që komponenta I ose Q të ketë brez frekuencor më të vogël se pjesa tjetër. Kështu kodimi
NTSC i YIQ-së në sinjal transmetues i shfrytëzon këto informata që të ketë efekt maksimal të sasisë së
informatave në brez frekuencor të fiksuar: 4 MHz i ndahet komponentës Y, 1.5 MHz i ndahet
komponentës I, ndërsa 0.6 Mhz i ndahet komponentës Q.
Modeli HSV i ngjyrave
Modelet RGB, CMY dhe YIQ janë modele harduerike. Modeli HSV është model i orientuar nga
shfrytëzuesi dhe është i bazuar në modelin e artistit të spjeguar më parë që përmban komponenet e
nuancës, hijës dhe tonit (tint, shade, tone). Sistemi koordinativ është cilindrik dhe nënbashkësia e
hapësirës brenda të cilit modeli është i definuar është kon ose piramidë gjashtëfaqësore sipas figurës 29.
Maja e konit korrespondon me V = 1, që përmban ngjyrat e ndritshme. Mirëpo ngjyrat e rrafshit V = 1
nuk përmbajnë të njejtin shkëlqim të perceptuar.
Grafika kompjuterike
-33-
Figura 18. Modeli HSV. Rrafshi V = 1 përmban rrafshet R = 1, G = 1 dhe B = 1 të modelit RGB
Ngjyrimi (hue) matet me këndin rreth boshtit vertikal ashtu që ngjyra e kuqe ka këndin 00, ngjyra
e gjelbër ka këndin 1200 e kështu me rradhë. Ngjyrat komplementare në sistemin HSV ndërmjet veti
janë në kënd prej 1800. Vlera e S-së është një raport i cili mund të jetë prej 0 në qendër të linjës (boshti
V) deri në 1 në pjesët e trekëndëshit të konit.
Koni është 1 njësi i lartë në V, me majën më të lartë në origjinën e sistemit koordinativ. Pika e
majës së konit është e zezë dhe koordinata V është 0 në këtë rast. Në këtë rast vlerat e H-së dhe S-së
nuk janë të rëndësishme. Pika S = 0, V = 1 është e bardhë. Vlerat e ndërmjetme të V-së për të cilat S = 0
(pra në linjën qendrore) janë nuancat e ngjyrës së hirtë. Kur S = 0, vlera e H-së është e parëndësishme.
Kur vlera e S-së nuk është zero, vlera e H është e rëndësishme. Psh. ngjyra e kuqe e pastër fitohet për
pikat H = 0, S = 1, V = 1. Shtimi i pigmentit të bardhë korrespondon me zvoglimin e S (pa e ndryshuar
komponentën V). Krijimi i hijeve bëhet nëse e mbajmë komponentën S = 1 dhe duke e zvogluar
komponentën V. Tonet krijohen me zvoglimin e komponenteve S dhe V. Natyrisht ndërrimi i
komponentës H korrespondon me selektimin e pigmentit të pastër prej të cilit duhet të fillohet.
Grafika kompjuterike
-34-
PROGRAMIMI I OBJEKTEVE PRIMITIVE
Njëra ndër gjuhët më të rëndësishme të platformës .NET është gjuha programuese C# (C Sharp).
Gjuha C# e ka fuqinë dhe shpejtësinë e gjuhës C++ dhe C. Poashtu me këtë gjuhë mund të zhvillohen
aplikacione mjaft shpejt dhe ate me pak kod të shkruar, ngjashëm si në gjuhën Visual Basic e ky
koncept quhet RAD (Rapid Application Development). Ne këtu nuk do të ndalemi në përshkrimin e
kësaj gjuhe, por në esencë se si i krijon kjo gjuhë objektet primitive si p.sh. vijat, drejtëkëndëshat,
elipsat, shumëkëndëshat, lakoret, objektet e mbyllura, etj. Objektet primitve mund të zhvillohen edhe në
gjuhën C++ si dhe në gjuhët tjera programuese, mirëpo qasja në C++ është më e komplikuar.
GDI+ (Graphics Device Interface) është koleksion i klasave që mundëson krijimin e objekteve
grafike, teksteve dhe imazheve. Njëra nga karakteristikat kryesore të saj është se një operacion grafik
është i pavarur nga operacioni i mëparshëm dhe nuk mund të ketë efekt në operacionin e ardhshëm.
Nëse dëshirojmë t’a vizatojmë një vijë (linjë), atëherë duhet të specifikojmë një objekt të tipit Pen (laps)
dhe dy pika të linjës. Për linjën tjetër që duhet vizatuar duhet bërë e njejta gjë. Këtu nuk mund të
supozohet se linja e dytë do t’a ketë të njejtin laps dhe të njejtat pika si linja paraprake.
Klasat e GDI+ gjenden në këto namespace: System.Drawing, System.Drawing2D,
System.Drawing.Imaging dhe System.Drawing.Text.
Para se të fillojmë vizatimin duhet të selektohet sipërfaqja në të cilën vizatohet, lloji (tipi) i
formës që duhet të vizatohet si dhe instrumenti që shfrytëzohet për vizatim. Sipërfaqja në të cilën
vizatohet është një objekt i tipit Graphics. Ky objekt përmban shumë metoda për vizatimin e formave
primitive dhe formave më të avancuara.
Hapi tjetër është mjeti me të cilën duhet vizatuar. Ekzistojnë dy mjete për vizatim: objekti i tipit
Pen (lapsi) dhe objekti i tipit Brush (brusha). Objekti i tipit Pen shfrytëzohet për vizatimin e objekteve
të hapura, p.sh. linjat, drejtëkëndëshat, elipsat, etj, ndërsa objekti i tipit Brush shfrytëzohet për
mbushjen e formave (format që kanë konturë të mbyllur). Karakteristika kryesore e objektit Pen është
ngjyra dhe trashësia, ndërsa karakteristika kryesore e objektit Brush është ngjyra apo mostra me të cilën
duhet të mbushet objekti i mbyllur.
Grafika kompjuterike
-35-
Le të marrim një shembull. Nëse dëshirojmë t’a vizatojmë një vijë të drejtë me ngjyrë të kuqe,
me trashësi 2 piksela, atëherë kodi i shkurtër në gjuhën C# do të ishte:
Pen lapsi = new Pen(Color.Red, 2);
Point pika1 = new Point(10, 10);
Point pika2 = new Point(120, 180);
this.CreateGraphics().DrawLine(lapsi, pika1, pika2);
Këtu pra krijohet një referencë e objektit të tipit Pen, q` n` shembullin ton` e kemi em`rtuar si
objekt me emrin lapsi. Parametri i parë i këtij objekti është i tipit Color dhe e kemi definuar të jetë
ngjyra e kuqe (Color.Red). Parametri i dytë ka të bëjë me trashësinë e lapsit dhe e kemi definuar q` të
jetë 2 piksela.
Poashtu i kemi krijuar edhe dy referenca të objektit Point (pra dy pika) që i kemi emërtuar pika1
dhe pika2, me koordinata (10, 10) dhe (120, 180) respektivisht. Koordinatat janë të paraqitura në
piksela ndërsa origjina e sistemit koordinativ është skaji i epërm i majtë. Hapi tjetër thërret metodën
DrawLine që vizaton linjën. Së pari thirret forma (që është e shënuar me objektin this), e cila e krijon
objektin Graphics (pra this.CreateGraphics( )). Objekti që është krijuar në stak do t’a thërret metodën
DrawLine që e vizaton linjën. Metoda DrawLine si argumente i merr objektin Pen dhe pikën startuese
dhe përfunduese të linjës.
Të gjitha koordinatat janë të paraqitura në pikselë. Është e mundshme edhe paraqitja e
koordinatave edhe në njësi tjera dhe në këtë rast GDI+ është përgjegjëse për konvertimin e
koordinatave.
Objekti GRAPHICS
Objekti Graphics është sipërfaqja në të cilën vizatohet. Objekti Graphics i paraqet të gjitha
metodat për vizatim në sipërfaqe të kontrollës. P.sh. objekti PictureBox (kontrollë për vizatim të
imazheve në C#) tregon veti të objektit Graphics, por poashtu edhe kontrolla TextBox (kontrollë për
shkrim të tekstit në C#). Në mënyrë që të krijojmë objektin Graphics të një kontrolle, duhet të thirret
metoda CreateGraphics e cila metodë e kthen një objekt të tipit Graphics.
Së pari duhet deklaruar një variabël të tipit Graphics. Pastaj në kontrollën në të cilën dëshirojmë
të vizatojmë e thërrasim metodën CreateGraphics. Kjo metodë kthen një objekt të tipit Graphics e cila
do t’i ndahet variablës së definuar në fillim. Nëse kontrolla është PictureBox dhe është e emëruar me
pictureBox1, atëherë së pari e krijojmë një objekt të tipit Graphics që e emërojmë me g. Kontrolla
Grafika kompjuterike
-36-
pictureBox1 e thërret metodën CreateGraphics e cila kthen një objekt të tipit Graphics që do t’i ndahet
variablës g të krijuar më parë. Kjo mund të vërehet më mirë në vazhdim me këtë pjesë të kodit:
Graphics g;
g = pictureBox1.CreateGraphics();
Nëse dëshirohet të vizatohet në formë, athëherë kodi në C# për këtë do të ishte:
Graphics g;
g = this.CreateGraphics();
Vetitë (Property) më të rëndësishme të objektit Graphics janë:
DpiX, DpiY. Rezolucioni horizontal dhe vertikal, e shprehur në piksela/inç.
PageUnit. Njësitë në të cilën dëshirohet të shprehen koordinatat në objektin Graphics. Kjo
mund të ketë vlerat Display (njësia është 1/75 e inçit), Document (njësia është 1/300 e inçit), Inch
(njësia është një inç), Millimeter (njësia është 1 milimetër), Pixel (njësia është 1 piksel), Point (njësia
është 1/72 e inçit), World (njësitë specifikohen nga shfrytëzuesi).
TextRenderingHint. Kjo veti specifikon se si do të bëhet shprehja e tekstit në ekran. Kjo
mund të ketë këto vlera: AntiAlias, AnitAliasGridFit, ClearTypeGridFit, SingleBitPerPixel,
SingleBitPerPixelGridFit dhe SystemDefault
SmoothingMode. Është e ngjashme me vetinë TextRenderingHint, por kjo aplikohet për të
gjitha format. Kjo mund të ketë vlerat AntiAlias, Default, HighQuality, HighSpeed, Invalid dhe None.
Objekti POINT
Objekti Point e paraqet një pikë në sipërfaqen që vizatohet dhe shprehet me koordinata (x, y), ku
x është distanca horizontale nga origjina, ndërsa y është distanca vertikale nga origjina. Origjina është
në pikën me koordinatat (0, 0) dhe kjo është në pjesën e epërme të majtë të objektit që vizatohet. Figura
30 tregon koordinatat e dy skajeve të kundërta.
Grafika kompjuterike
-37-
Figura 30. Paraqitja e koordiantave në objektet në të cilat vizatohet
Që të krijojmë një objekt të tipit Point, duhet specifikuar koordinatat x dhe y, të shprehura si veti
( property) të objektit. Deklarimi dhe inicializimi i një variable të tipit Point bëhet në këtë mënyrë:
Point P;
P1.X = 34;
P2.Y = 50;
Koordinatat mund të paraqiten edhe si numra me pikë të lëvizshme (në C# këta numra quhen
float dhe kanë 4 bajta). Në këtë rast përdoret objekti PointF.
Objekti RECTANGLE
Objekti që përdoret shpesh kur duhet të vizatojmë është objekti Rectangle. Nëse dëshirojmë t’a
deklarojmë dhe inicializojmë një objekt të tipit Rectangle, atëherë kodi në C# do të jetë:
int x = 11, y = 11;
int gjeresia = 100, lartesia = 20;
Rectangle rect = new Rectangle(x, y, gjeresia, lartesia);
Në fillim i kemi inicializuar 4 variabla të tipit integjer (x = 11, y = 11, gjeresia = 100, lartesia =
20). Pastaj duke i shfrytëzuar këto variabla, e kemi krijuar një variabël të tipit Rectangle që e kemi
emëruar rect. Në këtë rast variablat x dhe y paraqesin koordinatat prej ku fillon drejtkëndëshi, ndërsa
gjeresia dhe lartesia paraqesin gjerësine dhe lartësinë e drejtkëndëshit.
Objekti COLOR
Objekti Color e paraqet një ngjyrë të caktuar. Në gjuhën C# ekzistojnë shumë mënyra për
paraqitjen e ngjyrës. Ngjyrat e objektit Color mund të paraqiten përmes emrave në gjuhën angleze. P.sh.
Grafika kompjuterike
-38-
nëse dëshirojmë të krijojmë një variabël të tipit Color dhe t’a inicilizojmë me ngjyrën e kaltër, atëherë
kodi në C# për këtë do të ishte:
Color ngjyra = new Color();
ngjyra = Color.Blue;
Pra këtu objekti i tipit Color do të përmbajë ngjyrën e kaltër ( blue). Mund të përdoren 128
emërtime të ndryshme për ngjyra, emërtime të cilat janë në gjuhën angleze. P.sh. nëse duhet që t’a
definojmë ngjyrën e zezë, atëherë në vend të shprehjes Color.Blue duhet të shkruhet Color.Black.
Përveq kësaj metode ngjyra mund të krijohet edhe me metodën FromARGB, që e krijon një ngjyrë nga
komponentet primare të ngjyrave (e kuqe, e gjelbër, e kaltër). Në këtët rast në vend të rreshtit
ngjyra = Color.Blue;
do të kemi rreshtin
ngjyra = Color.FromArgb(red, green, blue);
ku parametri i parë paraqet intensitetin e komponentës së kuqe, parametri i dytë ngjyrën e gjelbër
dhe parametri i tretë intensitetin e ngjyrës së kaltër.
Objekti Color përdoret për të vendosur ngjyrën në objektin e tipit Pen që do të diskutohet më
vonë.
Objekti FONT
Ky objekt përdoret kur dëshirojmë të vizatojmë një objekt të tipit string dhe kjo zakonisht bëhet
me metodën DrawString. Për të specifikuar një font, së pari duhet krijuar një objekt të tipit Font ku
duhet specifikuar familjen e fontit, madhësinë, stilin, etj. Objekti Font do të përdoret si një nga
parametrat e metodës DrawString për vizatim të tekstit. Konstruktori i këtij objekti ka 13 forma të
ndryshme. Format më të thjeshta të objektit Font janë:
Font drawFont = new Font(name, size);
Font drawFont = new Font(name, size, style);
ku size paraqet madhësinë e fontit, style përmban stilin e fontit (Bold,-fonti i trashë, Italic-fonti
italic, StrikeOut-fonti me vijë në mes të shkronjës, Underline- fonti i nënvizuar), ndërsa name paraqet
familjen e fontit. Psh. nëse dëshirojmë të krijojmë një font të familjes Roman, me madhësi 12 piksela,
atëherë kodi në C# do të ishte:
Font f = new Font("Roman", 12);
Grafika kompjuterike
-39-
Objekti PEN
Objetki Pen paraqet një laps virtual me të cilin do të vizatohet në sipërfaqen e objektit Graphics.
Për të konstruktuar një objekt të tipit Pen, duhet të specifikohet ngjyra dhe gjerësia e lapsit në piksela.
Psh. nëse dëshirojmë t’i konstruktojmë 3 objekte të tipit Pen me gjerësi respektivisht 1, 3, 5 si dhe me
ngjyra të kuqe, gjelbër dhe kaltër respektivisht, atëherë kodi në C# do të jetë:
Pen Lapsi1, Lapsi2, Lapsi3;
Lapsi1 = new Pen(Color.Reg, 1);
Lapsi2 = new Pen(Color.Green, 3);
Lapsi3 = new Pen(Color.Blue, 5);
Nëse parametri i dytë nuk specifikohet, gjerësia e lapsit do të jetë 1 piksel. Konstruktori tjetër i
objektit Pen lejon që të bëhet specifikimi i një brushe, në vend të ngjyrës:
Pen Lapsi;
Lapsi = New Pen(brusha, gjeresia);
ku brusha është një objekt i tipit Brush. Siç shihet metodat e vizatimit bëjnë të mundshme
gjenerimin e dy tipeve të vizatimeve: konturave të objekteve si dhe formave të mbushura. Konturat e
objekteve vizatohen me laps, ndërsa format e mbushura vizatohen me brushë.
Objekti Pen ka këto veti ( property):
LineJoin; Përcakton se si bëhet bashkimi i dy linjave të ndryshme
DashStyle; Përcakton stilin e vijave që vizatohen me objektin Pen. Mund të ketë këto vlera
(Solid, Dash, DashDot, DashDotDot, Dot, Custom) të cilat mund të jenë vija e plotë, vija e ndërprerë,
vija e ndërprerë me pika, etj
PenType; Përcakton stilin e objektit Pen dhe mund të ketë këto vlera: HatchFilled,
LinearGradient, PathGradient, SolidColor dhe TextureFill
Objekti GRAPHICSPATH
Objekti GraphicsPath (path-rrugë, shteg) është kombinim i disa objekteve primitive për vizatim
të figurave si linjat, drejtëkëndëshat dhe lakoret. Mund të krijohen disa objekte primitive të ndryshme
dhe një kombinim i objekteve primitive i cili quhet GraphicsPath. Objekti GraphicsPath zakonisht është
i mbyllur dhe i mbushur me ndonjë ngjyrë apo kombinim ngjyrash. Metoda më e thjeshtë është të
Grafika kompjuterike
-40-
krijohet një objekt i tipit GraphicsPath dhe pastaj thirret njëra nga metodat për të shtuar një element në
rrugë (shteg). Këto metoda mund të jenë:
AddArc AddEllipse AddPolygon
AddBezier AddLine AddRectangle
AddCurve AddPie AddString
P.sh. nëse dëshirojmë që të krijojmë një shteg të ri që përbëhet prej një vije të drejtë dhe një
drejtëkëndëshi, kodi në C# do të dukej kështu:
Graphics g;
g = this.CreateGraphics();
Pen pen = new Pen(Color.Blue, 2);
Rectangle rect = new Rectangle(4, 4, 100, 100);
GraphicsPath path = new GraphicsPath();
path.AddLine(1, 1, 30, 30);
path.AddRectangle(rect);
g.DrawPath(pen, path);
Para krijimit të objekteve Graphics, Pen dhe Rectangle, e kemi krijuar një referencë të tipit
GraphicsPath e cila paraqet shtegun. Në shteg e kemi shtuar së pari një linjë, e pastaj një drejtkëndësh.
Në fund këto objekte janë vizatuar në objektin Graphics.
Njëra nga përparësitë e shtegut është se pasi të krijohen disa objekte të cilat vendosen në shteg,
dhe nëse në ndërkohë e kemi ndërruar ndonjë parametër të shtegut si p.sh. ngjyra, atëherë të gjitha
objektet që janë në shteg do të ndërrojnë përnjëherë.
Objekti BRUSH
Objekti Brush është një vegël e cila shërben për mbushjen e formave të mbyllura. Format mund
të mbushen me ngjyrë, me kombinim ngjyrash, me mostër të caktuar, apo edhe me bitmap. Objekti
Brush është objekt abstrakt (koncept i gjuhës C#) dhe objektet që trashëgohen ( inheritance) prej objekit
Brush mund të jenë:
SolidBrush i cili shërben për krijmin e brushës me ngjyrë të njëtrajtshme,
HatchStyle i cili përdoret për krijimin e brushave prej dy ngjyrave,
LinearGradientBrush, i cili përdoret për krijimin e brushës me ngjyrë të kombinuar,
Grafika kompjuterike
-41-
PathGradientBrush, i cili është brushë me ngjyrë të kombinuar më i sofistikuar në krahasim
me objektin LinearGradientBrush si dhe
TextureBrush i cili krijon brushën prej bitmapi
Objekti SOLIDBRUSH
Ky objekt përdoret për mbushjen e formës së mbyllur me ngjyrë të njëtrajtshme. Për të
konstruktuar një objekt të tillë, mund të përdoret kodi në C#:
SolidBrush s = new SolidBrush(brushColor);
ku brushColor është objekt i tipit Color dhe paraqet ngjyrën e brushës.
Detalet në lidhje me brushat e tjera mund të shihen në MSDN apo në literaturë tjetër që ka të bëjë
me C#.
Vizatimi i formave të ndryshme
Tani do të aplikohen metodat për vizatim të objektit Graphics. Le t’a implementojmë një
aplikacion të thjeshtë i cili ka një buton. Kur shfrytëzuesi e shtyp butonin atëherë do të vizatohet një
drejtkëndësh, dhe dy vija të drejta. Kodi në C# do të dukej kështu:
// Vizatimi i formës së thjeshtë, Programi_1
private void button1_Click(object sender, System.EventArgs e)
{
Graphics g;
g = this.CreateGraphics();
Pen lapsi = new Pen(Color.Red);
g.DrawRectangle(lapsi, 10, 10, 200, 150);
g.DrawLine(lapsi, 10, 10, 210, 160);
g.DrawLine(lapsi, 210, 10, 210, 160);
}
Grafika kompjuterike
-42-
Figura 31. Pamja e aplikacionit që, pas shtypjes së butonit Vizato formën, vizaton dy vija të
drejta dhe një drejtkëndësh.
Pra së pari e kemi definuar një objekt të tipit Graphics, që e kemi emërtuar me g. Pastaj në
formën e aplikacionit e kemi thirrur metodën CreateGraphics, që kthen një objekt të tipit Graphics, i cili
i ndahet variablës g. Hapi tjetër është krijimi i një objekti të tipit Pen (dmth një laps) që bën të
mundshme krijimin e lapsit me ngjyrë të kuqe. Pastaj objekti g e thërret metodën DrawRectangle, që
bën të mundshme vizatimin e drejtkëndëshit. Parametri i parë i kësaj metode është lapsi që e kemi
definuar më parë, ndërsa parametrat tjerë kanë të bëjnë me koordinatat fillestare të drejtkëndëshit dhe
gjatësinë dhe gjerësinë e drejtkëndëshit. Objekti g e thërret metodën DrawLine që e vizaton linjën me
laps të kuq (parametri i parë është lapsi), në koordinata të specifikuara sipas parametrave, ku 2
parametrat e ardhshëm paraqesin koordinatën x dhe y të pikës së parë, ndërsa 2 parametrat e fundit
paraqesin koordinatat x dhe y të pikës së dytë. Kjo mundëson që të vizatohet linja e parë. Në fund
vizatohet edhe linja e dytë, ngjashëm sikurse linja e mëparshme por me parametra tjerë.
Vizatimi i përhershëm
Nëse programin që e krijuam më lartë (Programi_1) e ekzekutojmë dhe e shtypim butonin
“Vizato formen”, atëherë do të bëhet vizatimi i dy vijave dhe një drejtkëndëshi. Mirëpo nëse e
aktivizojmë një program tjetër dhe nëse prapë kalojmë në aplikacionin tonë (pra Programi_1), atëherë
do të shohim se vijat dhe drejtkëndëshat janë zhdukur. Çdo objekt që vizatohet në objektin Graphics
është i përkohshëm. Pra shtrohet pyetja se si të bëhet vizatimi i objekteve ashtu që ato të jenë të
Grafika kompjuterike
-43-
përhershme. Microsofti sugjeron që për këtë qëllim të gjitha objektet të vendosen në metodën OnPaint,
që aktivizohet çdo herë që forma të rivizatohet. Për të aktivizuar këtë metodë duhet aktivizuar ngjarjen
(event) Paint, me shtypjen e të cilit krijohet metoda OnPaint. Pra në këtë rast do të bëjmë modifikimin e
shembullit të parë, ashtu që kodin që ka qenë brenda metodës button1_Click do t’a vendosim brenda
metodës OnPaint. Kështu programin e ardhshëm do t’a quajmë Programi_2 dhe kjo do të duket si vijon:
// Programi_2
private void OnPaint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
Graphics g;
g = this.CreateGraphics();
Pen lapsi = new Pen(Color.Red);
g.DrawRectangle(lapsi, 10, 10, 200, 150);
g.DrawLine(lapsi, 10, 10, 210, 160);
g.DrawLine(lapsi, 210, 10, 10, 160);
}
Tani nëse e aktivizojmë programin Programi_2 do të paraqitet drejtkëndëshi dhe dy vija. Nëse
aktivizohet një program tjetër dhe nëse prapë kthehemi në programin Programi_2, forma do të
rivizatohet.
Kjo teknikë është shumë e përshtatshme në rastet kur kemi të bëjmë me një numër të kufizuar të
objekteve grafike. Mirëpo shumë aplikacione do të vizatojnë figura në formë si përgjigje ndaj aksioneve
të shfrytëzuesit, si psh klikimi i ndonjë butoni apo ndonjë menyje do të mundësojë vizatimin e
objekteve të caktuara. Pra në këtë rast përdorimi i metodës OnPaint nuk mund të vijë në shprehje.
Zgjidhja do të ishte që vizatimi i objekteve të bëhej i përhershëm, ashtu që nuk do të ketë nevojë që të
bëhet rivizatimi i formës sa herë që forma nuk është e aktivizuar apo i ndryshohet madhësia.
Është e mundur që objektet grafike të bëhen të përhershme mirëpo të mos vizatohet në objektin e
tipit Graphics, por direkt në bitmapin e formës. Këtu do të kufizohemi vetëm në objektet permanente që
vizatohen në formë dhe në objektet e tipit PictureBox, e jo edhe në kontrolla tjera.
Që të kemi një sipërfaqe permanente vizatuese, duhet krijuar një objekt të tipit Bitmap, që ka
dimensione të njejta me formën, pra:
Bitmap bmp = new Bitmap(this.Width, this.Height);
Grafika kompjuterike
-44-
Objekti bmp paraqet një bitmap të zbrazët. E krijojmë një objekt të tipit Graphics duke e
shfrytëzuar metodën FromImage të objektit Graphics të cilën e emërojmë me G. Objektit G do t’ia
japim ngjyrën e prapavisë së formës. Pastaj, imazhit që është në prapavi do t’i ndahet objekti i tipit
Bitmap. Në fund objekti G kthehet nga funksioni. I tërë funksioni duket kështu:
Graphics GetGraphicsObject()
{
Bitmap bmp = new Bitmap(this.Width, this.Height);
Graphics G = Graphics.FromImage(bmp);
G.Clear(this.BackColor);
this.BackgroundImage = bmp;
return G;
}
Tani i krijojmë dy butona, ashtu që butoni i parë e shfrytëzon funksionin GetGraphicsObject,
ndërsa butoni i dytë nuk e shfrytëzon funksionin GetGraphics. Kodi në C# do të duket:
private void button1_Click(object sender, System.EventArgs e)
{
Graphics G = GetGraphicsObject();
Pen P = new Pen(Color.Blue);
G.DrawRectangle(P, 10, 10, 200, 150);
G.DrawLine(P, 10, 10, 210, 160);
G.DrawLine(P, 210, 10, 10, 160);
}
private void button2_Click(object sender, System.EventArgs e)
{
textBox1.CreateGraphics().DrawEllipse(Pens.Red, 10, 10, 200, 150);
}
Pra nëse shfrytëzuesi e shtyp butonin e parë dhe të dytë, do të paraqiten një drejtkëndësh dhe dy
linja (nga butoni i parë) dhe një elipsë. Mirëpo nëse aktivizohet ndonjë program tjetër dhe prapë
aktivizohet ky program, atëherë do të paraqitet vetëm drejtkëndëshi dhe dy vija të drejta, ndërsa elipsa
nuk do të paraqitet. Kjo ka të bëjë me atë se butoni i parë i vizaton objektet permanente në formë ndërsa
butoni i dytë vetëm objekte primitive të përkohshme.
Nëse dëshirojmë të paraqesim objekte permanente në objektin PictureBox, kodi në C# do të ishte:
Graphics GetGraphicsObject(PictureBox PBox)
Grafika kompjuterike
-45-
{
Bitmap bmp = new Bitmap(PBox.Width, PBox.Height);
PBox.Image = bmp;
Graphics G = Graphics.FromImage(bmp);
return G;
}
Pra ky kod është i ngjashëm me kodin për të krijuar objekte permanente në formë, mirëpo si
parametër hyrës duhet t’a marrim parametrin PictureBox. Ngjashëm si më parë edhe metodat që thirren
pas aktivizimit të butonave do të jenë të ngjashme, mirëpo në vend të rreshtit:
Graphics G = GetGraphicsObject();
Duhet përdorur rreshti:
Graphics G = GetGraphicsObject(pictureBox1);
Ku pictureBox1 është emri i kontrollës PictureBox.
Metodat për vizatim
Në C# ekzistojnë shumë metoda për vizatim, ashtu që secili objekt primitiv i ka metodat e veta.
Mirëpo të gjitha këto metoda i kanë disa veti të përbashkëta. Argumenti i parë është gjithmonë objekt i
tipit Pen, i cili bënë të mundshëm vizatimin e formës së caktuar në objektin Graphics. Argumentet tjera
varen nga metoda. Metoda DrawLine si parametra tjerë i merr pikën e parë dhe të fundit, ndërsa metoda
DrawRectangle si parametra tjerë e merr origjinën e drejtkëndëshit dhe dimensionet e tij.
Metodat për vizatim mund të ndahen në dy kategori: në metoda që vizatojnë konturat e një forme
si dhe në metoda që vizatojnë forma që mbushen. Zakonisht grupi i parë i metodave përmban prefiksin
Draw (psh DrawRectangle, DrawElipse, etj), ndërsa grupi i metodave të dyta përmban prefiksin Fill
(psh FillRectangle, FillElipse, etj). Dallimi tjetër në mes të metodave për vizatim të konturave dhe të
objekteve që mbushen është se objektet që mbushen e shfrytëzojnë objektin Brush për t’a mbushur një
formë, e jo objektin Pen.
Grafika kompjuterike
-46-
Tabela e m`poshtme tregon emrat e metodave për vizatim. Kolona e parë përmban metodat për
vizatimin e konturave, ndërsa kolona e dytë përmban metodat për mbushjen e objekteve (nëse ekziston
një metodë e tillë).
Metoda për vizatim Metoda për
mbushje të
objekit
Përshkrimi
DrawArc
DrawBezier
DrawBeziers
DrawClosedCurve
DrawCurve
DrawElipse
DrawIcon
DrawImage
DrawLine
DrawLines
DrawPath
DrawPie
DrawPolygon
DrawRectangle
DrawRectangles
DrawString
FillClosedCurve
FillElipse
FillPath
FillPie
FillPolygon
FillRectangle
FillRectangles
FillRegion
Vizaton një hark
Vizaton lakore të Bezierit
Vizaton shumë lakore të Bezierit
Vizaton një lakore të mbyllur
Vizaton një lakore
Vizaton një elipsë
Vizaton një ikonë në objektin Graphics
Vizaton një imazh në objektin Graphics
Vizaton një linjë
Vizaton shumë linja
Vizaton një objekt GraphisPath
Vizaton një formë të pites ( Pie)
Vizaton një poligon
Vizaton një drejtkëndësh
Vizaton shumë drejtkëndësha
Vizaton një tekst të caktuar
E mbush një objekt Region
Metoda DRAWLINE
Metoda DrawLine vizaton një vijë të drejtë në mes të dy pikave të specifikuara si argumente.
Argumenti tjetër është objekti i tipit Pen, pra lapsi me të cilën dëshirohet të vizatohet. Format më të
thjeshta të metodës DrawLine janë:
DrawLine(pen, x1, y1, x2, y2);
DrawLine(pen, point1, point2);
ku koordinatat x1, y1, x2, y2 janë të specifikuara në piksela, ndërsa point1, point2 janë objekte të
tipit Point.
Metoda DRAWRECTANGLE
Metoda DrawRectangle e vizaton një drejtkëndësh dhe ka këto forma:
DrawRectangle(pen, rectangle);
DrawRectangle(pen, X1, Y1, gjeresia, lartësia);
Grafika kompjuterike
-47-
Argumenti rectangle është një objekt i tipit Rectangle që e specifikon drejtkëndëshin i cili duhet
të vizatohet. Në formën e dytë argumentet X1 dhe Y1 janë koordinatat e skajit të epërm të majtë, ndërsa
argumentet tjera janë dimensionet e drejtkëndëshit.
Metoda DRAWELLIPSE
Për të vizatur një elipsë, duhet të thirret metoda DrawEllipse që i ka këto forma:
DrawEllipse(pen, rectangle);
DrawEllipse(pen, X1, Y1, gjerësia, lartësia);
Le t’a implementojmë një program i cili do të bëjë vizatimin e dy drejtëkëndëshave dhe dy
elipsave të cilin do t’a emërojmë Programi_3.
// Programi_3
private void button1_Click(object sender, System.EventArgs e)
{
Graphics g = this.CreateGraphics();
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.FillRectangle(Brushes.Silver, ClientRectangle);
Rectangle r1, r2;
r1 = new Rectangle(10, 10, 160, 320);
r2 = new Rectangle(200, 85, 320, 160);
g.DrawEllipse(new Pen(Color.Black, 3), r1);
g.DrawRectangle(Pens.Black, r1);
g.DrawEllipse(new Pen(Color.Black, 3), r2);
g.DrawRectangle(Pens.Red, r2);
}
Pra kur shfrytëzuesi e shtyp butonin, në formë do të vizatohen dy elipsa dhe dy drejtëkëndësha.
Metoda DRAWPIE
Forma PIE (në formë të pitës) është e ngjashme me sektoret rrethore: këtu ekziston një hark dhe
dy segmente të cilat i lidhin pikat e atij harku me qendrën e rrethit apo elipsës. Metoda DrawPie i
pranon si argumente objektin e tipit Pen me të cilin do të vizatohet forma e objektit Pie, drejkendëshin
në të cilin do të brendashkruhet objekti Pie, këndin ku fillon harku dhe këndi ku përfundon harku.
Grafika kompjuterike
-48-
Këndet startuese dhe përfunduese të harkut janë në drejtim të akrepave të orës. Pra dy format më të
thjeshta janë:
DrawPie(lapsi, drejtkëndëshi, këndi fillestar, këndi përfundues);
DrawPie(lapsi, X, Y, width, height, start, end);
Do t’a krijojmë një program i cili do t’i aplikojë këto funksione. Programin e tillë do t’a quajmë
Programi_4 dhe figura 32 tregon se si do të duket programi pas ekzekutimit.
Figura 32. Pamja e aplikacionit Programi_4 pas shtypjes së butonit “Vizato objektin pie”
private void button1_Click(object sender, System.EventArgs e)
{
Graphics g = this.CreateGraphics();
SolidBrush brush = new SolidBrush(Color.Green);
Rectangle rect = new Rectangle(100, 10, 300, 300);
float [] Angles = {0, 43, 79, 124, 169, 252, 331, 360};
Color [] Colors = {Color.Red, Color.Cornsilk, Color.Firebrick,
Color.OliveDrab, Color.LawnGreen, Color.SandyBrown,
Color.MidnightBlue};
g.Clear(Color.Ivory);
int angle;
for (angle = 1; angle < Angles.Length; angle++)
{
brush.Color = Colors[angle - 1];
g.FillPie(brush, rect, Angles[angle - 1], Angles[angle] -
Angles[angle - 1]);
}
g.DrawEllipse(Pens.Black, rect);
}
Grafika kompjuterike
-49-
Në këtë program i kemi definuar dy vargje të quajtur Angles dhe Colors. Vargu Angles i definon
këndet startuese të objektit Pie. Këndi përfundues është diferenca mes këndit startues dhe këndit
përfundues. Psh. këndi përfundues i objektit të parë Pie është Angles[1] – Angles[0] = 43 – 0 = 43.
Këtu do të përdoret metoda FillPie e cila do t’a bën mbushjen e një harku me ngjyrë të caktuar.
Metoda DRAWPOLYGON
Kjo metodë shërben për definimin e një poligon të çfarëdoshëm. Kjo i merr dy argumente, ku
argumenti i parë është një objekt i tipit Pen, ndërsa objekti i dytë është një varg i pikave që e definojnë
poligonin. Poligoni përbëhet prej aq brinjëve sa ka pika në vargun e pikave dhe është i mbyllur edhe
nëse pika e parë dhe e fundit nuk janë identike. Sintaksa për këtë metodë është:
DrawPoligon(pen, points());
Metoda DRAWCURVE
Për të vizatuar një lakore me metodën DrawCurve, duhet specifikuar lokacionet e pikave nëpër të
cilat lakorja duhet të kalojë dhe tensionet e lakores. Nëse tensioni është 0, lakorja është fleksibile,
ndërsa sa më i lartë të jetë tensioni, aq më e lëmuar do të jetë lakorja. Forma më e thjeshtë e metodës
DrawCurve është:
DrawCurve(pen, points, tension)
ku points është varg i pikave. Elementi i parë dhe i fundit i vargut pen janë pikat e fundit të
lakores por lakorja do të kalojë nëpër pikat tjera. Një shembull që tregon përdorimin e metodës
DrawCurve në gjuhën C# është dhënë në vazdhim dhe ky program do të emërohet Programi_5:
// Programi_5
private void button1_Click(object sender, System.EventArgs e)
{
Graphics g = this.CreateGraphics();
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
Point [] points = {new Point(20, 50), new Point(220, 190),
new Point(330, 80), new Point(450, 280)};
g.DrawCurve(Pens.Blue, points, 0.1f);
g.DrawCurve(Pens.Red, points, 0.5f);
g.DrawCurve(Pens.Green, points, 1f);
g.DrawCurve(Pens.Black, points, 2f);
Grafika kompjuterike
-50-
}
Figura 33. Pamja e aplikacionit pas ekzekutimit të programit Programi_5
Siq shihet nga kodi këtu do të kemi 4 pika të ndryshme të cilat i shfrytëzon metoda DrawCurve,
pra lakorja do të kalojë nëpër këto pika. Ky program përdor tensione të ndryshme të linjës, ashtu që
secila do të vizatohet me ngjyrë tjetër. Mund të vërehet se kur tensioni i linjës është 0, lakorja që kalon
nëpër dy pika është një drejtëz, ndërsa për vlera më të mëdha të tensionit do të kemi lakore më të
lëmuara.
Metoda DRAWBEZIER
Metoda DrawBezier vizaton lakore të Bezierit, të cilat janë më të lëmuara se lakoret të cilat
vizatohen me metodën DrawCurve. Lakorja e Bezierit definohet me dy pika të fundit dhe dy pika
kontrolluese. Pikat kontrolluese do të sillen si magnetë. Kjo metodë si parametër hyrës pranon një
objekt të tipit Pen dhe katër parametrat tjerë janë objekte të tipit Point.
DrawBezier(pen, point1, point2, point3, point4);
Programi në vazhdim e përdor metodën DrawBezier ashtu që njëra nga pikat kontrolluese do të
ndryshohet (parametri i 4-të), ndërsa pikat tjera të fundit të lakores dhe pika tjetër kontrolluese do të
mbetet konstante.
// Programi_6
private void button1_Click(object sender, System.EventArgs e)
{
Point P1 = new Point(120, 150);
Grafika kompjuterike
-51-
Point P2 = new Point(220, 90);
Point P3 = new Point(330, 30);
Point P4 = new Point(410, 110);
Graphics G = this.CreateGraphics();
G.DrawBezier(new Pen(Color.Blue), P1, P2, P3, P4);
P3 = new Point(330, 230);
G.DrawBezier(new Pen(Color.Red), P1, P2, P3, P4);
P3 = new Point(330, 330);
G.DrawBezier(new Pen(Color.Green), P1, P2, P3, P4);
}
Pra i kemi definuar 4 pika, ku pika P1 dhe P4 janë pikat e fundit, ndërsa pikat P2 dhe P3 janë
pikat kontrolluese. Thirret metoda DrawBezier me këto parametra dhe kemi lakoren me ngjyrë të kaltër.
Pastaj ndërrohet pika kontrolluese e dytë, apo pika P3 dhe prapë e vizatojmë lakoren tjetër e cila ka
ngjyrë të kuqe (parametri i parë në metodën DrawBezier është ngjyra e kuqe). Prapë e ndërrojmë pikën
P3 ashtu që kjo do të referojë në koordinata tjera dhe pasi e thërrasim funksionin DrawBezier do të
kemi lakoren e vizatuar me ngjyrë të gjelbër. Kjo mund të shihet edhe nga figura 34, ku janë të treguara
të tri lakoret me ngjyra të ndryshme që do të vizatohen pasi shfrytëzuesi ka shtypur butonin “Vizato
Bezier lakoret”.
Figura 34. Përdorimi i lakores së Bezierit me pika kontrolluese të ndryshme
Grafika kompjuterike
-52-
Metoda DRAWSTRING
Kjo metodë vizaton një tekst në sipërfaqen vizatuese. Teksti mund të vizatohet si një rresht i
vetëm, por edhe në më shumë rreshta. Forma më e thjeshtë e metodës DrawString është:
DrawString(string, font, brush, X, Y);
ku argumenti string është teksti që do të vizatohet në ekran ndërsa argumenti i dytë paraqet fontin
me të cilin do të bëhet vizatimi i tekstit. Argumenti i tretë paraqet brushën me të cilën bëhet vizatimi i
tekstit, ndërsa argumentet e fundit janë koordinatat X dhe Y të skajit të epërm të majtë ku do të bëhet
vizatimi i tekstit.
Forma tjetër e metodës DrawString pranon si argument një drejtkëndësh dhe bën vizatimin e
tekstit në këtë drejtkëndësh. Në këtë rast nëse teksti është më i gjatë se drejtkëndëshi, bëhet thyerja e
tekstit në disa rreshta. Sintaksa në këtë rast do të jetë:
DrawString(string, font, brush, rectanglef);
Në vazhdim programi Programi_7 bën vizatimin e tekstit në ekran në një pozitë të caktuar, dhe
poashtu bën thyerjen e një teksti të madh brenda një drejtkëndëshi:
// Programi_7
private void button1_Click(object sender, System.EventArgs e)
{
Graphics G = this.CreateGraphics();
G.DrawString("Grafika kompjuterike", new Font("Roman", 12,
FontStyle.Regular), Brushes.Black, 10, 10);
String txt = "Ky duhet te jete tekst i gjate i cili e demostron
perdorimin e metodes DrawString. ";
txt += txt + txt + txt;
G.DrawString(txt, new Font("Roman", 12, FontStyle.Bold),
Brushes.Black, new Rectangle(100, 80, 180, 250));
G.DrawRectangle(Pens.Red, 100, 80, 180, 250);
}
OBJEKTI ME NGJYRA TË NDRYSHME (GRADIENTI)
Objekti mund të mbushet me ngjyra të ndryshme (gradient). Teknikat për gradient mund të jenë
shumë të komplikuara, kështu që këtu do të shqyrtohen vetëm disa prej formave elementare.
Grafika kompjuterike
-53-
Gradienti linear
Gradientët janë të implementuara si brusha. Për të shfrytëzuar një gradient, duhet krijuar një
brushë me ngjyrë të caktuar. Hapi i parë për vizatimin e një gradienti bëhet duhet krijuar një objekt të
tipit LinearGradientBrush, pra:
LinearGradientBrush lgBrush;
lgBrush = new LinearGradientBrush(rect, startColor, endColor,
gradientMode);
Kjo metodë e krijon një gradient e cila e mbush një drejtkëndësh, e kjo specifikohet nga
parametri rect. Drejtkëndëshi nuk mbushet me ndonjë gradient, mirëpo me këtë tregohet se sa i gjatë do
të jetë gradienti. Gradienti fillon me parametrin e dytë startColor dhe përfundon me parametrin
endColor. Gradienti e ndërron ngjyrën ngadalë duke shkuar prej një drejtimi në tjetrin. Parametri i
fundit gradientMode specifikon drejtimin e gradientit dhe mund të ketë këto vlera:
BackwardDiagonal. Gradienti e mbush drejtkëndëshin në formë diagonale prej skajit të epërm të
djathtë (startColor) në skajin e poshtëm të majtë (endColor)
ForwardDiagonal. Gradienti e mbush drejtkëndëshin në formë diagonale, prej skajit të epërm të
majtë (startColor) në skajin e poshtëm të djathtë (endColor)
Horizontal. Gradienti e mbush drejtkëndëshin nga ana e majtë (startColor) në anën e djathtë
(endColor)
Vertical. Gradienti e mbush drejtkëndëshin nga pjesa e epërme (startColor) në pjesën e poshtme
(endColor).
Gradienti do të mbushet në bazë të dimensionit të drejtkëndëshit të specifikuar nga argumenti i
parë. Nëse forma që vizatohet është më e vogël se ky drejtkëndësh, vetëm një pjesë e drejtkëndëshit do
të mbushet. Nëse forma që mbushet është më e madhe se drejtkëndëshi, atëherë gradienti do të
përsëritet sa herë që të është e nevojshme në mënyrë që të mbushet forma.
Psh. supozojmë se duhet të përdoret gradienti i cili është horizontalisht 300 piksela. Ky gradient
duhet të mbush dy drejtkëndësha, ashtu që njëri është 200 piksela i gjerë, ndërsa tjetri është 600 piksela
i gjerë. Programi që e bën këtë do të emërohet Programi_8 dhe është dhënë në vazhdim:
// programi_8
private void button1_Click(object sender, System.EventArgs e)
{
Grafika kompjuterike
-54-
Graphics G = this.CreateGraphics();
Rectangle R = new Rectangle(20, 20, 300, 100);
Color startColor = Color.Red;
Color endColor = Color.Yellow;
LinearGradientBrush lgBrush;
lgBrush = new LinearGradientBrush(R, startColor, endColor,
LinearGradientMode.Horizontal);
G.FillRectangle(lgBrush, new Rectangle(20, 20, 200, 100));
G.FillRectangle(lgBrush, new Rectangle(20, 150, 600, 100));
}
Pas shtypjes së butonit “Vizato gradientin” në formë do të vizatohen këto objekte të cilat janë të
paraqitura në figurë.
Figura 35. Pamja e aplikacionit Programi_8 pas shtypjes së butonit “Vizato gradientin”
Gradienti i shtegut
Shfrytëzimi i gradientit të shtegut bën të mundur krijimin e gradientit që fillon në një pikë të
caktuar dhe që zbehet në ngjyra tjera në drejtime të ndryshme. Për t’a mbushur një objekt me gradient
të shtegut, së pari duhet krijuar një shteg. Gradienti i shtegut mund të aplikohet vetëm për një shteg të
caktuar, e jo për objekte tjera. Pra kodi për C# për të krijuar një gradient të shtegut do të jetë:
PathGradientBrush pathBrush = new PathGradientBrush(path);
ku path është një objekt i inicializuar në të cilin janë të përfshirë disa objekte.
Grafika kompjuterike
-55-
Objekti pathBrush është objekt i cili përcakton se si do të mbushet gradienti me ngjyra. Së pari
duhet specifikuar ngjyrën e gradientit në qendër të formës, duke e shfrytëzuar vetinë ( property)
CenterColor. Vetia SurroundColors është një varg i cili përmban aq elemente sa ka kulme në objektin
path. Çdo elementi të vargut duhet bashkangjitur një ngjyrë dhe gradienti resultues do të ketë
kombinimin e ngjyrave të elementeve të vargut SurroundColor.
Në vijim është krijuar aplikacioni Programi_9 i cili e ilustron përdorimin e gradientit të shtegut.
// Programi_9
private void button1_Click(object sender, System.EventArgs e)
{
Graphics g = this.CreateGraphics();
GraphicsPath path = new GraphicsPath();
path.AddLine(new Point(10, 10), new Point(400, 10));
path.AddLine(new Point(400, 10), new Point(400, 250));
path.AddLine(new Point(400, 250), new Point(10, 250));
PathGradientBrush pathBrush = new PathGradientBrush(path);
pathBrush.CenterColor = Color.Red;
Color [] surroundColor = {Color.Yellow, Color.Green,
Color.Blue, Color.Cyan};
pathBrush.SurroundColors = surroundColor;
g.FillPath(pathBrush, path);
}
Figura 36. Programi pas shtypjes së butonit “Gradienti i shtegut”
Pas shtypjes së butonit “Gradienti i shtegut” do të paraqitet gradienti sipas figurës 36. Kodi i
aplikacionit Programi_9 është i ngjashëm me kodet e spjeguara më parë.
Grafika kompjuterike
-56-
ALGORITMET PËR VIZATIMIN E OBJEKTEVE PRIMITIVE DYDIMENSIONALE
SKANIMI DHE KONVERTIMI I LINJËS
Algoritmi për skanim dhe konvertim të linjës llogaritë koordinatat e pikselave të cilët shtrihen në
(apo afër) linjën ideale të hollë të vënë në rrjetën dydimensionale. Është me rëndësi që sekuenca e
pikselave të shtrihet sa më afër linjës ideale dhe të jetë sa më e drejtë që të jetë e mundur. Nëse kemi një
linjë e cila është me trash`si 1 piksel ajo duhet të ketë ndriçueshmëri konstante dhe të mos jetë e varur
nga gjatësia dhe orientimi.
Figura 37 tregon një linjë e cila ka trashësi prej 1 pikseli dhe siç shihet kjo përmban piksela të
cilët janë të zmadhuar. Pikselat që e tregojnë linjën janë të paraqitura me ngjyrë të zezë të mbushur,
ndërsa pikselat tjerë që e paraqesin prapavinë kanë ngjyrë të bardhë. Në ekran diametri i pikselit është
më i madh se hapësira ndërmjet pikselave, kështu që përshkrimi sipas figurës 37 e zmadhon natyrën
diskrete të pikselave.
Figura 37. Konvertimi dhe skanimi i pikselave
ALGORITMI THEMELOR INKREMENTAL
Strategjia më e thjeshtë për skanimin dhe konvertimin e linjave është që të bëhet llogaritja e
pjerrtësisë së linjës të cilën do t’a shënojmë me m. Pjerrtësia m llogaritet si Δy/Δx, pra herësi i
Grafika kompjuterike
-57-
ndryshimit të koordinatës y ndaj koordinatës x. Kështu pasi ekuacioni i drejtzës është y = ax + b mund
të themi se për një pikë në pozitën i + 1 do të kemi:
yi+1 = mxi+1 + B = m(xi + Δx) + B = yi + mΔx
Në rastet kur Δx = 1, atëherë yi+1 = yi + m
Figura 38. Kalkulimi inkremental i (xi , yi)
Pra një ndryshim njësi i x-it e ndryshon y-in për m, e cila është pjerrtësia e linjës. Për të gjitha
pikat (xi, yi) që i takojnë linjës, nëse xi+1 = xi + 1, atëherë yi+1 = yi + m. Prej kësaj shihet se vlerat e x-it
dhe y-it janë të definuara varësisht prej koordinatës paraprake. Pra algoritmi inkremental bën llogaritjen
inkrementale varësisht nga hapi paraprak. Kjo mund të shihet edhe nga figura 38.
Inicializimi i pikës (x0 , y0) bëhet ashtu që kjo pikë është pika e fundme e linjës. Nëse |m| > 1, një
hap i vetëm në koordinatën x e rrit hapin në koordinatën y në vlerë më të madhe se 1.
Ky algoritëm quhet edhe algoritmi digjital diferencial. Ky algoritëm bën zgjidhjen e ekuacionit
diferencial me metoda numerike, pra vlerat sukcesive të (x, y) i gjen ashtu që i rrit vlerat e x-it dhe y-it
për një inkrement të vogël. Në rastin tonë, x inkrementohet për 1, ndërsa y për m = dy/dx. Programi në
C# për vizatimin e linjës sipas algoritmit të inkrementimit do të ishte:
void Line(int x0, int y0, int x1, int y1, Color value, Bitmap bmp)
{
int x;
float dy, dx, y, m;
dy = y1 - y0;
dx = x1 - x0;
m = dy / dx;
Grafika kompjuterike
-58-
y = y0;
for (x = x0; x <= x1; x++)
{
bmp.SetPixel(x, (int) Math.Floor(y + 0.5), value);
y += m;
}
}
Pra nga ky program shihet se si parametra hyrës janë koordinatat x0, y0, x1, y1, pastaj ngjyra që
duhet të vendoset në pikselat përkatës si dhe referenca në objektin e tipit Bitmap. Objekti bmp do të
nevojitet për të bërë vendosjen e pikselit në koordinatat e caktuara me ngjyrën e cila është e dhënë si
parametër me emrin value. Pra këtu përgjegjëse për vendosjen e pikselit në ngjyrë të caktuar është
metoda SetPixel e cila gjendet brenda for loop-ës, dhe e cila me rritjen e koordinatës x e rrit vlerën e
koordinatës y për vlerën m. Pjesa tjetër e kodit është e lehtë për t’u kuptuar, dhe nuk do të përshkruhet.
ALGORITMI I PIKËS SË MESME TË LINJËS
Dobësi e algoritmit themelor inkremental është se rrumbullaksimi i koordinatës y në vlerë
decimale do të merr kohë si dhe variablat y dhe m do të jenë numra me presje dhjetore, pasi që
pjerrtësia e linjës llogaritet si herës i dy numrave. Bresenhami e implementoi algoritmin e tillë ku
përdoren numrat e plotë dhe kështu eleminohet funksioni që e bën rrumbullaksimin. Bresenhami e
vërtetoi se linja e cila përdoret nga ky algoritëm është linja e cila më së shumti i përgjigjet linjës së
vërtetë ashtu që bëhet minimizimi i gabimit gjatë vizatimit të linjës.
Supozojmë se pjerrtësia e linjës është ndërmjet 0 dhe 1. Me pjerrtësitë tjera mund të operohet
ashtu që bëhet ndërrimi i koordinatave x dhe y në mes veti. Pikat e skajshme të linjës, pra pikën e
poshtme të majtë do t’a shënojmë me (x0 , y0), ndërsa pikën e epërme të djathtë do ta shënojmë me
koordinatat (x1 , y1). Spjegimi i kësaj metode mund të bëhet nga figura 39.
Grafika kompjuterike
-59-
Figura 39. Algoritmi i pikës së mesme
Nga figura 29 shihet linja e cila duhet të vizatohet. Pikseli i zi i selektuar në hapin paraprak duket
si rreth i vogël i zi, dhe hapi i ardhshëm tregon se njëri nga pikselat duhet zgjedhur. Pikselin në pozitën
(xp , yp) e kemi selektuar në hapin paraprak ndëra pikseli i ardhshëm që duhet selektuar pas
inkrementimit të koordinatës x duhet të jetë pikseli i shënuar me E ( East) apo pikseli i shënuar me NE (
North East). Le të jetë pika Q pikë e cila është prerja e linjës që skanohet me rrjetën e linjës. Në
formulimin e Bresenhamit njehsohet diferenca ndërmjet distancave vertikale NE-Q dhe E-Q dhe shenja
e diferencës së tillë përdoret për selektimin e pikselit. Distanca e cila është më e vogël është
aproksimimi më i mirë i linjës. Nga formulimi i pikës së mesme mund të shihet se ku gjendet pika M
(pika e mesme). Nëse pika e mesme gjendet mbi linjë, atëherë pikeli E është është më afër linjës, ndërsa
nëse pika e mesme gjendet nën linjë pikseli NE është më afër linjës.
Në rastin e figurës 29, si piksel i ardhshëm i zgjedhur do të jetë pikseli NE. Për të kalkuluar në
cilën pjesë të linjës gjendet pika e mesme duhet shprehur linjën me koeficientë a, b, c, ashtu që e kemi
funksionin F(x, y) = ax + by + c = 0. Nëse dy = y1 – y0 dhe dx = x1 – x0, pjerrtësia mund të llogaritet si
Bxdx
dyy
apo
F(x, y) = dy* x – dx * y + B * dx = 0,
ku a = dy, b = -dx, c = B * dx.
Mund të vërtetohet se F(x, y) është zero në linjë, pozitive për pikat nën linjë, dhe negative për
pikat mbi linjë. Për të përdorur kriterin e pikës së mesme, nevojitet të llogaritet F(M) = F(xP + 1, yP +
Grafika kompjuterike
-60-
½) dhe të testohet shenja e tij. Definohet variabla vendosëse d = F(xP + 1, yP + ½) e cila bën të mundur
caktimin e shenjës së këtij funksioni. Sipas definicionit d = a(xP + 1) + b(yP + 1/2) +c. Nëse d > 0
zgjidhet pikseli NE, nëse d < 0 zgjidhet pikseli E, ndërsa nëse d = 0 mund të zgjidhet cilido piksel.
Lokacioni i pikës M dhe vlera d për pikën e ardhshme do të varet nga ajo se a është zgjedhur
pikseli E apo NE. Nëse është zgjedhur pikseli E, pika M rritet për një njësi në drejtimin x. Pra kemi
dre = F(xP + 2, yP + ½) = a(xp + 2) + b(yP + ½) + c,
mirëpo
dvjetër = a(xP + 1) + b(yP + ½) + c
Pas zbritjes së variablës dvjetër nga dre mund të shkruajmë se dre = dre + a. Pas zgjedhjes së pikës E
inkrementin e quajmë ΔE, ku ΔE = a = dy. Pra me fjalë tjera vlera e variablës vendosëse mund të
gjendet në hapin e ardhshëm nga vlera e hapit që shqyrtohet pa pasur nevojë që të llogaritet vlera F(M)
në mënyrë direkte, duke e shtuar ΔE .
Nëse është zgjedhur pika NE, M inkrementohet për një hap në drejtimet x dhe y. Pra kemi
dre = F(xP + 2, yP + 3/2) = a(xp + 2) + b(yP + 3/2) + c,
Duke e zbritur dvjetër nga dre për të gjetur diferencën e inkrementeve, mund të shkruajmë se
dre = dvjetër + a + b
Inkrementin e tillë do t’a quajmë ΔNE ku ΔNE = a + b = dy – dx.
Pra t’a bëjmë një përmbledhje të teknikës së pikës së mesme. Për çdo hap algoritmi zgjedh në
mes të dy pikselave e kjo bazohet nga variabla vendosëse e kalkuluar në iteracionin e kaluar. Pastaj
bëhet azhurimi i variablës vendosëse duke e shtuar ose ΔE ose ΔNE në vlerën e vjetër, e që varet nga
zgjedhja e pikselit.
Pasi pikseli i parë është pika e parë e linjës, pra (x0, y0), vlera iniciale e variablës vendosëse d
mund të llogaritet si:
F(x0 + 1, y0 + ½) = a(x0 + 1) + b(y0 + ½) + c
= ax0 + by0 + c + a + b/2 = F(x0, y0) + a + b/2.
Grafika kompjuterike
-61-
Mirëpo (x0, y0) është një pikë e linjës dhe F(x0, y0) është 0, prandaj dfillim është: dfillim = a + b/2 =
dy – dx /2. Zgjedhja e pikselit të dytë varet nga variabla dfillim e kështu me rradhë. Për të eleminuar
herësin në dfillim definohet F në atë mënyrë që të jetë shumëfish i 2-it, pra F(x, y) = 2(ax + by + c). Kjo e
shumëzon çdo konstantë dhe variabël vendosëse për 2 mirëpo nuk ka efekt në shenjën e variablës
vendosëse, e cila është pjesa më e rëndësishme e këtij algoritmi.
Llogaritja e dre për cilindo hap është vetëm mbledhje e numrave të plotë. Duke e shikuar
programin e pikës së mesme në vazhdim shihet se në fillim të “while” ciklit testohet vlera e d-së që
përcakton zgjedhjen e pikselit. Inkrementimi i variablave x dhe y bëhet pas azhurimit të variablës
vendosëse.
void MidpointLine(int x0, int y0, int x1, int y1, Color value, Bitmap
bmp)
{
int dx, dy, incrE, incrNE, d, x, y;
dx = x1 - x0;
dy = y1 - y0;
d = dy * 2 - dx;
incrE = dy * 2;
incrNE = (dy - dx ) * 2;
x = x0; y = y0;
bmp.SetPixel(x, y, value);
while (x < x1)
{
if (d <= 0)
{
d += incrE;
x++;
}
else
{
d += incrNE;
x++;
y++;
}
bmp.SetPixel(x, y, value);
}
}
Grafika kompjuterike
-62-
ALGORITMI I PIKËS SË MESME TË RRETHIT
Ekzistojnë algoritme që bëjnë vizatimin e rrethit, mirëpo që nuk janë efikase. Këto algoritme
bazohen në formulën e rrethit x2 + y
2 = R
2. Këtu me rritjen e variablës x prej 0 në R, variabla y ndërron
sipas formulës së rrethit. Kjo qasje është joefikase, sepse këtu kemi të bëjmë me shumëzime dhe
operacione të rrënjës katrore. Poashtu vizatimi i rrethit në pikat me vlera të afërta të x-it me R do të
krijojë zbraztësira të mëdha e kjo nuk është vizatim i mirë i rrethit.
Qasja e Bresenhemit shfrytëzon pikën e mesme për të bërë vizatimin e rrethit. Këtu do të mirret
parasysh gjysëmrrethi me këndin fillestar 450 dhe kënd përfundimtar 90
0, pra prej x = 0 deri në x = y =
R/ 2 dhe kjo do të quhet oktanti i dytë. Sikur me strategjinë për vizatimin e linjës edhe ky algoritëm
selekton cili prej dy pikselave është më afër rrethit duke e llogaritur një funksion në pikën e mesme të 2
pikselave.
Figura 40. Rrjeta e pikselave për algoritmin e pikës së mesme të rrethit.
Në oktantin e dytë, nëse pikseli paraprak i zgjedhur si përafrim më i mirë i rrethit ka qenë P(xP,
yP), zgjedhja e pikselit të ardhshëm duhet të bëhet në mes pikselit E dhe SE (figura 40).
Le të jetë F(x, y) = x2 + y
2 – R
2 një funksion i cili është 0 në rreth, pozitiv jashtë rrethit dhe
negativ brenda rrethit. Mund të shihet se nëse pika e mesme ndërmjet pikselave E dhe SE është jashtë
rrethit, atëherë pikseli SE është më afër rrethit. Në anën tjetër nëse pika e mesme është brenda rrethit,
pikseli E është më afër rrethit. Sikur te linjat edhe këtu bëhet zgjedhja e variablës vendosëse d, e cila
paraqet vlerën e funksionit në pikën e mesme, pra:
Grafika kompjuterike
-63-
dvjetër = F(xP + 1, yP – ½) = (xP + 1)2 + (yP – ½)
2 – R
2
Nëse dvjetër < 0, pikseli E është zgjedhur, ndërsa pika e ardhshme inkrementohet për 1 në
koordinatën x. Pra:
dre = F(xP + 2, yP – ½) = (xP + 2)2 + (yP – ½)
2 – R
2
dhe dre = dvjetër + (2xP + 3). Për këtë arsye inkrementi do të jetë ΔE = 2xP + 3.
Nëse dvjetër > 0, pika SE është zgjedhur dhe pika e ardhshme e mesme do të rritet për 1 në
koordinatën x dhe do të zvoglohet për 1 në koordinatën y. Pra kemi
dre = F(xP + 2, yP – 3/2) = (xP + 2)2 + (yP – 3/2)
2 – R
2
Pasi dre = dvjetër + (2xP – 2yP + 5), inkrementi i ΔSE = 2xP – 2yP + 5.
Në rastin e algoritmit të linjës, ΔE dhe ΔNE janë konstante, ndërsa në këtë rast ΔE dhe ΔSE
ndryshojnë në çdo hap dhe janë funksione të variablave xP dhe yP. Pasi këto funksione shprehen në
varësi të pikave (xP, yP), pika P quhet pika e llogaritjes.
Pra funksionimi i këtij algoritmi kërkon që për çdo iteracion të llogariten dy hapa: 1) Zgjedhet
pikseli duke u bazuar nga variabla d e cila llogaritet në hapin e mëparshëm dhe 2) azhurohet variabla
vendosëse d me Δ e cila i përgjigjet zgjedhjes së pikselit.
Tani mbetet të llogaritet kushti fillestar. Duke e limituar algoritmin në numra të plotë në oktantin
e dytë, mund të thuhet se pikseli startues është në pikën (0, R). Pika e ardhshme e mesme është në
koordinatat (1, R – ½), prandaj kemi F(1, R – ½) = 1 + (R2 – R + ¼) – R
2 = 5/4 – R. Problemi me këtë
version është se në këtë mënyrë do të jemi të detyruar të bëjmë llogaritje të numrave me presje dhjetore.
Për këtë arsye e definojmë variablën e re vendosëse h, ashtu që h = d – ¼, e prej kësaj rrjedh se d = h +
¼. Tani kushti fillestar do të llogaritet si h = 1 – R, ndërsa krahasimi d < 0 do të bëhet h < -1/4. Pasi
vlera fillestare e variablës h fillon me numër të plotë dhe rritet për numrat e plotë ΔE dhe ΔSE , krahasimi
mund të ndërrohet ashtu që të jetë h < 0. Tani algoritmi do të operojë vetëm me numra të plotë. Në
algoritmin në vazhdim do të përdoret variabla d në vend të variablës h, e kjo bëhet për të pasur
konsistencë me algoritmin e linjës të spjeguar më parë.
void MidpointCircle(int radius, Color value, Bitmap bmp)
{
int x, y, d;
Grafika kompjuterike
-64-
x = 0;
y = radius;
d = 1 - radius;
CirclePoints(radius, x, y, value, bmp);
while (y > x)
{
if (d < 0)
{
d += x * 2 + 3;
x++;
}
else
{
d += (x - y) * 2 + 5;
x++;
y--;
}
CirclePoints(radius, x, y, value, bmp);
}
}
Siq shihet funksioni MidpointCircle e thërret funksionin CirclePoints i cili bën vizatimin e
pikselave në pozita të caktuara. Nëse rrethi e përmban një pikë (x,y) mund të caktohen 7 pikët tjera
simetrike të pikës (x, y) për të gjithë 7 oktantët tjerë. Për shkak të simetrisë së rrethit, llogaritja e
koordinatave tjera simetrike të pikës (x, y) bëhet duke i marrë pikat (-x, y), (-y, x), (-y, -x), (-x, -y), (x, -
y), (y, -x), (y, x) si koordinata simetrike.
Figura 41. Pikat simetrike të rrethit
Grafika kompjuterike
-65-
Për të bërë vizatimin e 8 pikave simetrike të rrethit shfrytëzohet funksioni CirclePoints, i cili e
shfrytëzon parametrin radius që paraqet qendrën e rrethit.
void CirclePoints(int radius, float x, float y, Color value, Bitmap
bmp)
{
bmp.SetPixel((int)(radius + x), (int)(radius + y), value);
bmp.SetPixel((int)(radius + y), (int)(radius + x), value);
bmp.SetPixel((int)(radius + y), (int)(radius - x), value);
bmp.SetPixel((int)(radius + x), (int)(radius - y), value);
bmp.SetPixel((int)(radius - x), (int)(radius - y), value);
bmp.SetPixel((int)(radius - y), (int)(radius - x), value);
bmp.SetPixel((int)(radius - y), (int)(radius + x), value);
bmp.SetPixel((int)(radius - x), (int)(radius + y), value);
}
MBUSHJA E DREJTKËNDËSHAVE
Mbushja e drejtkëndëshit është një proces i cili mund të ndahet në dy pjesë: mbushja e
drejtkëndëshit me piksela të njejtë si dhe mbushja e drejtkëndëshit me ndonjë mostër apo bitmap.
Mbushja e drejtkëndëshit me ngjyrë të njejtë është mjaft e thjeshtë dhe pseudokodi për mbushjen e
drejtkëndëshit është si në vijim:
for (y= ymin to ymax) // përgjatë boshtit y
{
for (x prej xmin deri xmax)// përgjatë boshtit x
SetPixel(x, y, value);
}
Cikli i parë “for” është përgjegjës për mbushjen e pikselave me ngjyrë për të gjitha kolonat e
drejtkëndëshit. Cikli i dytë është përgjegjës për mbushjen e një rreshti ashtu që koordinata y mbetet
konstante. Të gjithë pikselat do të mbushen me ngjyrë të njejtë, e kjo në pseudokod është e specifikuar
me parametrin “value” në funksionin SetPixel.
Në rastin kur drejtkëndëshin duhet t’a mbushim me një mostër, nevojitet të dihet relacioni në mes
të mostrës dhe të objektit që duhet mbushur. Me fjalë tjera duhet të dihet se ku është mostra statike
ashtu që të dihet se cili piksel në mostër korrespondon me pikselin e objektit.
Grafika kompjuterike
-66-
Teknika e parë që mostra të bëhet statike është ashtu që rreshti i parë i mostrës vendoset në
pikselat e majtë të objektit. Kjo mundëson që mostra të zhvendoset kur objekti primitiv zhvendoset, e
ky efekt pritet në rastet kur objekti primitiv është drejtkëndësh. Mirëpo në rastet kur objekti primitiv
është rreth apo shumëkëndësh zhvendosja e mostrës nuk do të bëhet sepse pika statike e mostrës mund
të ketë vlera të ndryshme.
Teknika e dytë është që i tërë ekrani të mbushet me mostër dhe objekti primitiv në këtë rast
përbëhet nga sipërfaqja e mbushur me mostrën e caktuar. Pozita standarde e pikës statike është origjina
e ekranit. Pikselat e objektit primitiv do të kenë vlera binare 1 dhe në këta piksela do të aplikohet
operatori And (dhe) ndaj mostrës. Dobësi e kësaj teknike është se nëse objekti primitiv do të
zhvendoset, pozita e mostrës nuk do të jetë e njejtë.
Për t’a mbushur objektin primitiv me mostër do të konsiderojmë se pikseli i objektit primitiv
është në koordinatat (x, y). Pasi mostrat janë të definuara si bitmap i vogël me dimensione psh. MxN,
do të përdoret aritmetika modulare ashtu që mostra të përsëritet. Pikseli i mostrës në pozitën (0, 0) do të
jetë i njejtë me origjinën e ekranit ndërsa pikselat tjerë të objektit primitiv do të mund të mbushen duke
shfrytëzuar aritmetikën modulare në këtë mënyrë:
if (pattern[x % M, y % M])
SetPixel(x, y, value);
Kjo duhet aplikuar përgjatë tërë objektit primitiv pra në drejtimin x dhe y, e duke filluar nga
rreshti i parë i objektit primitiv.
OBJEKTET PRIMITIVE ME TRASHËSI TË MËDHA
Në rastet kur objektet primitive duhen të jenë me trashësi më të madhe se 1, atëherë përdoret
skanimi dhe konvertimi i pikselave të objektit primitiv disa herë. Kjo është sikurse vizatimi i një objekti
me anë të brushës. Në rastet kur objekti primitiv ka trashësi 1 piksel, atëherë objekti është vizatuar me
trashësi të brushës 1 piksel. Mirëpo këtu shtrohen disa pyetje, si psh. çfarë forme duhet të ketë brusha.
Implementimet tipike shfrytëzojnë brusha në formë rrethore dhe drejtkëndëshe. Pastaj pyetja tjetër është
se a duhet brusha të ketë trashësi të njejtë dhe si do të duket fundi i vijës së trashë në formë ideale dhe
në rrjetën e pikselave?
Ekzistojnë shumë metoda të cilat e bëjnë vizatimin e objekteve me trashësi të ndryshme, dhe
figura 42 – 43 do të ilustrojnë këtë.
Grafika kompjuterike
-67-
Figura 42. Linja dhe rrethi me trashësi të madhe pas replikimit të pikselave
Figura 43. Linja dhe rrethi i trashë pas aplikimit të metodës së ndjekjes së lapsit drejtkëndësh
Forma ideale e objekteve primitive është e dhënë ashtu që pikselat që janë me trashësi 1 piksel
janë me ngjyrë të zezë, ndërsa objektet primitive me trashësi të caktuar janë me ngjyrë të hirtë. Duke i
vërejtur më detalisht këto objekte mund të shikohet se rezolucioni i objekteve me trashësi është i ultë.
Figura 42 përdor replikimin e pikselave për të vizatuar objektet me trashësi, ashtu që këtu përdoret më
shumë se 1 piksel për çdo kolonë gjatë skanimit dhe konvertimit. Figura 43 përdor lëvizjen e lapsit
drejtkëndësh e cila do t’a vizatojë objektin me trashësi. Këto metoda kanë rezultate të kënaqshme në
shumicën e rasteve. Në rastet kur duhet të përdoret vizatimi i objekteve primitive për printim, atëherë
duhet përdorur rezolucion më i madh, sepse në këtë rast shpejtësia e shtypjes së objektit nuk është
relevante. Në rastet e printimit përdoren algoritmet më komplekse për vizatimin e objekteve primitive
me trashësi e që bën të mundur arritjen e rezolucionit të dëshiruar.
REPLIKIMI I PIKSELAVE
T’a konsiderojmë një linjë që ka trashësi prej 1 pikseli dhe një linjë tjetër me trashësi më të
madhe se 1 piksel. Nëse linjën me trashësi prej 1 pikseli e duplikojmë në kolonat për të cilat pjerrtësia
Grafika kompjuterike
-68-
është ndërmjet -1 dhe 1, fitohet linja me trashësi. Efekti i fituar është se pikat e fundit të linjave janë në
formë vertikale apo horizontale, që nuk është formë ideale për linjat me trashësi të madhe.
Algoritmi i replikimit poashtu krijon zbraztësira në pjesët ku linjat formojnë një kënd të cakutar
dhe kur kemi zhvendosje prej replikimit horizontal në ate vertikal. Kjo anomali mund të shihet në
figurën 42 (pjesa ku vizatohet rrethi i trashë) ku pjesa ndërmjet dy oktanteve është mjaft e hollë. Përveq
kësaj trashësia e linjës që ka kënd 0 apo 900 (linjës horizontale apo vertikale) ndryshon prej trashësisë
së linjës e cila ka një kënd të caktuar. Kështu nëse parametri i trashësisë është t, trashësia e linjës
vertikale apo horizontale do të jetë t, ndërsa nëse linja ka këndin prej 450 atëherë ajo do të ketë trashësi
mesatare prej t/ 2 . Problem tjetër është problemi i pikselave me trashësi çifte. Objekti primitiv i
trashë përbëhet prej: qendrës që përmban objektin primitiv prej 1 pikseli dhe dy anëve që janë pikselat e
replikuar. Në rastin e trashësisë çifte njëra anë është e replikuar me më shumë piksela se se ana tjetër.
Algoritmi i replikimit është një algoritëm efikas por aproksimim i ashpër i objektit primitiv i cili tregon
rezultatet më të mira në rastet kur objektet primitive nuk kanë trashësi të madhe.
ALGORITMI I LËVIZJES SË LAPSIT
Nëse e zgjedhim një laps në formë të drejtkëndëshit ashtu që qendra apo skajet e lapsit lëvizin
dhe krijojnë piksela të ri përgjatë objektit primitiv me trashësi prej 1 piksel, do të kemi një objekt me
trashësi të caktuar. Ky laps do të funksionoj mjaft mirë për vizatimin e linjave, e kjo mund të shihet në
figurën 43. Mund të vërehet se kjo linjë është e ngjashme me linjën e krijuar me replikimin e pikselave,
mirëpo pikat e skajshme të linjës janë më të trasha krahasuar me algoritimin e replikimit të pikselave.
Sikur te replikimi i pikselave pasi lapsi është në pozitë vertikale, trashësia e objektit primitiv ndërron në
funksion të këndit të objektit primitiv. Gjerësia këtu është më e hollë për segmentet horizontale, ndërsa
më e trashë për segmentet me pjerrtësi ±1. Këndi i një elipse ka trashësi të ndryshueshme përgjatë
trajektorës së tij ashtu që ajo do të ketë trashësi siç është e specifikuar në rastet kur këndi është 00ose
900, ndërsa për këndet ±45
0 do të kemi më shumë piksela për faktorin 2 , e që mund të shihet në
figurën 43 ku është bërë vizatimi i rrethit.
SHKURTIMI I REGJIONEVE TË VIZATIMIT
Shkurtimi (clipping) i pjesëve të vizatimit mund të bëhet për të gjitha objektet primitive.
Shkurtimi i një drejtkëndëshi ndaj një drejtkëndëshi tjetër rezulton në një drejtkëndësh të thjeshtë.
Grafika kompjuterike
-69-
Shkurtimi i një poligoni konveks ndaj një drejtkëndëshi do të rezultojë në më së shumti një poligon
konveks, mirëpo shkurtimi i një poligoni konkav mund të krijojë më shumë se një poligon konkav.
Shkurtimi i një rrethi ndaj një drejtkëndëshi do të rezultojë në 4 harqe.
Linjat të cilat e prejnë një regjion drejtkëndësh do të shkurtohen në segment të thjeshtë. Linjat të
cilat janë në kufirin e drejtkëndëshit shkurtues konsiderohen brenda drejtkëndëshit, dhe për këtë arsye
do të paraqiten. Figura 44 tregon disa shembuj të linjave të shkurtuara. Në këtë figurë mund të shihet
regjioni drejtkëndësh i cili bën shkurtimin e linjave. Këtu linja AB është brenda drejtkëndëshit, prandaj
ajo do të tregohet e plotë në figurën 44.b). Linja CD nuk do të paraqitet e plotë në figurën 44.b), por do
të paraqitet vetëm prerja e drejtkëndëshit me linjë që është pika D’. Linja GH do të shkurtohet nga të
dyja anët dhe pas aplikimit të operacionit të shkurtimit do të kemi linjën G’H’. Linja EF nuk është
brenda zonës drejtkëndëshe, kështu që ajo nuk është vizatuar fare pas aplikimit të operacionit të
shkurtimit.
Le t’a shikojmë një problem të thjeshtë të shkurtimit të pikave të linjave. Nëse koordinata x e
drejtkëndëshit shkurtues ka pikat minimale dhe maksimale xmin dhe xmax, ndërsa koordinata y e
drejtkëndëshit ka pikat minimale dhe maksimale ymin dhe ymax, atëherë kushti që duhet plotësuar në
mënyrë që një pikë të gjendet brenda drejtkëndëshit shkurtues duhet të jetë:
xmin ≤ x ≤ xmax, ymin ≤ y ≤ ymax
Figura 44. Shembuj të shkurtimit të linjave
Për të shkurtuar një linjë, duhet të konsiderohen pikat e fundme të linjës. Nëse pikat e fundme të
linjës janë brenda drejtkëndëshit shkurtues (psh linja AB në figurën 44), atëherë linja gjendet brenda
drejtkëndëshit shkurtues dhe këtu nuk do të ketë shkurtim të linjës AB. Nëse njëra pikë është brenda
Grafika kompjuterike
-70-
drejtkëndëshit (linja CD në figurën 44), atëherë linja do t’a pret drejtkëndëshin dhe këtu duhet gjetur
pika prerëse në mes drejtkëndëshit dhe linjës. Nëse të dyja pikët e fundme të linjës gjenden jashtë
drejtkëndëshit mund të ekzistojë prerja në mes drejtkëndëshit dhe linjës, por mund të ndodhë që
drejtkëndëshi dhe linja të mos kenë pikë prerëse (shembujt EF, GH dhe IJ në figurën 44). Në rastin e
dytë duhet bërë më shumë kalkulime në mënyrë që të shihet nëse ka prerje të linjës me drejtkëndëshin.
Qasja e detyrueshme ( Brute force) që të bëhet shkurtimi i linjës është që të gjendet prerja e linjës
me majet e drejtkëndëshit shkurtues në mënyrë që të shihet se a prehet linja me majet e drejtkëndëshit.
Nëse prerja ekziston linja e pren drejtkëndëshin dhe është pjesërisht brenda drejtkëndëshit. Për çdo linjë
dhe maje të drejtkëndëshit mirren dy linja infinitve dhe e gjejmë prerjen e tyre. Pastaj e shqyrtojmë se a
është pika prerëse brenda drejtkëndëshit e nëse është atëherë pika e tillë quhet pikë e brendshme. Në
rastin e figurës 44, pikat prerëse G’ dhe H’ janë pika të brendshme, ndërsa pikat I’ dhe J’ nuk janë të
brendshme.
Nëse shfrytëzohet kjo qasje duhet zgjedhur sistemin e ekuacioneve duke e shfrytëzuar
shumëzimin dhe pjestimin për çdo çift [maje e drejtkëndëshit, linjë]. Në këtë rast përdoren linjat e
fundme, kështu që duhet përdorur formulimin parametrik për linja:
x = x0 + t(x1 – x0); y = y0 + t(y1 – y0)
Këto ekuacione i përshkruajnë koordinatat (x,y) të linjës prej (x0, y0) deri në (x1, y1), për
parametrin t në rangun [0,1]. Dy sisteme të ekuacioneve të formës parametrike mund të zgjidhen për
parametrat tmaje për majet e drejtkëndëshit dhe tline për linja. Vlerat e gjendura tmaje dhe tline verifikohen se
a gjenden brenda intervalit [0,1]. Nëse këto vlera gjenden në këtë interval atëherë pika prerëse është
pikë e brendshme. Edhepse qasja e detyrueshme përfshin shumë kalkulime dhe testime, ajo nuk është
shumë efikase.
ALGORITMI I COHEN-SUTHERLAND-IT PËR SHKURTIM TË
LINJAVE
Algoritmi i Cohen-Sutherland-it fillimisht bën testimin e linjës për të përcaktuar se a mund të
eleminohet kalkulimi i prerjes së majes së drejtkëndëshit me linjën. Së pari bëhet verifikimi i pranimit
të pikave të fundme. Nëse linja nuk mund të pranohet verifikimi i regjioneve është kryer. Për shembull
në rastin e figurës 44 të dyja pikat e linjës EF kanë koordinatën x e cila është më e vogël se xmin, dhe për
këtë arsye gjenden majtas nga drejtkëndëshi shkurtues. Për këtë arsye segmenti EF do të refuzohet dhe
Grafika kompjuterike
-71-
nuk do të paraqitet. Në mënyrë të ngjashme mund të bëhet refuzimi i linjave të cilat kanë pikat e
fundme djathtas nga xmax, poshtë nga ymin dhe lartë nga ymax.
Nëse linja as nuk mund të pranohet e as të refuzohet, ajo ndahet në dy segmente në majen e
drejtkëndëshit shkurtues, ashtu që një segment mund të refuzohet. Prandaj një segment në mënyrë
iterative do të shkurtohet duke testuar për pranim apo refuzim. Pastaj bëhet ndarja e sërishme e
segmentit dhe verifikohet sa a është pranuar apo refuzuar segmenti. Kjo ndarje do të bëhet derisa pjesa
që mbetet është brenda zonës drejtkëndëshe dhe do të pranohet, apo do të refuzohet. Algoritmi është
efikas për dy raste të shpeshta. Rasti i parë është kur drejtkëndëshi shkurtues është një sipërfaqe e
madhe ashtu që shumica e objekteve primitive do të mund të pranohen. Rasti tjetër është kur
drejtkëndëshi shkurtues është një sipërfaqe e vogël ashtu që shumica e objekteve do të refuzohen.
Për të bërë testet e pranimit apo refuzimit, bëhet ndarja e majeve të drejtkëndëshit shkurtues në 9
regjione, sipas figures 45. Çdo regjioni i është ndarë një kod prej 4 bitave varësisht nga ku gjendet
regjioni në krahasim me majet e drejtkëndëshit shkurtues. Çdo bit mund të ketë vlerë 1 (e saktë) ose 0
(e pasaktë), dhe 4 bitat në kod korrespondojnë me këto kondita:
Figura 45. Regjioni i kodeve dalëse
Biti i parëJashtë drejtkëndëshit shkurtues, lartë nga maja e epërme y > ymax
Biti i dytëJashtë drejtkëndëshit shkurtues, poshtë nga maja e poshtme y < ymin
Biti i tretëJashtë drejtkëndëshit shkurtues, djathtas maja e djathtë x > xmax
Biti i katërtJashtë drejtkëndëshit shkurtues, majtas nga maja e majtë x < xmin
Regjioni që gjendet në anën e epërme dhe të majtë të drejtkëndëshit shkurtues ka kodin 1001. Një
formë efikase për kalkulimin e majeve të epërme dhe të majtë vjen nga observimi se biti 1 është shenja
Grafika kompjuterike
-72-
e bitit të shprehjes (ymax – y), biti 2 është shenja e (y - ymin). Biti 3 është shenja e shprehjes (xmax – x)
ndërsa biti 4 është shenja e shprehjes (x - xmin). Çdo pike të fundme të linjës i është ndarë kodi i
regjionit në të cilin shtrihet. Në bazë të pikave të fundme përcaktohet se a gjendet linja brenda
drejtkëndëshit shkurtues apo jashtë drejtkëndëshit shkurtues. Nëse të dy pikët e fundme të linjës janë
zero, atëherë linja shtrihet brenda drejtkëndëshit shkurtues. Nëse të dy pikët e fundme të linjës gjenden
jashtë majës së drejtkëndëshit siç është rasti me linjën EF ashtu që kodi i të dy pikave të fundme ka
bitin 1 të vendosur në pozitën e njejtë, atëherë linja duhet të refuzohet.
Nëse linja nuk mund të pranohet apo të refuzohet, duhet të bëhet ndarja në dy segmente ashtu që
një apo dy segmente refuzohen. Këtu bëhet llogaritja e kodeve e të dy pikave të fundme dhe bëhet
verifikim i pranimit apo refuzimit të linjës. Kjo mund të shihet më mirë nga figura 46. Nëse
konsiderohet linja AD, pikat e fundme të kësaj linje janë pikat A dhe D. Pika A ka kodin 0000, ndërsa
pika D ka kodin 1001. Kjo linjë as nuk mund të pranohet e as të refuzohet. Prandaj algoritmi zgjedh
pikën D si pikë të jashtme kodi i të cilit tregon se linja kryqëzohet nga maja e epërme dhe e majtë. Sipas
rradhitjes së testit bëhet shkurtimi i linjës AD në linjën AB dhe llogaritet kodi i pikës B i cili është
0000. Tani bëhet testi i pranim/refuzimit të pikës AB dhe pasi kodet e të dy pikave janë 0000 bëhet
pranimi dhe paraqitja e kësaj linje.
Figura 46. Ilustrimi i shkurtimit të linjës sipas algoritmit të Cohen-Sutherland-it
Linja EI kërkon më shumë iteracione. Pika e parë e fundme e linjës është E e cila ka kodin 0100,
prandaj algoritmi e zgjedh këtë si pikë të jashtme dhe pasi krahasohet me drejtkëndëshin shkurtues,
bëhet shkurtimi i linjës EI në linjën FI. Në iteracionin e ardhshëm FI as nuk mund të pranohet e as të
refuzohet. Kodi i pikës së parë të fundme është 0000 prandaj algoritmi e zgjedh pikën e parë të jashtme
pikën I, kodi i të cilit është 1010. Maja e parë që shkurtohet është maja e epërme, që jep si rezultat
linjën FH. Kodi i pikës H është 0010 prandaj iteracioni i tretë sjell shkurtimin e majës së djathtë të
linjës FG. Prandaj hapi i fundit do të bëjë pranimin e linjës dhe tani mund të bëhet paraqitja e linjës.
Kodi në vazhdim do të jetë kodi që ilustron shkurtimin e linjës sipas kodit të Cohen-Sutherland-it
typedef struct
Grafika kompjuterike
-73-
{
unsigned all;
unsigned left:4;
unsigned right:4;
unsigned botton:4;
unsigned top:4;
} outcode;
// algoritmi i Cohen Sutherlandit per linje prej P0 = (x0, y0) deri
P1=(x1, y1) dhe
// drejtkendeshi shkurtues prej (xmin, ymin) deri (xmax, ymax)
void CohenSutherlandLineClipAndDraw(float x0, float y0, float x1,
float y1, float xmin, float xmax, float ymin, float ymax, int value)
{
boolean accept, done;
outcode outcode0, outcode1, outcodeOut;
float x, y;
accept = FALSE;
done = FALSE;
outcode0 = CompOutCode(x0, y0, xmin, xmax, ymin, ymax);
outcode1 = CompOutCode(x1, y1, xmin, xmax, ymin, ymax);
do
{
if (outcode0.all == 0 && outcode1.all == 0)
{
accept = TRUE;
done = TRUE;
}
else if ((outcode0.all & outcode1.all) != 0)
{
done = TRUE; /* prerja logjike eshte e sakte, prandaj kemi refuzim
//te linjes dhe dalje*/
else
{
if (outcode0.all != 0)
outcodeOut = outcode0;
else
outcodeOut = outcode1;
// linja ndahet ne pjesen e eperme te drejkendeshit shkurtues
Grafika kompjuterike
-74-
if (outcodeOut.top)
{
x = x0 + (x1 – x0) * (ymax – y0)/ (y1 – y0);
y = ymax;
}
// linja ndahet ne pjesen e poshtme te drejkendeshit shkurtues
else if (outcodeOut.bottom)
{
x = x0 + (x1 – x0) * (ymin – y0)/ (y1 – y0);
y = ymin;
}
// linja ndahet ne pjesen e djathte te drejkendeshit shkurtues
else if (outcodeOut.right)
{
y = y0 + (y1 – y0) * (xmax – x0)/ (x1 – x0);
x = xmax;
}
// linja ndahet ne pjesen e majte te drejkendeshit shkurtues
else if (outcodeOut.left)
{
y = y0 + (y1 – y0) * (xmin – x0)/ (x1 – x0);
x = xmin;
}
if (outcodeOut.all == outcode0.all)
{
x0 = x;
y0 = y;
outcode0 = CompOutCode(x0, y0, xmin, xmax, ymin, ymax);
}
else
{
x1 = x;
y1 = y;
outcode1 = CompOutCode(x1, y1, xmin, xmax, ymin, ymax);
}
}
} while (!done);
Grafika kompjuterike
-75-
if (accept)
// versioni per koordinata me pike te levizshme
MidpointLineReal(x0, y0, x1, y1, value);
}
outcode CompOutCode(float x, float y, float xmin, float xmax, float
ymin, float ymax)
{
outcode code;
code.top = 0, code.bottom =0, code.right = 0, code.left = 0, code.all
= 0;
if (y > ymax)
{
code.top = 8;
code.all += code.top;
}
else if (y < ymin)
{
code.bottom = 4;
code.all += code.bottom;
}
if (x > xmax)
{
code.right = 2;
code.all += code.right;
}
else if (x < xmin)
{
code.left = 1;
code.all += code.left;
}
return code;
}
Grafika kompjuterike
-76-
TRANSFORMIMET GJEOMETRIKE DYDIMENSIONALE
TRANSFORMIMET THEMELORE GJEOMETRIKE
DYDIMENSIONALE
Në vazhdim do të diskutohet transformimi gjeometrik dydimensional i objekteve që shfrytëzohen
në grafikën kompjuterike. Operacionet themelore që përdoren për transformime gjeometrike janë:
zhvendosja, shkallëzimi dhe rotacioni.
ZHVENDOSJA
Pikat e objektit në rrafshin (x, y) mund të zhvendosen në pozita të reja ashtu që atyre pikave iu
shtohen vlera të përcaktuara të zhvendosjes. Nëse çdo pikë P(x,y) zhvendoset për njësinë dx paralel me
rrafshin x, si dhe për njësinë dy paralel me rrafshin y në pikën tjetër P’(x’,y’), atëherë matematikisht kjo
mund të shkruhet:
x’ = x + dx,y’ = y + dy............................... (11)
Nëse definohen vektorët
P =
y
x, P’ =
'
'
y
x,T =
y
x
d
d,…………… (12)
Atëherë ekuacioni (11) mund të shprehet më saktë si
P’ = P + T………………………………….. (13)
Zhvendosja e objektit mund të bëhet duke përdorur ekucionin (13) për çdo pikë të objektit. Pasi
çdo linjë e objektit përbëhet prej pafundësisht shumë pikave, ky proces do të zgjaste pafundësisht
shumë. Fatmirësisht kjo mund të bëhet ashtu që bëhet zhvendosja e vetëm pikave të fundme të objektit
dhe pastaj bëhet vizatimi i vijave të reja ndërmjet pikave të fundme të zhvendosura. Kjo teknikë mund
Grafika kompjuterike
-77-
të aplikohet edhe për operacionin e shkallëzimit. Figura 47 tregon efektin e zhvendosjes së një figure
për pozitën (3, -4) dhe ate njëra pjesë e figurës e tregon pozitën e “shtëpisë“ para zhvendosjes ndërsa
pjesa tjetër e tregon pozitën pas zhvendosjes.
Figura 47. Zhvendosja e një objekti për pozitën (3, -4)
SHKALLËZIMI
Pikat e një objekti mund të shkallëzohen për konstantën sx përgjatë boshtit x dhe për konstantën
sy përgjatë boshtit y në pika të reja duke shfrytëzuar këto relacione:
x’ = sx * x,y’ = sy * y..................................................................(14)
Apo në formë matricore:
'
'
y
x
=
y
x
s
s
0
0
*
y
x ose P’ = S * P………….. (15)
ku S është matrica në ekuacionin (15).
Grafika kompjuterike
-78-
Figura 48. Shkallëzimi jouniform: “shtëpia” do t’a ndërrojë pozitën
Në figurën 48 shtëpia është shkallëzuar për ½ në koordinatën x dhe për ¼ përgjatë koordinatës y.
Shkallëzimi bëhet rreth origjinës së sistemit koordinativ, ashtu që shtëpia pas shkallëzimit është më e
vogël dhe më afër prej origjinës. Nëse të dy faktorët e shkallëzimit janë më të mëdha se 1, shtëpia do të
ishte më e madhe dhe më larg nga origjina. Kemi dy tipe të shkallëzimit: shkallëzimi diferencial në të
cilën sx ≠ sy ku proporcionet e objektit do të ndërrohen krahasuar me proporcionet e objektit para
shkallëzimit. Tipi tjetër i shkallëzimit është shkallëzimi uniform në të cilin sx = sy. Në këtë rast do të
bëhet zmadhimi apo zvoglimi i objektit mirëpo zmadhimi (zvoglimi) do të bëhet për shkallë të njejtë si
në koordinatën x ashtu edhe në ate y.
ROTACIONI
Pikat e objektit mund të rrotullohen për këndin θ rreth origjinës. Rotacioni matematikisht
definohet si:
x’ = x * cosθ – y * sinθ, y’ = x * sinθ + y*cosθ.......... (16)
Në formë matricore kjo mund të shkruhet si:
'
'
y
x =
cossin
sincos*
y
x ose P’ = R * P……………………. (17)
ku R është matrica e rotacionit në ekuacionin (17).
Grafika kompjuterike
-79-
Në figurën 49 është paraqitur rotacioni i shtëpisë për këndin 450. Sikur te shkallëzimi, rotacioni
bëhet përgjatë origjinës. Këtu përdoret konvencioni që këndet pozitive maten në drejtim të kundërt të
akrepave të orës prej boshtit x kah boshti y. Për këndet negative mund të shfrytëzohen relacionet cos(-θ)
= cosθ dhe sin(-θ) = - sinθ për të modifikuar ekuacionet (16) dhe (17).
Ekuacionet (16) mund të nxirren shume lehtë nga figura 49, në të cilën bëhet rotacioni i pikës
P(x, y) në pikën P’(x’, y’) për këndin θ. Pasi që rotacioni bëhet rreth origjinës së sistemit koordinativ
distancat prej origjinës në pikën P dhe prej origjinës në pikën P’ janë të njejta, e në figurën 40. këto
distanca janë të paraqitura me r. Me anë të ekuacioneve të thjeshta trigonometrike, mund të gjendet se:
x = r * cos Φ, y = r* sin Φ....................................................... (18)
Figura 49. Rotacioni i “shtëpisë”.
‘Shtëpia” do t’a ndërrojë pozitën dhe
x’ = r * cos(θ + Φ) = r * cos Φ * cos θ - r * sin Φ * sin θ
y’ = r * sin (θ + Φ) = r * cos Φ * sin θ + r * sin Φ * cos θ.............(19)
Duke zëvendësuar ekuacionet (18) në ekuacionet (19), do të fitohet ekuacioni (16).
Grafika kompjuterike
-80-
Figura 50. Rotacioni i një pike
KOORDINATAT HOMOGJENE DHE PREZENTIMI I
TRANSFORMIMEVE DYDIMENSIONALE PËRMES MATRICAVE
Prezentimi matricor i zhvendosjes, shkallëzimit dhe rotacionit është i dhënë përmes formulave:
P’ = T + P..................... (13)
P’ = S * P.................... (15)
P’ = R * P................... (17)
Siç po shihet nga këto formula operacioni i zhvendosjes paraqitet ndryshe në krahasim me
operacionet e shkallëzimit dhe rotacionit. Do të ishte mirë që të tri transformimet të paraqiten në
mënyrë konsistente, ashtu që kombinimi i tyre të jetë sa më i lehtë. Nëse pikat paraqiten në koordinata
homogjene, të tri transformimet mund të paraqiten përmes operatorit të shumëzimit.
Në koordinata homogjene bëhet shtimi edhe i një koordinate. Kështu një pikë e caktuar në vend
se të paraqitet përmes çiftit të numrave (x, y), do të paraqitet përmes treshes (x, y, W). Në të njejtën
kohë për dy treshe të ndryshme (x, y, W) dhe (x’, y’, W’) mund të thuhet se paraqesin pikën e njejtë
nëse njëra nga treshet është shumëfish i treshes tjetër. Kështu pikat (2, 3, 6) dhe (4, 6, 12) paraqesin
pikën e njejtë të paraqitur përmes koordinatave të ndryshme. Pra secila pikë mund të ketë shumë
reprezentime të ndryshme të koordinatave homogjene. Poashtu së paku njëra nga koordinatat
homogjene duhet të jetë jozero: pika (0, 0, 0) nuk është e lejuar. Nëse koordinata W është jozero, mund
të bëhet pjestimi sipas koordinatës W i një pike, pra pika me koordinata (x, y, W) është e njejtë me
pikën me koordinata (x/w, y/w, 1). Kur W është jozero dhe bëhet pjestimi i koordinatave me W, numrat
Grafika kompjuterike
-81-
x/w dhe y/w quhen koordinata karteziane të pikës homogjene. Pikat për të cilat W = 0 quhen pika
infinite.
Treshet e koordinatave përdoren për prezentimin e pikës në hapësirën tridimensionale, mirëpo
këtu pikat paraqiten në hapësirën dydimensionale. Lidhja mes këtyre dy nocioneve është: nëse i marrim
të gjitha treshet që paraqesin pikën e njejtë, pra të gjithat treshet e formës (tx, ty, tw) ashtu që t ≠ 0 do të
fitohet një linjë në hapësirën tridimensionale. Nëse bëhet homogjenizimi i pikës (pra nëse pjestohet me
W), do të fitohet pika e formës (x, y, 1). Prandaj pikat homogjene do të formojnë një rrafsh të definuar
me ekuacionin W = 1 në hapësirën (x, y, w). Figura 51 tregon relacionin e tillë. Pikat infinite nuk janë
të paraqitura.
Figura 51. Hapësira e koordinatave homogjene XYW me rrafshin W = 1 dhe pikën P(X, Y, W) të
projektuar në rrafshin W = 1.
Pasi pikat janë të paraqitura me tri parametra, duhet të operohet me matrica me 3 dimensione.
Ekuacionet e zhvendosjes sipas formulës (11) mund të shkruhen në formë matricore në këtë mënyrë:
1
*
100
10
01
1
'
'
y
x
d
d
y
x
y
x
…………… (20)
Ekuacioni (20) mund të shkruhet edhe në këtë formë:
P’ = T(dx, dy) * P……………………………… (21)
Ku
Grafika kompjuterike
-82-
T(dx, dy) =
100
10
01
y
x
d
d
…………………… (22)
Nëse një pikë zhvendoset për T(dx1, dy1) në pikën P’ dhe nëse pika e zhvendosur P’ zhvendoset
për pikën P’’ për T(dx2, dy2) rezultati i fituar do të jetë shuma e zhvendosjes së atyre pikave, pra matrica
T do të jetë T(dx1 + dx2, dy1 + dy2). Vërtetimi i kësaj teoreme është mjaft i thjeshtë, pra kemi dy pika P’
dhe P’’ me ekuacionet:
P’ = T(dx1, dy1) * P…………………………. (23)
P’’ = T(dx2, dy2) * P’……………………….. (24)
Duke zëvendësuar ekuacionin (24) në ekuacionin (23) do të fitohet:
P’’ = T(dx2, dy2) * ( T(dx1, dy1) * P) = (T(dx2, dy2) * T(dx1, dy1) )* P… (25)
Produkti matricor T(dx2, dy2) * T(dx1, dy1) është:
100
10
01
2
2
y
x
d
d
*
100
10
01
1
1
y
x
d
d
=
100
10
01
21
21
yy
xx
dd
dd
………………. (26)
Në mënyrë të ngjashme ekuacionet e shkallëzimit prezentohen në formë matricore si:
1
*
100
00
00
1
'
'
y
x
s
s
y
x
y
x
………………………………………………….. (27)
Duke e definuar matricën S(sx, sy) që të jetë
Grafika kompjuterike
-83-
100
00
00
),( y
x
yx s
s
ssS ……………………………………..(28)
do të kemi
P’ = ),( yx ssS * P……………………………………..…………. (29)
Ngjashëm sikur te rasti i transformimit sukcesiv të zhvendosjes ku transformimi sukcesiv është
aditiv, te transformimi sukcesiv i shkallëzimit rezultati përfundimtar do të jetë multiplikativ. Pra nëse
kemi pikat e shkallëzuara,
P’ = S(sx1, sy1) * P……………………………………………… (30)
P’’ = S(sx2, sy2) * P’…………………………………………….. (31)
Dhe duke zëvendësuar ekuacionin (30) në ekuacionin (31), do të kemi:
P’’ = S(sx2, sy2) * ( S(sx1, sy1) * P) = (S(sx2, sy2) * S(sx1, sy1) )* P…….… (32)
Produkti matricor S(sx2, sy2) * S(sx1, sy1) do të jetë
100
00
00
2
2
y
x
s
s
*
100
00
00
1
1
y
x
s
s
=
100
0*0
00*
21
21
yy
xx
ss
ss
……………. (33)
Operatori i rotacionit i shprehur përmes ekuacioneve (16) mund të shprehet si:
1
*
100
0cossin
0sincos
1
'
'
y
x
y
x
……………………………………………… (34)
Nëse matricën me dimensione 3x3 në ekuacionin (34) e shenojmë me R(θ), pra
Grafika kompjuterike
-84-
R(θ) =
100
0cossin
0sincos
………………………….(35)
Atëherë do të kemi:
P’ = R(θ) * P…………………………………………………… (36)
Nëse matrica transformuese ka formën:
100
2221
1211
y
x
trr
trr
……………………………………….. (37)
Për transformimet që kanë matricën transformuese sikur në ekuacionin (37) do themi se janë
transformime të papërkulshme, sepse trupi i objektit që transformohet nuk do të shtrembërohet në asnjë
mënyrë. Një sekuencë e operacioneve të zhvendosjes dhe rotacionit do të krijojë një matricë të tillë.
Nëse matrica transformuese është produkt i një sekuence të matricave të rotacionit, zhvendosjes
dhe shkallëzimit, atëherë transformimi i tillë thuhet se është transformim afin. Transformimet afine
kanë vetinë se e ruajnë paralelizmin e linjave, por gjatësitë dhe këndet e linjave nuk do të ruhen. Figura
52 paraqet objektin pas aplikimit të rotacionit për këndin -450 dhe shkallëzimit jouniform. Nga figura
52 është e qartë se nga ky transformim këndet dhe gjatësitë e linjave nuk janë ruajtur, por linjat paralele
kanë mbetur paralele. Nëse edhe më tutje në objekt aplikohen transformimet e rotacionit, shkallëzimit
dhe zhvendosjes kjo nuk do të shkaktojë që linjat paralele të mos mbesin paralele. Matricat R(θ), S(sx,
sy) dhe T(dx, dy) janë poashtu afine.
Figura 52. Një kub është rotulluar për -450 dhe pastaj është bërë shkallëzimi në mënyrë
jouniforme.
Grafika kompjuterike
-85-
Tip tjetër i transformimeve primitive është transformimi i pjerrtësuar ( shear) i cili është poashtu
transformim afin. Transformimet e pjerrtësuara dydimensionale mund të jenë të dy tipeve: pjerrtësimi
përgjatë boshit x dhe përgjatë boshtit y. Figura 53 tregon efektin e pjerrtësimit të një kubi përgjatë
secilit bosht. Ky operacion është paraqitur nga kjo matricë:
SHx =
100
010
01 a
… (41)
Figura 53. Operacioni i pjerrtësimit i zbatuar në një kub njësi. Në këtë rast gjatësitë e objektit të
pjerrët janë më të mëdha se 1
Termi a në matricën e pjerrtësuar është konstantë e proporcionalitetit. Këtu duhet vërejtur se
produkti SHx * [x y 1]T
është [x+ay y 1]T, ku T paraqet matricën e transponuar që demostron
ndërrimin proporcional të koordinatës x nga koordinata y. Ngjashëm si te koordinata x, matrica
SHy =
100
01
001
b ………………………………………………….. (42)
do të bëjë pjerrtësimin e objektit përgjatë boshtit y.
KOMPOZICIONI I TRANSFORMIMEVE DYDIMENSIONALE
Qëllimi kryesor i aplikimit të transformimeve të kompozuara është që të fitohet në efikasitet duke
përdorur një transformim të kompozuar të vetëm e jo duke aplikuar një seri të transformimeve njëri pas
Grafika kompjuterike
-86-
tjetrit. Le t’a konsiderojmë rotacionin e një objekti përgjatë një pike arbitrare P1. Pasi ne dimë se si të
bëhet rotacioni vetëm përgjatë origjinës, ne e transformojmë problemin tonë të ndërlikuar në tri
probleme të thjeshta. Pra për të rrotulluar objektin rreth pikës P1, sekuencialisht do të bëhen tri
transformime:
Zhvendoset objekti ashtu që pika P1 të jetë origjina
Bëhet rotacioni i objektit
Bëhet zhvendosja e pikës ashtu që objekti zhvendoset në pikën P1
Figura 54. Rotacioni i shtëpisë rreth pikës P1 për një kënd θ
Kjo sekuencë është paraqitur në figurën 54, ashtu që shtëpia është rrotulluar rreth pikës P1.
Zhvendosja e parë është bërë për (-x1, -y1), ndërsa zhvendosja tjetër është bërë për (x1, y1). Rezulati do
të ndryshojë në krahasim me operacionin në të cilën vetëm rotacioni do të përdoret.
Transformimi i fituar do të jetë:
T(x1, y1) * R(θ) * T(-x1, -y1) =
100
10
01
1
1
y
x
*
100
0cossin
0sincos
*
100
10
01
1
1
y
x
=
100
sin)cos1(cossin
sin)cos1(sincos
11
11
xy
yx
………… (43)
Grafika kompjuterike
-87-
Qasje e ngjashme mund të përdoret nëse dëshirojmë të shkallëzojmë një objekt përgjatë një pike
arbitrare P1. Së pari bëhet zhvendosja e pikës P1 në origjinë, pastaj bëhet shkallëzimi dhe në fund bëhet
zhvendosja e objektit në pikën P1. Në këtë rast trasformimi i fituar do të jetë:
T(x1, y1) * S(sx, sy) * T(-x1, -y1) =
100
10
01
1
1
y
x
*
100
00
00
y
x
s
s
*
100
10
01
1
1
y
x
=
100
)1(0
)1(0
1
1
yy
xx
sys
sxs
………………………………… (44)
Supozojmë se dëshirojmë të shkallëzojmë, rrotullojmë dhe zhvendosim shtëpinë sipas figurës 55
me pikën P1 si qendër të rotacionit dhe shkallëzimit.
Figura 55. Rotacioni i shtëpisë përgjatë pikës P1 dhe vendosja ashtu që qendra e objektit në fund
vendoset në pikën P2
Sekuenca që aplikohet këtu është: së pari pika P1 zhvendoset në origjinë, pastaj bëhet shkallëzimi
dhe rotacioni i objektit dhe në fund bëhet zhvendosja në pozitën P2 ku gjendet qendra e shtëpisë. Nëse
këtë e shprehim përmes matricave transformuese, atëherë do të kemi:
T(x2, y2) * R(θ) * S(sx, sy) * T(-x1, -y1)…………………………………. (45)
Grafika kompjuterike
-88-
TRANSFORMIMI I KOORDINATAVE DRITARE NË VIEWPORT
Disa sisteme grafike e lejojnë programerin që të specifikojë koordinatat në sistemin koordinativ
world duke përdorur njësitë e ndryshme në programin aplikativ si mikrona, metra, inqa, etj. Termi
world (botë) përdoret sepse programi aplikativ paraqitet si një “botë” e cila krijohet dhe i prezentohet
shfrytëzuesit.
Nëse objektet primitive janë të specifikuara në koordinata world, duhet të ekzistojë subrutina apo
paketa e cila do të transformojë koordinatat world në koordinata të ekranit. Një mënyrë për t’a bërë këtë
transformim është që programeri i aplikacionit e specifikon regjionin në formë drejtkëndëshe në
koordinata world të cilat quhen dritare të koordinatave world. Poashtu programeri e specifikohon
regjionin korrespondues drejtkëndësh në koordinata të ekranit të quajtura viewport. Programeri është
përgjegjës për transformimin e dritares në viewport. Transformimi që bën shndërrimin e dritares në
viewport do të aplikohet në të gjitha objektet primitive që janë në koordinata world, të cilat do të
shndërohen në koordinata të ekranit. Figura 56 do të ilustrojë konceptin e tillë. Siç shihet nga figura 56
nëse dritarja dhe viewporti nuk kanë raportin e njejtë lartësi-gjerësi shkallëzimi do të jetë jouniform.
Nëse programi aplikativ e ndërron dritaren apo viewportin atëherë objektet e reja primitive do të
ndikohen nga ky ndryshim. Objektet që kanë qenë të paraqitura më parë nuk do të ndikohen nga ky
ndryshim.
Figura 56. Dritarja në koordinata world dhe viewporti në koordinata të ekranit përcaktojnë
shndërrimin që aplikohet në të gjitha objektet primitve në world koordinata
Grafika kompjuterike
-89-
Disa aplikacione mund të bëjnë ndërrimin e viewport-it apo dritares. Shembulli që mund të
paraqitet është kur programi aplikativ do të ndërrojë dritaren apo viewportin në çdo kohë me ç’rast
objektet primitive të specifikuara do të kishin transformime të reja. Nëse ndërrimi do të përfshinte një
viewport tjetër, atëherë objektet primitive do të paraqiten në pozita të ndryshme nga pozitat e vjetra, e
kjo është treguar në figurën 57.
Figura 57. Efekti i vizatimit të objekteve primitive me 2 viewport-a. Objektet primitive së pari
janë vizatuar me viewportin 1, pastaj viewporti është ndërruar në viewportin 2 dhe pastaj aplikacioni e
ka thirrur prapë rutinën grafike për vizatimin e objektet primitive
Nëse është e dhënë dritarja dhe viewporti do të dëshironim të dinim transformimet matricore që e
bëjnë shndërrimin e dritares me world koordinatave në viewport me koordinata të ekranit. Kjo mund të
shihet nga figura 58.
Figura 58. Hapat që e bëjnë transformimin e dritares me world koordinata në viewport
Dritarja e cila është e specifikuar me koordinatën e poshme të majtë dhe të epërme të djathtë
është zhvendosur në origjinë të world koordinatave. Pastaj madhësia e dritares është shkallëzuar ashtu
që të jetë e njejtë me madhësinë e viewportit. Hapi i ardhshëm është zhvendosja e viewportit. Matrica
totale Mwv e fituar me kompozimin e 2 matricave zhvendosëse dhe një matrice shkallëzuese është:
Grafika kompjuterike
-90-
),(*),(*)( minmin
minmax
minmax
minmax
minmaxminmin, yxT
yy
vv
xx
uuSvuTM wv
=
100
10
01
min
min
v
u
* *
100
00
00
minmax
minmax
minmax
minmax
yy
vv
xx
uu
100
10
01
miny
xmiin
=
=
100
0
0
min
minmax
minmaxmin
minmax
minmax
min
minmax
minmaxmin
minmax
minmax
vyy
vvy
yy
vv
uxx
uux
xx
uu
……………………… (46)
Duke shumëzuar matricat P = Mwv *[x y 1]T fitohet rezultati i dëshiruar:
1*)(*)(' min
minmax
minmaxminmin
minmax
minmaxmin v
yy
vvyyu
xx
uuxxP
… (47)
Disa pakete grafike i kombinojnë transformimet dritare-viewport me shkurtimin ( Clipping) të
objekteve primitive grafike. Figura 59 e ilustron konceptin e shkurtimit të dritares dhe viewportit.
Figura 59. Objektet primitive në world koordinata janë të shkurtuara rreth dritares. Mbetjet e
objekteve janë të paraqitura në viewport
Pra, shihet se vetëm mbetjet e objekteve primitive janë paraqitur në viewport, pra ka ardhur deri
te shkurtimi i objekteve që paraqiten në koordinata të ekranit.
Grafika kompjuterike
-91-
DETYRA DHE USHTRIME
Shembull 1: Të vizatohet drejtëza në Forme në mes koordinatave (0,0) dhe (200,200).
Drejtëza duhet të ketë ngjyrë të kuqe.
Shënim: Drejtëza (vija) është bashkim i dy pikave:
Metoda për vizatim të vijes: DrawLine (lapsi, pika1, pika2)
Kodi: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace grafika_1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Pen lapsi; lapsi = new Pen(Color.Red); Graphics grafika = this.CreateGraphics(); grafika.DrawLine(lapsi, 0, 0, 200, 200); } } }
Rezultati ne ekran:
Grafika kompjuterike
-92-
Shembull 2: Të vizatohet vija që kalon nëpër pikat me koordinata: (10, 10), (10, 100), (150,
50) dhe (200, 250).
Kodi: Duke selektuar në Forme, pastaj Event dhe Paint private void Form1_Paint(object sender, PaintEventArgs e) { Pen lapsi; lapsi = new Pen(Color.Blue, 4); //…4 eshte trashesia e vijes Graphics grafika = this.CreateGraphics(); // definimi i vargut te (4) pikave Point[] pikat = { new Point (10, 10), new Point (10, 100), new Point (150, 50), new Point (200, 250) }; grafika.DrawLines(lapsi, pikat); }
Rezultati ne ekran:
Shembull 3: Të vizatohet drejtkëndeshi me parametrat (20, 20), gjeresi dhe lartesi (200, 150).
Shenim: Drejtkëndeshi është një figurë gjeometrike me katër brinjë këndedrejta:
Grafika kompjuterike
-93-
Metoda për drejtkëndesh është: DrawRectangle(lapsi, x, y, gjerësia, lartësia)
Kodi: Duke selektuar në Forme dhe pastaj tek Events dhe ne Paint:
private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g; g = this.CreateGraphics(); /*...krijimi i objektit Pen (lapsit), 2.4f eshte trashesia e vijes, f eshte floating point... */ Pen lapsi = new Pen(Color.Black, 2.4f); g.DrawRectangle(lapsi, 20, 20, 200, 150); }
Rezultati ne ekran:
Shembull 4: Të mbushet drejkëndeshi me ngjyrë.
Kodi: Për mbushje të drejtkëndeshit me ngjyrë përdoret objketi SolidBrush: private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g; g = this.CreateGraphics(); SolidBrush brusha = new SolidBrush(Color.Gold); g.FillRectangle(brusha, new Rectangle(10, 10, 120, 100)); }
Rezultati ne ekran:
Grafika kompjuterike
-94-
Shembull 5: Të vizatohet drejtkëndeshi dhe dy vijat të brendashkruara në diagonale.
Kodi: Në Forme krijojme nje buton (me emrin button1) dhe pastaj brenda tij definojme objeket
Graphics, Pen, dhe metodat DrawRectangle (për vizatim të drejtkëndeshit) dhe DrawLine (për
vizatim të vijave).
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace objekti_Pen { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { // definimi i objektit te tipit Graphics me emrin g Graphics g; // thirret metoda CreateGraphics qe i atribohet variables g g = this.CreateGraphics(); // krijimi i objektit Pen (lapsit) Pen lapsi = new Pen(Color.Blue); // g e therret metoden DrawRectangle per vizatim te drejtkendeshit // koordinatat (10, 10) dhe (200, 150) per gjeresi dhe lartesi g.DrawRectangle(lapsi, 10, 10, 200, 150); // g therret metoden DrawLine g.DrawLine(lapsi, 10, 10, 210, 160); // vizatimi i vijes se dyte me koordinatat (210,10) dhe (10,160) g.DrawLine(lapsi, 210, 10, 10, 160); } } }
Grafika kompjuterike
-95-
Rezultati ne ekran:
Shembull 6: Të vizatohet elipsa me koordinatat (50, 50) dhe (100, 100).
Shënim: Elipsa është një vijë e vazhdueshme e mbyllur, ku dy pikat e boshtit koordinativ jane
ne distance të njejtë nga boshti koordinativ. Kjo mund të shihet si në figurën e mëposhtme.
Në c# metoda për vizatimin e elipses është Graphics.DrawElipse().
Kodi: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace grafika_2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e)
Grafika kompjuterike
-96-
{ // vizatimi i elipses. e.Graphics.DrawEllipse(Pens.Blue, 50, 50, 100, 100); } } }
Rezultati ne ekran:
Shembull 7: Të mbushet Elipsa brenda katërkëndeshit me koordinata (100,100) si dhe gjerësi
dhe gjatësi (200, 300). Elipsa duhet të ketë ngjyrë të kuqe.
Shënim: Elipsa mund të vendoset brenda drejtkëndeshit, në koordinatat e caktuara.
Kodi: Së pari në Forme krijohet një button, pastaj mbushet Elipsa me ngjyrë korale brenda
katërkëndeshit me koordinata (50, 50) si dhe gjerësi dhe gjatësi (100, 200). using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace grafika_4 { public partial class Form1 : Form {
Grafika kompjuterike
-97-
public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { SolidBrush myBrush = new SolidBrush(Color.Coral); Graphics formGraphics = this.CreateGraphics(); formGraphics.FillEllipse(myBrush, new Rectangle(50, 50, 100, 200)); } } }
Rezultati ne ekran:
Shembull 8: Të vizatohet drejtkëndeshi, ndërsa brenda tij rrethi me diagonalet në të dy skajet e
tij.
Kodi:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace detprovimi { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g; // thirret metoda CreateGraphics qe i atribohet variables g g = this.CreateGraphics(); Pen lapsi = new Pen(Color.Red, 2f); Pen lapsi1 = new Pen(Color.Blue, 2f); Pen lapsi2 = new Pen(Color.Black); // koordinatat (10, 10) dhe vlera 150 per gjatesi dhe 150 per gjeresi
Grafika kompjuterike
-98-
g.DrawRectangle(lapsi, 10, 10, 150, 150); g.DrawLine(lapsi1, 10, 10, 160, 160); g.DrawLine(lapsi1, 160, 10, 10, 160); e.Graphics.DrawEllipse(lapsi2, new Rectangle(10, 10, 150, 150)); } } }
Rezultati ne ekran:
Shembull 9: Të krijohen dy drejtkëndesha me elipsa të brendashkruar. Drejtkëndeshi i parë me
koordinatat (10, 10), gjerësi dhe gjatësi (160, 320), drejtkëndeshi i dytë me koordinatat (200,
85), gjerësi dhe gjatësi (320, 160).
Kodi: Në Forme tek Event selektohet Paint. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace detyre_9 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = this.CreateGraphics(); Rectangle r1, r2; r1 = new Rectangle(10, 10, 160, 320); r2 = new Rectangle(200, 85, 320, 160); g.DrawEllipse(new Pen(Color.Blue, 3), r1);
Grafika kompjuterike
-99-
g.DrawRectangle(Pens.Black, r1); g.DrawEllipse(new Pen(Color.Red, 3), r2); g.DrawRectangle(Pens.Red, r2); } } }
Rezultati ne ekran:
Shembull 10: Të krijohet dhe të mbushet një objekt bitmap si dhe të paraqitet në kontrolen
PictureBox.
Shënim: Bitmap-i është një fajll që tregon një ngjyrë për secilin pixel (element të pikturës)
përgjatë boshtit x dhe y.
Kodi: Algoritmi gjendet në funksionin KrijoBitmap(). Së pari duhet që në Forme të krijohet
një kontrol pictureBox dhe një button. Pas klikimit në Button1 mbushet (merr si image)
Bitmap-in e mbushur me pixela si me poshtë. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace bitmap { public partial class Form1 : Form { public Form1() { InitializeComponent(); } // funksioni CreateBitmap i tipit void void KrijoBitmap() { // krijimi i Bitmap-it Bitmap pamja = new Bitmap(500, 500); for (int x = 0; x < pamja.Width; ++x) { for (int y = 0; y < pamja.Height; ++y)
Grafika kompjuterike
-100-
{ pamja.SetPixel(x, y, Color.Red); } } for (int x = 0; x < pamja.Height; ++x) { pamja.SetPixel(x, x, Color.Blue); } pictureBox1.Image = pamja; } private void button1_Click(object sender, EventArgs e) { // thirrja e funksionit KrijoBitmap(); } } }
Rezultati ne ekran:
Shembull 11: Gjenerimi i rastësishem i pikselave në bitmap.
Kodi: Në Forme krijojmë:
- Buton, me emrin button1
- PictureBox, me emrin pictureBox1
Sa herë që shtypet butoni (Set Pixel) do të vendoset piksel-at në bitmap në mënyrë të
rastësishme, me ngjyrë të kaltërt (blue).
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace bitmap1 {
Grafika kompjuterike
-101-
public partial class Form1 : Form { public Form1() { InitializeComponent(); } void krijobitmap() { Bitmap bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height); Random random = new Random(); for (int i = 0; i < bitmap.Height; i++) { for (int j = 0; j < bitmap.Width; j++) { if (random.Next(0, 4) == 0) { bitmap.SetPixel(j, i, Color.Blue); } } } pictureBox1.Image = bitmap; } private void button1_Click(object sender, EventArgs e) { krijobitmap(); } } }
Rezultati ne ekran:
Shembull 12: Të mbushet Forma me disa Elipsa me ngjyra të ndryshme.
Elipsa e pare duhet të jetë brenda katërkëndeshit me koordinata (50, 50) si dhe gjerësi dhe
gjatësi (100, 150). Elipsat tjera duhet të jenë të zhvendosura horizontalisht.
Kodi: Së pari në Forme krijohet një button, pastaj mbushet Elipsa me ngjyrë brenda
katërkëndeshit me koordinata (50, 50) si dhe gjerësi dhe gjatësi (100, 200).
Krijohet një varg me ngjyra Color[] ngjyrat, pastaj është inicializuar objekti SolidBrush me
një ngjyrë, dhe në fund në një unazë (me iteracione aq sa kemi ngjyra) ndryshojnë ngjyrat dhe
koordinatat e elipsave ku me i * 50 bëhët zhvendosja në aspektin horizontal.
Grafika kompjuterike
-102-
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace grafika_4 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { // krijimi i vargut te ngjyrave per elipsat
Color[] ngjyrat = {Color.Red,Color.Blue, Color.Violet, Color.Green, Color.Black};
SolidBrush brusha = new SolidBrush(ngjyrat[0]); Graphics grafika = this.CreateGraphics(); for (int i = 0; i < ngjyrat.Length; i++) { brusha.Color = ngjyrat[i];
grafika.FillEllipse(brusha, new Rectangle(50 + i*50, 50, 150, 100));
} } } } }
Rezultati ne ekran:
Shembull 13: Të mbushet Forma me disa drejtkëndesha. Drejtkëndeshi i parë duhet të jetë me
koordinata (vlerax, 100), gjerësi dhe lartësi (200, 150), kurse të tjerët duhet të jenë të
zhvendosura vetëm horizontalisht për 180 p. Ngjyra e lapsit të jetë e ndryshme për sëcilin
drejtkëndesh.
Grafika kompjuterike
-103-
Kodi: Së pari krijohet butoni (button1) dhe pastaj krijohet vargu me ngjyra për katër
drejtkëndeshat. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace grafika_drejtkendeshat { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) {
Color[] ngjyrat = { Color.Red, Color.Blue, Color.Violet, Color.Green, Color.Black };
Pen lapsi; lapsi = new Pen(ngjyrat[0]); Graphics grafika = this.CreateGraphics(); int vleraX = 100; for (int i = 0; i < ngjyrat.Length; i++) { lapsi.Color = ngjyrat[i]; grafika.DrawRectangle(lapsi, new Rectangle(vleraX, 100, 200, 150)); vleraX = vleraX + 180; } lapsi.Dispose(); grafika.Dispose(); } } }
Rezultati ne ekran:
Grafika kompjuterike
-104-
Shembull 14: Të mbushet Forma me disa trekendësha. Trekëndeshi i parë duhet të jetë me
koordinata P1 (100, 100), P2(200, 200) dhe P3(100, 300), kurse të tjerët duhet të jenë të
zhvendosura (pika e dytë P2 vetëm horizontalisht).
Kodi: Krijojmë metoden void VizatoTrekend(Point X1, Point X2, Point X3, Pen
lapsi, Graphics g) e cila vizaton një trekëndesh në mes të pikave X1, X2 dhe X3.
Në metoden button1_Click së pari janë krijuar tri pika, të cilat pastaj si parametra janë
vendosur në metoden VizatoTrekend. Gjithashtu është krijuar dhe inicialzuar edhe objekti Pen
si dhe Graphics.
Gjatë vizatimit të trekendëshit të dytë dhe të tretë është ndryshuar vetëm koordinata X e pikës
së dytë.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace grafika_trekendeshat { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
/* Kjo metode vizaton tri drejteza (segmente) ne mes pikave X1, X2 dhe X3. Keto
segmente krijojne nje trekendesh. Kjo metode thirret pastaj ne button1_Click.*/ void VizatoTrekend(Point X1, Point X2, Point X3, Pen lapsi, Graphics g) { g.DrawLine(lapsi, X1, X2); g.DrawLine(lapsi, X1, X3); g.DrawLine(lapsi, X2, X3); } private void button1_Click(object sender, EventArgs e) { Pen lapsi; lapsi = new Pen(Color.Blue); Point p1 = new Point(100, 100); Point p2 = new Point(200, 200); Point p3 = new Point(100, 300); Graphics grafika = this.CreateGraphics(); VizatoTrekend(p1, p2, p3, lapsi, grafika); p2.X = 400; VizatoTrekend(p1, p2, p3, lapsi, grafika);
Grafika kompjuterike
-105-
p2.X = 600; VizatoTrekend(p1, p2, p3, lapsi, grafika); lapsi.Dispose(); grafika.Dispose(); } } }
Rezultati ne ekran:
Shembull 15: Të vizatohet trekendëshi me njerën brinje në elipsë.
Kodi: Krijohet metoda void VizatoTrekend(Point X1, Point X2, Point X3, Pen
lapsi, Graphics grafika)e cila vizaton një trekendësh në mes të pikave X1, X2 dhe X3.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace grafika_koni { public partial class Form1 : Form {
/* Kjo metode vizaton tri drejteza (segmente) ne mes pikave X1, X2 dhe X3. Keto
segmente krijojne nje trekendesh. Kjo metode thirret pastaj ne button1_Click.*/ void VizatoTrekend(Point X1, Point X2, Point X3, Pen lapsi, Graphics grafika) { grafika.DrawLine(lapsi, X1, X2); grafika.DrawLine(lapsi, X1, X3); grafika.DrawLine(lapsi, X2, X3); } public Form1()
Grafika kompjuterike
-106-
{ InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Pen lapsi; lapsi = new Pen(Color.Red); Graphics grafika = this.CreateGraphics(); grafika.DrawEllipse(lapsi, new Rectangle(100, 100, 200, 300)); Point p1 = new Point(200, 100); Point p2 = new Point(200, 400); Point p3 = new Point(800, 200); VizatoTrekend(p1, p2, p3, lapsi, grafika); lapsi.Dispose(); grafika.Dispose(); } } }
Rezultati ne ekran:
Shembull 16: Të vizatohet poligoni nëpër pesë pika, pastaj të mbushet poligoni me ngjyrë.
Kodi: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace poligoni {
Grafika kompjuterike
-107-
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics grafika = this.CreateGraphics(); Pen lapsi = new Pen(Color.Black, 4); SolidBrush brusha = new SolidBrush(Color.Blue); // krijimi i vargut te pikave te poligonit me koordinata Point[] pikat = { new Point(113, 283), new Point(70, 156), new Point(180, 70), new Point(290, 156), new Point(250, 283) }; grafika.DrawPolygon(lapsi, pikat); grafika.FillPolygon(brusha, pikat); } } }
Rezultati ne ekran:
Shembull 17: Vizatimi i objektit “pie”.
Shenim: “Pie” është një pjesëz e elipses e kufizuar me dy vija të lidhura me qendren e elipses.
Grafika kompjuterike
-108-
Metoda për definimin e objektit Pie është DrawPie (lapsi, drejtkëndeshi, startAngle,
sweepAngle ).
Kodi: Tek forma Pie ekziston një hark dhe dy segmente të cilat i lidhin pikat e atij harku me
qendrën e rrethit apo elipsës. Metoda DrawPie i pranon si argumente objektin e tipit Pen me të
cilin do të vizatohet forma e objektit Pie, drejkendëshin në të cilin do të brendashkruhet objekti
Pie, këndin ku fillon harku dhe këndi ku përfundon harku. Këndet startuese dhe përfunduese të
harkut janë në drejtim të akrepave të orës.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace objekti_Pie { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Graphics grafika = this.CreateGraphics(); SolidBrush brusha = new SolidBrush(Color.Green); Rectangle drejtkendeshi = new Rectangle(50, 10, 200, 200); // definimi i vargut te kendeve startuese float[] Angles = { 0, 43, 79, 124, 169, 252, 331, 360 }; Color[] ngjyrat = {Color.Red, Color.Cornsilk, Color.Firebrick, Color.OliveDrab, Color.LawnGreen, Color.SandyBrown, Color.MidnightBlue}; grafika.Clear(Color.Ivory); int kendi; for (kendi = 1; kendi < Angles.Length; kendi++) {
Grafika kompjuterike
-109-
brusha.Color = ngjyrat[kendi-1]; // Angles[kendi-1] eshte kendi startues (start Angles) // Angles[kendi] - Angles[kendi-1] eshte kendi sweep
grafika.FillPie(brusha, drejtkendeshi, Angles[kendi-1], Angles[kendi] - Angles[kendi-1]);
} grafika.DrawEllipse(Pens.Black, drejtkendeshi); } } }
Rezultati ne ekran:
Shembull 18: Të shkruhet programi për regjistrim të studentëve përmes objektit Pie.
Kodi: 1. Dizajnimi i formes:
Grafika kompjuterike
-110-
Control Name Text
Label Regjistrimi / Drejtimi
______________
Label Kompjuterike
Label Telekomunikacion
Label Elektronike
TextBox txtKompjuterike 0
TextBox txtTelekomunikacion 0
TextBox txtElektronike 0
Button btnkrijoDiagram Krijo Diagram
PictureBox pboxDiagrami
Label --Legjenda--
Label lblKompjuterike Kompjuterike
Label lblTelekomunikacion Telekomunikacion
Label lblElektronike Elektronike
Button btnMbylle Mbylle
2. Me tastin e djathtë në Forme (Design) pastaj View Code 3. Deklarimi i variablave:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace pie_studentet { public partial class Form1 : Form { float Kompjuterike; float Telekomunikacion; float Elektronike; public Form1() { InitializeComponent(); } }
4. Duke u kthyer në Forme tek Events dhe duke klikuar ne Paint:
private void Form1_Paint(object sender, PaintEventArgs e) {
pboxDiagrami.CreateGraphics().DrawEllipse(new Pen(Color.Red), new Rectangle(0, 0, 260, 200));
pboxDiagrami.CreateGraphics().DrawPie(new Pen(Color.Blue), 0.0F, 0.0F, 260.0F, 200.0F, 0.0F, Kompjuterike);
pboxDiagrami.CreateGraphics().DrawPie(new Pen(Color.Green), 0.0F, 0.0F, 260.0F,200.0F, Kompjuterike, Telekomunikacion);
Grafika kompjuterike
-111-
pboxDiagrami.CreateGraphics().DrawPie(new Pen(Color.Fuchsia), 0.0F, 0.0F, 260.0F,200.0F, Kompjuterike + Telekomunikacion, Elektronike);
e.Graphics.DrawEllipse(new Pen(Color.Blue), new Rectangle(lblKompjuterike.Left, lblKompjuterike.Top + 20, lblTelekomunikacion.Width, 20));
e.Graphics.DrawEllipse(new Pen(Color.Green), new Rectangle(lblTelekomunikacion.Left, lblTelekomunikacion.Top + 20, lblTelekomunikacion.Width, 20));
e.Graphics.DrawEllipse(new Pen(Color.Fuchsia), new Rectangle(lblElektronike.Left, lblElektronike.Top + 20, lblTelekomunikacion.Width, 20));
}
5. Ne Form design tek kontrola PictureBox, ne Events dhe Paint: private void pboxDiagrami_Paint(object sender, PaintEventArgs e) { Invalidate(); }
6. Klikohet në butonin Krijo Diagram dhe gjenerohet:
private void btnkrijoDiagram_Click(object sender, EventArgs e) { float komp = 0.00F, telekom = 0.00F, elekt = 0.00F, totali = 0.00F; float perqindjaKompjuterike, perqindjaTelekomunikacion, perqindjaElektronike; try { komp = float.Parse(txtKompjuterike.Text); } catch (FormatException) { MessageBox.Show("Vlera gabim"); } try { telekom = float.Parse(txtTelekomunikacion.Text); } catch (FormatException) { MessageBox.Show("Vlera gabim"); } try { elekt = float.Parse(txtElektronike.Text); } catch (FormatException)
Grafika kompjuterike
-112-
{ MessageBox.Show("Vlera gabim"); } totali = komp + telekom + elekt; perqindjaKompjuterike = (komp / totali) * 100; perqindjaTelekomunikacion = (telekom / totali) * 100; perqindjaElektronike = (elekt / totali) * 100; Kompjuterike = (360 * perqindjaKompjuterike) / 100; Telekomunikacion = (360 * perqindjaTelekomunikacion) / 100; Elektronike = (360 * perqindjaElektronike) / 100; pboxDiagrami.Invalidate(); }
7. Klikohet ne butonin Mbylle dhe kodi:
private void btnMbylle_Click(object sender, EventArgs e) { Close(); }
Rezultati ne ekran
Shembull 19: Të krijohet diagrami “pie” me te dhena numerike në textbox-a.
Kodi: Janë përdor metodat: DrawPie, SolidBrush, FillPie të objektit Graphics.
1. Dizajnimi i Formes
Grafika kompjuterike
-113-
Control Name Text
Label vlera 1
Label vlera 2
Label vlera 3
Label vlera 4
TextBox textBox1 0
TextBox textBox2 0
TextBox textBox3 0
TextBox textBox4 0
Button button1 krijo Diagram
Button Pastro Pastro
2. Duke klikuar ne butonin krijo Diagram:
private void button1_Click(object sender, EventArgs e) { // int.Parse (metoda Parse) konverton tekstin ne numer te tipit int int i1 = int.Parse(textBox1.Text); int i2 = int.Parse(textBox2.Text); int i3 = int.Parse(textBox3.Text); int i4 = int.Parse(textBox4.Text);
// shuma e shkalleve te çdo regjioni te objektit "pie" dhe shumezohet me 360 shkalle
float total = i1 + i2 + i3 + i4; float shkalla1 = (i1 / total) * 360; float shkalla2 = (i2 / total) * 360; float shkalla3 = (i3 / total) * 360; float shkalla4 = (i4 / total) * 360; // vizatimi i vijave (te jashtme dhe te brendshme) te diagramit Pen lapsi = new Pen(Color.Black, 2); Graphics g = this.CreateGraphics();
Rectangle drejt = new Rectangle(textBox1.Location.X + textBox1.Size.Width + 10, 12, 150, 150);
Brush brusha1 = new SolidBrush(Color.Red); Brush brusha2 = new SolidBrush(Color.Blue);
Grafika kompjuterike
-114-
Brush brusha3 = new SolidBrush(Color.Black); Brush brusha4 = new SolidBrush(Color.BlueViolet); g.DrawPie(lapsi, drejt, 0, shkalla1); g.FillPie(brusha1, drejt, 0, shkalla1); g.DrawPie(lapsi, drejt, shkalla1, shkalla2); g.FillPie(brusha2, drejt, shkalla1, shkalla2); g.DrawPie(lapsi, drejt, shkalla2 + shkalla1, shkalla3); g.FillPie(brusha3, drejt, shkalla2 + shkalla1, shkalla3); g.DrawPie(lapsi, drejt, shkalla3 + shkalla2 + shkalla1, shkalla4); g.FillPie(brusha4, drejt, shkalla3 + shkalla2 + shkalla1, shkalla4); }
3. Mbi butonin Pastro ne Forme klikojme dy here dhe shkruajme kodin per pastrimin e textbox-ave:
private void Pastro_Click(object sender, EventArgs e) { pastro_textbox(this.Controls); } // kjo metode perdoret per fshirjen e te dhenave ne textbox-a private void pastro_textbox(Control.ControlCollection c) { foreach (Control kontroll in c) { TextBox tb = kontroll as TextBox; // nese textbox-at nuk jane zero (kane te dhena/numra) if (tb != null) tb.Clear(); else pastro_textbox(kontroll.Controls); } }
Rezultati ne ekran:
Grafika kompjuterike
-115-
Shembull 20: Të shkruhet programi me disa lloje artikujsh të dhënë në përqindje përmes
objektit Pie.
Kodi: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace _pie { public partial class Form1 : Form { public Form1() { InitializeComponent(); } struct diagramiPie { public string artikujt; public float perqindja; public Color ngjyra; public diagramiPie(string a, float p, Color c) { artikujt = a; perqindja = p; ngjyra = c; } }; private Pen lapsi = new Pen(Color.Red); private diagramiPie[] formaPie = { new diagramiPie("pije freskuese", 20, Color.Red), new diagramiPie("pije alkoolike", 15, Color.BlueViolet), new diagramiPie("artikuj higjienik", 35, Color.Green), new diagramiPie("artikuj ushqimor", 15, Color.YellowGreen), new diagramiPie("artikuj per femije", (float) 7.5, Color.Tomato), new diagramiPie("artikuj tjere", (float) 7.5, Color.Orange) }; int numri_artikujve = 6; private void Form1_Paint(object sender, PaintEventArgs e) { // deklarimi i variables se perqindjes float perqindja1 = 0; float perqindja2 = 0; // rrezhja e diagramit 75 float rrezja = 75; // pozita e diagrameve ne koordinatat x dhe y: (90, 150)
Grafika kompjuterike
-116-
int xCenter = 80, yCenter = 140; Graphics grafika = this.CreateGraphics(); // kordinatat e diagramit pie float x = xCenter - rrezja; float y = yCenter - rrezja; float gjeresia = rrezja * 2; float lartesia = rrezja * 2; for (int i = 0; i < numri_artikujve; i++) { if (i >= 1) perqindja1 = perqindja1 + formaPie[i - 1].perqindja; perqindja2 = perqindja2 + formaPie[i].perqindja; float kendi1 = perqindja1 / 100 * 360; float kendi2 = perqindja2 / 100 * 360; Brush brusha = new SolidBrush(formaPie[i].ngjyra);
grafika.FillPie(brusha, x, y, gjeresia, lartesia, kendi1, kendi2 - kendi1);
} // krijimi i objektit per lapsin (ngjyre te zeze) lapsi.Color = Color.Black; // vizatimi i elipses me kordinata grafika.DrawEllipse(lapsi, x, y, gjeresia, lartesia);
// koordinatat e listes se artikujve me perqindje (distanca nga diagrami)
float xpozita = x + gjeresia + 20; float ypozita = y - 25; // unaza per drjetkendeshat e vegjel te artikujve for (int k = 0; k < numri_artikujve; k++) { // objekti brush per drejtkendeshat e vegjel te artikujve Brush b = new SolidBrush(formaPie[k].ngjyra); // mbushja e drejtkendshave te listuar dhe pozita e tyre grafika.FillRectangle(b, xpozita, ypozita, 30, 30); // vizatimi i drejtkendshave te listes se artikujve grafika.DrawRectangle(lapsi, xpozita, ypozita, 30, 30); // ngjyra e tekstit te listes se artikujve Brush b2 = new SolidBrush(Color.Black); /*formaPie[k].artikujt gjeneron emrat e artikujve; formaPie[k].perqindja.ToString() paraqet numrat ne perqindje */
grafika.DrawString(formaPie[k].artikujt + ": " + formaPie[k].perqindja.ToString() + "%", Font, b2, xpozita + 35, ypozita + 12);
// distanca me listes se artikujve (ne kete rast 35) ypozita = ypozita + 35; } } } }
Grafika kompjuterike
-117-
Rezultati ne ekran:
Shembull 21: Të vizatohet një formë e harkut përmes objektit Arc.
Shënim: Harku “arc” është një pjesë ose segment i një elipse. Po ashtu mund të vendoset
brenda kornizave të drejtkëndeshit.
Metoda DrawArc (lapsi, drejtkendeshi, startAngle, sweepAngle);
Kodi: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace objekti_Arc { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_ Click(object sender, EventArgs e)
Grafika kompjuterike
-118-
{ Graphics grafika = this.CreateGraphics(); Pen lapsi = new Pen(Color.Black); //DrawArc(lapsi, drejtkendeshi, startAngle, sweepAngle) grafika.DrawArc(lapsi, 20, 20, 200, 150, 220, 200); } } } Apo private void button1_Click(object sender, EventArgs e) { Graphics grafika = this.CreateGraphics(); Pen lapsi = new Pen(Color.Black); Rectangle drejtkendeshi = new Rectangle(20, 20, 200, 150); float startAngle = 220.0F; //krijimi I kendeve (start dhe sweep). float sweepAngle = 200.0F; grafika.DrawArc(lapsi, drejtkendeshi, startAngle, sweepAngle); }
Rezultati ne ekran:
Shembull 22: Të vizatohet lakorja e cila kalon nëpër katër pika me koordinatat (20, 50), (220,
190), (330, 80) dhe (450, 280) duke përdor objektin DrawCurve.
Kodi: Lakorja duhet të kaloj nëpër pikat me koordinata të caktuara dhe tension (lakueshmëri të
definuar). Nëse tensioni është 0, lakorja është më fleksibile, ndërsa sa më i madh që është
tensioni, atëherë lakorja është më e lemueshme.
DrawCurve (laspi, pikat, tensioni)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace drawCurve {
Grafika kompjuterike
-119-
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Graphics g = this.CreateGraphics(); // smoothingMode eshte veti per lemueshmeri te lakores g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; // vargu i 4 pikave me koordinata Point[] pikat = { new Point(20, 50), new Point(220, 190), new Point(330, 80), new Point(450, 280) }; // kater pikat neper te cilat kalon lakorja g.DrawCurve(Pens.Blue, pikat, 0.1f); // 0.1f tensioni (lakueshmeria) g.DrawCurve(Pens.Red, pikat, 0.5f); g.DrawCurve(Pens.Green, pikat, 1f); g.DrawCurve(Pens.Black, pikat, 2f); } } }
Rezultati ne ekran:
Shembull 23: Të vizatohet lakorja e mbyllur (pika e fillimit të bashkohet me pikën e fundit) e
cila kalon nëpër katër pikat me koordinata: (40, 42), (188, 246), (484, 192) dhe (350, 48) duke
perdor objektin DrawClosedCurve.
Kodi: Këtu përdoret numeratori FillMode, i cila ka dy atribute: Alternate dhe Winding për
mbushje të brendisë së lakores.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing;
Grafika kompjuterike
-120-
using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace drawCurveClosed { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Pen lapsi = new Pen(Color.Red); // vargu (array) i pikave me koordinata Point[] pikat = { new Point(40, 42), new Point(188, 246), new Point(484, 192), new Point(350, 48)}; // DrawClosedCurve bashkon piken e fillimit dhe mbarimit // 0.5F eshte tensioni; FillMode tregon se si mbushet brendia e lakores e.Graphics.DrawClosedCurve(lapsi, pikat, 0.5F, FillMode.Winding); } } }
Rezultati ne ekran:
Shembull 24:Të shkruhet kodi duke perdor metoden DrawBezier me dy pikat e fundit dhe dy
pikat kontrolluese.
Shënim: Metoda DrawBezier vizaton lakore të Bezierit, të cilat janë më të lëmuara se
lakoret të cilat vizatohen me metodën DrawCurve.
Në këtë shembull lakorja e Bezierit definohet me dy pika të fundit dhe dy pika kontrolluese.
Pikat kontrolluese do të sillen si magnetë. Kjo metodë si parametër hyrës pranon një objekt të
tipit Pen dhe katër parametrat tjerë janë objekte të tipit Point.
Grafika kompjuterike
-121-
DrawBezier(lapsi, pikat)
Kodi: Pikat me koordinata P1(120, 150), P2(220, 90), P3(330, 30) dhe P4(410, 110). Pikat e
fundit te lakores jane P1 dhe P4, ndersa pikat kontrolluese jane P2 dhe P3. Pika kontrolluese e
cila levizë në koordinata në këtë rast është pika P3. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace DrawBezier { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { /* definimi i kater piakve me koordinata P1 dhe P4 jane pikat e fundit ndersa P2 dhe P3 pikat kontrolluese */ Point P1 = new Point(120, 150); Point P2 = new Point(220, 90); Point P3 = new Point(330, 30); Point P4 = new Point(410, 110); Graphics G = this.CreateGraphics(); G.DrawBezier(new Pen(Color.Blue), P1, P2, P3, P4); // levizja me koordinata tjera e pikes kontrolluese P3 P3 = new Point(330, 230); G.DrawBezier(new Pen(Color.Red), P1, P2, P3, P4); P3 = new Point(330, 330); G.DrawBezier(new Pen(Color.Green), P1, P2, P3, P4); } } }
Grafika kompjuterike
-122-
Rezultati ne ekran:
Shembull 25: Të vizatohet lakorja përmes metodës DrawBeziers nëpër shtatë pika.
Kodi: Ne Forme tek Events dhe klikohet ne Paint.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace DrawBeziers { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Pen lapsi = new Pen(Color.Red); Point[] pikat = { new Point( 10, 5), new Point(340, 60), new Point(320, 148), new Point(150, 120), new Point(24, 220), new Point(250, 150), new Point(304, 240) }; e.Graphics.DrawBeziers(lapsi, pikat); } } }
Rezultati ne ekran:
Grafika kompjuterike
-123-
Shembull 26: Të vendoset një imazh në Form:
Kodi: Krijohet pictureBox1 dhe pastaj caktohet lokacioni i imazhit / fotos. Fotoja mund të jetë
në formatin .jpg, .png etj.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace foto { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { pictureBox1.ImageLocation = "F:\\foto.jpg"; pictureBox1.SizeMode = PictureBoxSizeMode.Zoom; } } }
Shembull 27: Të merret një objekt bitmap nga imazhi dhe pastaj të vendoset teksti në imazh.
Kodi:
Në Forme vendosim një kontrol PictureBox (me emrin pictureBox1).
Rezultati ne ekran:
Grafika kompjuterike
-124-
Duke selektuar në Forme, pastaj në Event-in Paint kemi:
private void Form1_Paint(object sender, PaintEventArgs e) { // krijimi i objektit bitmap nga imazhi (lule.jpg) Bitmap bitmap = new Bitmap("F:\\lule.jpg"); // krijimi i objektit Graphics nga bitmap-i Graphics g = Graphics.FromImage(bitmap); // StringFormat klasa perdoret per formatim te tekstit StringFormat formati = new StringFormat(); // Vetia Alignment bene rreshtimin e tekstit horizontalisht formati.Alignment = StringAlignment.Center; // Vetia LineAlignment per rreshtim vertikal formati.LineAlignment = StringAlignment.Center;
g.DrawString("Grafika\nKompjuterike", new Font("Arial", 30), Brushes.Black, new RectangleF(0, 0, 300, 300), formati);
pictureBox1.Image = bitmap; }
Rezultati ne ekran:
Shembull 28: Të shkruhet teksti “Grafika Kompjuterike” duke shfrytëzuar objekte të grafikes.
Kodi
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace grafika_tekst { public partial class Form1 : Form { public Form1()
Grafika kompjuterike
-125-
{ InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { e.Graphics.TranslateTransform(50, 50); // kendi i tekstin (ne kete rast 45 shkalle) e.Graphics.RotateTransform(45); // metoda DrawString per tekst e.Graphics.DrawString("Grafika Kompjuterike", new Font("Arial", 20), Brushes.Blue, new Point(0, 0), StringFormat.GenericDefault); } } }
Rezultati ne ekran:
Shembull 29: Të shkruhet kodi për dy vija, ku vija valore është mbi vijen e drejt.
Kodi: Së pari vendosim kontrollen pictureBox1 në Forme. Duhet shtuar namespace-in using System.Drawing.Drawing2D; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace grafika_vijat { public partial class Form1 : Form
Grafika kompjuterike
-126-
{ public Form1() { InitializeComponent(); } private void pictureBox1_Paint(object sender, PaintEventArgs e) { // vetia SmoothingMode per "zbutje" e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; // PointF paraqet nje qift te renditur te pikave float PointF[] pikat = new PointF[] { new PointF(50,50), new PointF(150,50), new PointF(200,100), new PointF(200,200), }; e.Graphics.DrawLines(Pens.Red, pikat); List<PointF> listaPikave = new List<PointF>(); float distanca1 = 0; float distanca2 = 0; for (int i = 0; i < pikat.Length - 1; i++) { PointF pikaA = pikat[i]; PointF pikaB = pikat[i + 1]; float vleraX = pikaB.X - pikaA.X; float vleraY = pikaB.Y - pikaA.Y; distanca1 = 0; distanca2 =(float)Math.Sqrt(Math.Pow(vleraX, 2)+Math.Pow(vleraY, 2)); while (distanca1 < distanca2) { distanca1++;
float pozitaX = (float)((double)distanca1 / (double)distanca2 * (double)vleraX); float pozitaY = (float)((double)distanca1 / (double)distanca2 * (double)vleraY); listaPikave.Add(new PointF(pikaA.X + pozitaX, pikaA.Y + pozitaY));
} } for (int i = 0; i < listaPikave.Count - 24; i = i + 24) {
drawWaveLine(e.Graphics, Pens.Blue, listaPikave[i].X, listaPikave[i].Y, listaPikave[i + 24].X, listaPikave[i + 24].Y);
} } // metoda drawWaveLine per vizatim te vijave valore
public void drawWaveLine(Graphics g, Pen lapsi, float x1, float y1, float x2, float y2)
{ // Math.Atan2 eshte Arctangjenti i dy numrave
Grafika kompjuterike
-127-
float angle = (float)((Math.Atan2(y2 - y1, x2 - x1) * 180 / 3.14159265)); g.TranslateTransform(x1, y1); g.RotateTransform(angle); GraphicsPath gp1 = new GraphicsPath(); Point[] p1 = new Point[] { new Point(0,0), new Point(3,-3), new Point(6,-4), new Point(9,-3), new Point(12,0), new Point(15,3), new Point(18,4), new Point(21,3), new Point(24,0) }; g.DrawLines(lapsi, p1); g.RotateTransform(-angle); g.TranslateTransform(-x1, -y1); } } }
Rezultati ne ekran:
GRADIENTI
Shembull 30: Të paraqitet gradienti linear.
Kodi: Gradientet jane të implementuara si brushat, ku për të shfrytëzuar një gradient duhet
krijuar një brushë me ngjyrë të caktuar.
LinearGradientBrush(rect, startColor, endColor, gradientMode);
rect - paraqet drejtkëndeshin ku vizatohet gradienti,
startColor - ngjyren fillestare të gradientit,
endColor - ngjyren e fundit të gradientit,
gradientMode – specifikon drejtimin e gradientit dhe mund të jetë:
Grafika kompjuterike
-128-
BackwardDiagonal - gradienti e mbush drejtkëndëshin në formë diagonale prej skajit të
epërm të djathtë (startColor) në skajin e poshtëm të majtë (endColor),
ForwardDiagonal - gradienti e mbush drejtkëndëshin në formë diagonale, prej skajit të
epërm të majtë (startColor) në skajin e poshtëm të djathtë (endColor),
Horizontal - gradienti e mbush drejtkëndëshin nga ana e majtë (startColor) në anën e
djathtë (endColor)
Vertical - gradienti e mbush drejtkëndëshin nga pjesa e epërme (startColor) në pjesën e
poshtme (endColor).
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace gradienti_linear { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Graphics grafika = this.CreateGraphics(); Rectangle drejtkendeshi = new Rectangle(20, 20, 300, 100); Color startColor = Color.Red; Color endColor = Color.Yellow; // krijimi i objektit LinearGradientBrush LinearGradientBrush glBrusha;
// krijimi i gradientit per mbushjen e drejtkendeshit (gjatesine e gradientit) glBrusha = new LinearGradientBrush(drejtkendeshi, startColor, endColor, LinearGradientMode.Horizontal);
grafika.FillRectangle(glBrusha, new Rectangle(20, 20, 200, 100)); grafika.FillRectangle(glBrusha, new Rectangle(20, 150, 600, 100)); } } }
Grafika kompjuterike
-129-
Rezultati ne ekran:
Shembull 31: Të paraqitet gradienti i shtegut.
Kodi: Gradienti i shtegut krijon gradientin që fillon në një pikë të caktuar dhe që zbehet në
ngjyra tjera në drejtime të ndryshme. Për t’a mbushur një objekt me gradient të shtegut, së pari
duhet krijuar një shteg.
Gradienti i shtegut mund të aplikohet vetëm për një shteg të caktuar, e jo për objekte tjera.
Së pari duhet specifikuar ngjyrën e gradientit në qendër të formës, duke e shfrytëzuar
vetinë (property) CenterColor.
Vetia SurroundColors është një varg i cili përmban aq elemente sa ka kulme në objektin
path. Çdo elementi të vargut duhet bashkangjitur një ngjyrë dhe gradienti resultues do të ketë
kombinimin e ngjyrave të elementeve të vargut SurroundColor.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace gradienti_shtegut { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) {
Grafika kompjuterike
-130-
Graphics g = this.CreateGraphics(); GraphicsPath shtegu = new GraphicsPath();
/* path.AddLine bene shtimin e vijave te segmentit ne objektin GraphicsPath. Segmenti vije lidhe piken e fundit ne shteg me piken e pare te vijes se re te segmentit. Pika e pare paraqet piken e fillimit te segmentit, ndersa pika e dyte paraqet piken e fundit te vijes */
shtegu.AddLine(new Point(10, 10), new Point(400, 10)); shtegu.AddLine(new Point(400, 10), new Point(400, 250)); shtegu.AddLine(new Point(400, 250), new Point(10, 250)); PathGradientBrush brushaShtegut = new PathGradientBrush(shtegu); /* objekti brushaShtegut percakton se si mbushet objekti me ngjyra, CenterColor percakton ngjyren ne mes te formes, ne kete raste kuqe */ brushaShtegut.CenterColor = Color.Red;
// Vetia surroundColor eshte varg me elemente po aq sa ka kulme te objektit path Color[] surroundNgjyra = {Color.Yellow, Color.Green, Color.Blue, Color.Cyan};
brushaShtegut.SurroundColors = surroundNgjyra; g.FillPath(brushaShtegut, shtegu); } } }
Rezultati ne ekran:
Shembull 32: Të paraqitet trekendëshi i mbushur me brushen e gradientit të shtegut.
Kodi: Krijimi i gradientit të shtegut i bazuar në trekendësh. Nga lëvizja prej kufijve të
trekendëshit drejt qendres ngjyrat ndryshohen gradualisht nga e gjelberta e errët në aqua dhe
prej aqua në ngjyrë të kaltërt.
Në ketë rast përdoret sistemi i ngjyrave ARGB, ku A- Alpha, merr vlerat prej 0 (me mbushje
transparente) deri ne 255 (plotësisht e erret); R- Red, me vlerat (0 deri ne 255); G- Green, me
vlerat (0 deri ne 255); B- Blue, me vlerat (0 deri ne 255).
Grafika kompjuterike
-131-
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace gradienti_1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { // Pikat e trekendeshit te jashtem Point[] pikat = { new Point(100, 0), new Point(200, 200), new Point(0, 200) }; // Objekti PathGradientBrush krijohet nga vargu i pikave PathGradientBrush brushaGrShtegut = new PathGradientBrush(pikat); Color[] ngjyrat = { //Color.FromArgb(255, 255, 0, 0), e kuqe Color.FromArgb(255, 0, 128, 0), // e gjelbert e erret Color.FromArgb(255, 0, 255, 255), // aqua Color.FromArgb(255, 0, 0, 255) // e kaltert }; float[] pozitat = {
0f, // ngjyra e gjelbert e erret ne kufijte e trekendeshit. 0.4f, // ngjyra Aqua eshte 40 perqind me larg kufirit nga pika e qendres.
1.0f // ngjyra e kaltert eshte pika qendrore }; // klasa ColorBlend (perzierja e ngjyrave) ColorBlend ngjyrat_perziera = new ColorBlend(); ngjyrat_perziera.Colors = ngjyrat; ngjyrat_perziera.Positions = pozitat; //InterpolationColors per nderfutjen e ngjyrave brushaGrShtegut.InterpolationColors = ngjyrat_perziera;
/* mbushja e drejtkendeshit qe definohet ne vargun e pikave. Drejtkendeshi jashte trekendeshit nuk do te ngjyroset...*/
e.Graphics.FillRectangle(brushaGrShtegut, 0, 0, 200, 200); } } }
Grafika kompjuterike
-132-
Rezultati ne ekran:
Shembull 33: Të vizatohen elipsat dhe të mbushen me brushen për gradient të shtegut.
Kodi: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace gradienti_shtegut1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { // Krijimi i shtegut per nje elipse GraphicsPath shtegu = new GraphicsPath(); shtegu.AddEllipse(10, 10, 150, 150); // krijimi i brushes se gradientit te shtegut bazuar ne shtegun eliptik PathGradientBrush Brusha = new PathGradientBrush(shtegu); // percaktimi i ngjyres se gjelbert pergjate gjithe kufirit Color[] ngjyra = { Color.Green }; Brusha.SurroundColors = ngjyra; // percaktimi i ngjyres qendrore ne ngjyre ari (gold) Brusha.CenterColor = Color.Gold; // perdorimi i brushes se shtegut te gradientit per mbushje te elipses
Grafika kompjuterike
-133-
e.Graphics.FillPath(Brusha, shtegu);
//FocusScales specifikon shtegun e brendshem qe shtrihet ne brendi te shtegut kryesor
Brusha.FocusScales = new PointF(0.3f, 0.8f); e.Graphics.TranslateTransform(220.0f, 0.0f); // Elipsa e dyte e.Graphics.FillPath(Brusha, shtegu); } } }
Rezultati ne ekran:
Shembull 34: Të paraqitet gradienti linear në format vertikale, horizontale dhe diagonale.
Kodi: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace gradient_form { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics grafika = this.CreateGraphics(); Rectangle drejt = new Rectangle(10, 10, 100, 100); LinearGradientBrush brusha = null; int yPozita = 10; // pozita ne bosht
Grafika kompjuterike
-134-
/* Enum- numerimet; typeof- merr informacion per tipin, ne kete rast modin (drejtimin) e gradientit linear */ Array objekt = Enum.GetValues(typeof(LinearGradientMode)); for (int x = 0; x < objekt.Length; x++) { LinearGradientMode modi = (LinearGradientMode)objekt.GetValue(x); brusha = new LinearGradientBrush(drejt, Color.Blue, Color.Yellow, modi);
// vizatimi i tekstit (Horizontal, Vertical, ForewardDiagonal, BackwardDiagonal)
grafika.DrawString(modi.ToString(), new Font("Arial", 10), new SolidBrush(Color.Black), 0, yPozita); grafika.FillRectangle(brusha, 120, yPozita, 200, 50); yPozita += 80; // distanca mes drejtkendshave ne gradient } } } }
Rezultati ne ekran:
Shembull 35: Të shkruhet programi për ngjyrat në sistemin RGB. Në program të paraqiten
specifikat e ngjyrave si: brightness (shkelqimi), hue (ngjyrimi), saturation (ngopja) dhe
paraqitja në heksadecimal.
Kodi:
1. Dizajnimi i Formes
Grafika kompjuterike
-135-
Control Name Text
Buton button1 Ngjyrat
Label lblBrightness Brightness =
Label lblHue Hue =
Label lblSaturation Saturation =
Label lblRGBHex RGB =
Label Zgjidh Ngjyren:
ListBox listBox1
Panel panel1
2. Kodi using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace colorDialogu { public partial class Form1 : Form { ColorDialog dialoguNgjyrave = new ColorDialog(); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) {
Grafika kompjuterike
-136-
string[] emratNgjyrave = Enum.GetNames(typeof(KnownColor)); listBox1.Items.AddRange(emratNgjyrave); }
// Duke selektuar ne listBox1, pastaj ne Event me double klik SelectedIndexChanged
private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { // KnowColor numeron 174 ngjyra te paraqitura me emer.
KnownColor ngjyratEzgjedhura = (KnownColor)Enum.Parse(typeof(KnownColor), listBox1.Text);
panel1.BackColor = Color.FromKnownColor(ngjyratEzgjedhura); ColorInfo(); } private void button1_Click(object sender, EventArgs e) { dialoguNgjyrave.ShowDialog(); panel1.BackColor = dialoguNgjyrave.Color; ColorInfo(); } private void ColorInfo() { // Brightness - shkelqimi lblBrightness.Text = "Brightness = " + panel1.BackColor.GetBrightness(); // Hue - ngjyrimi lblHue.Text = "Hue = " + panel1.BackColor.GetHue().ToString(); // Saturation - ngopja
lblSaturation.Text = "Saturation = " + panel1.BackColor.GetSaturation().ToString();
//formatimi numerik i ngjyres ne heksadecimal string strRGBHex = string.Format("0x{0:X8}", panel1.BackColor.ToArgb()); strRGBHex = "RGB = #" + strRGBHex.Substring(strRGBHex.Length - 6, 6); lblRGBHex.Text = strRGBHex; //lblRGBHex.Text = strRGbValue; } } }
Grafika kompjuterike
-137-
Rezultati ne ekran:
Shembull 36: Të mbushet forma me drejtkendësha të nderthurur në mes veti dhe të mbushur
me ngjyrë.
Kodi: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace _RGB { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics grafika = this.CreateGraphics(); int x = 0; int y = 0; // unaza qe ka deri ne 255 vlera for (int i = 0; i <= 255; i++) { /* Argb -- A-Alpha (vlera implicite eshte 255 plotesisht e erret); r- red; g- green; b - blue; vlerat e ngjyrave prej 0 deri 255 */ Color ngjyra = Color.FromArgb(i, 0, 0); // brusha eshte solid sepse ashtu e kemi percaktuar ne drejtkendesh
Grafika kompjuterike
-138-
SolidBrush brusha = new SolidBrush(ngjyra); grafika.FillRectangle(brusha, x, y, 10, 10); // drejtkendeshi i radhes duhet te jete prane te fundit x = x + 10; // nese rreshti eshte kompletuar fillo ne nje te ri if ((x % 290) == 0) { y = y + 10; x = 0; } } for (int i = 0; i <= 255; i++) { Color ngjyra = Color.FromArgb(0, i, 0); SolidBrush brusha = new SolidBrush(ngjyra); grafika.FillRectangle(brusha, x, y, 10, 10); x = x + 10; if ((x % 290) == 0) { y = y + 10; x = 0; } } for (int i = 0; i <= 255; i++) { Color ngjyra = Color.FromArgb(0, 0, i); SolidBrush brusha = new SolidBrush(ngjyra); grafika.FillRectangle(brusha, x, y, 10, 10); x = x + 10; if ((x % 290) == 0) { y = y + 10; x = 0; } } } } }
Rezultati ne ekran:
Grafika kompjuterike
-139-
Shembull 37: Të vizatohen format (shapes) si me poshtë.
Kodi: Si namespace te shtohet using System.Drawing.Drawing2D;
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace draw_shapes { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics grafika = e.Graphics; Rectangle drejtkendesh = new Rectangle(5, 35, 30, 100); //Figura e pare: elipsa e mbushur
LinearGradientBrush brushaL = new LinearGradientBrush(drejtkendesh, Color.DarkViolet,
Color.Violet, LinearGradientMode.Horizontal); grafika.FillEllipse(brushaL, 5, 30, 65, 100); //Figura e dyte: drejtkendeshi Pen lapsi = new Pen(Color.Green, 4); Rectangle drejtkendesh2 = new Rectangle(80, 30, 65, 100); grafika.DrawRectangle(lapsi, drejtkendesh2); //Figura e trete: krijimi i bitmap-it Bitmap bitmap = new Bitmap(10, 10); Graphics grafika1 = Graphics.FromImage(bitmap); // marrja e bitmap-it SolidBrush brushaSolid = new SolidBrush(Color.Red); Pen lapsiNgjyre = new Pen(brushaSolid); // mbushja e formes se bitmap-it me ngjyre brushaSolid.Color = Color.Aqua; grafika1.FillRectangle(brushaSolid, 0, 0, 10, 10); // vizatimi i drejtkendeshave te vegjel ne formen e bitmap-it me ngjyre lapsiNgjyre.Color = Color.Black; grafika1.DrawRectangle(lapsiNgjyre, 1, 1, 6, 6); //mbushja e drejt. te vegjel ne formen e bitmap-it brushaSolid.Color = Color.Blue;
Grafika kompjuterike
-140-
grafika1.FillRectangle(brushaSolid, 1, 1, 3, 3); //mbushja e drejt. te vegjel ne formen e bitmap-it brushaSolid.Color = Color.Red; grafika1.FillRectangle(brushaSolid, 4, 4, 3, 3); // mbushja e brendise se formes TextureBrush brushaTxt = new TextureBrush(bitmap); grafika.FillRectangle(brushaTxt, 155, 30, 75, 100); //Figura e katert: vizatimi i harkut te formes pie me ngjyre lapsiNgjyre.Color = Color.RoyalBlue; lapsiNgjyre.Width = 5; grafika.DrawPie(lapsiNgjyre, 240, 30, 75, 100, 0, 270); //Figura e peste: vizatimi i vijave lapsiNgjyre.Color = Color.Red; lapsiNgjyre.Width = 5; grafika.DrawLine(lapsiNgjyre, 380, 30, 320, 140); lapsiNgjyre.Color = Color.Orange; lapsiNgjyre.DashCap = DashCap.Round; lapsiNgjyre.DashStyle = DashStyle.Dash; grafika.DrawLine(lapsiNgjyre, 320, 30, 380, 140); } } }
Rezultati ne ekran:
Grafika kompjuterike
-141-
Shembull 38: Të shkruhet kodi për vizatimin e flamurit të SHBA-ve duke përdor objekte të
grafikes.
Shënim:
Flamuri përmban 51 yje, që si objekt të grafikes për ti paraqitur yjet përdoret objekti Polygon.
Duhet nisur nga paraqitja ne aspektin gjeometrik të koordinatave të yllit, si në figurë:
Nga figura mund të zbërthehen koordinatat në aspektin tabelar:
Pikat Koordinatat X Koordinatat Y
0 Xc yc-r
1 xc + r1 sinβ yc – r1 cosβ
2 xc + r sinα yc – r cosα
3 xc + r1 sinα yc + r1 cosα
4 xc + r sinβ yc + r cosβ
5 Xc yc + r1
6 xc - r sinβ yc + r cosβ
7 xc - r1 sinα yc + r1 cosα
8 xc - r sinα yc - r cosα
9 xc - r1 sinβ yc - r1 cosβ
xc dhe yc janë koordinatat e qendrës së yllit,
r është rrezja e rrethit të jashtëm të yllit,
r1 është rrezja e rrethit të brendshëm të yllit,
α = 72 shkallë dhe β = 36 shkallë.
Kodi:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing;
Grafika kompjuterike
-142-
using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace USA { public partial class Form1 : Form { public Form1() { InitializeComponent(); } protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; // rritja e kualitetit te paraqitjes se flamurit g.SmoothingMode = SmoothingMode.AntiAlias; VizatoFlamur(g, 20, 20, this.Width - 50); g.Dispose(); } private void VizatoFlamur(Graphics g, float x0, float y0, float gjeresia) { SolidBrush brushaBardhe = new SolidBrush(Color.White); SolidBrush brushaKaltert = new SolidBrush(Color.FromArgb(0, 0, 128)); SolidBrush brushaKuqe = new SolidBrush(Color.Red); float lartesia = 10 * gjeresia / 20; // mbushja e drejtkendeshit me ngjyren e bardhe g.FillRectangle(brushaBardhe, x0, y0, gjeresia, lartesia); // mbushja me ngjyre te kuqe e shtate shiritave ne flamur for (int i = 0; i < 7; i++) {
g.FillRectangle(brushaKuqe, x0, y0 + 2 * i * lartesia / 13, gjeresia, lartesia / 13);
}
/* vizatimi i katrorit te kaltert, madhesia e te cilit mbulon 2/5 e gjeresise se flamurit dhe kater shiritat e eperm me ngjyre te kuqe */ RectangleF katroriKaltert = new RectangleF(x0, y0, 2 * gjeresia/5, 7 * lartesia/13);
g.FillRectangle(brushaKaltert, katroriKaltert);
/* vizatimi i 50 yllave ne katrorin e kaltert; ndarja e katrorit ne rrjet te katroreve 11 x 9 dhe vendosja e yllit ne cdo katror */
float pozita = katroriKaltert.Width / 40; float dx = (katroriKaltert.Width - 2 * pozita) / 11; float dy = (katroriKaltert.Height - 2 * pozita) / 9; for (int j = 0; j < 9; j++) { float yc = y0 + pozita + j * dy + dy / 2; for (int i = 0; i < 11; i++)
Grafika kompjuterike
-143-
{ float xc = x0 + pozita + i * dx + dx / 2; if ((i + j) % 2 == 0) { VizatoYll(g, this.Width / 55, xc, yc); } } } } /* Metoda VizatoYll vizaton nje poligon ylli ne poziten qendrore (xc, yc) dhe madhesi r (rrezja e rrethit te jashtem) */ private void VizatoYll(Graphics g, float r, float xc, float yc) { /* r: rrezja e rrethit te jashtem, percakton madhesine e yllit xc, yc : koordinatat e yllit (pika qendrore e poligonit ylli) α = 72 shkallle dhe β = 36 shkalle. */ float sin36 = (float)Math.Sin(36.0 * Math.PI / 180.0); float sin72 = (float)Math.Sin(72.0 * Math.PI / 180.0); float cos36 = (float)Math.Cos(36.0 * Math.PI / 180.0); float cos72 = (float)Math.Cos(72.0 * Math.PI / 180.0); float r1 = r * cos72 / cos36; //vizatimi i yllit neper dhjete pika (0-9) PointF[] pikat = new PointF[10]; pikat[0] = new PointF(xc, yc - r); pikat[1] = new PointF(xc + r1 * sin36, yc - r1 * cos36); pikat[2] = new PointF(xc + r * sin72, yc - r * cos72); pikat[3] = new PointF(xc + r1 * sin72, yc + r1 * cos72); pikat[4] = new PointF(xc + r * sin36, yc + r * cos36); pikat[5] = new PointF(xc, yc + r1); pikat[6] = new PointF(xc - r * sin36, yc + r * cos36); pikat[7] = new PointF(xc - r1 * sin72, yc + r1 * cos72); pikat[8] = new PointF(xc - r * sin72, yc - r * cos72); pikat[9] = new PointF(xc - r1 * sin36, yc - r1 * cos36); g.FillPolygon(Brushes.White, pikat); } } }
Rezultati ne ekran:
Grafika kompjuterike
-144-
ANIMACIONET NË C#
Shembull 1: Të shkruhet programi për vizatim të lirë me laps.
Kodi: Në Forme krijojmë një kontrol Panel (nga Toolbox-i) me emrin panel1, pastaj dy
butona (në ketë rast me emrat Clear dhe Exit).
-Të butoni exit duke selektuar dhe ne event-in Click shënojme tekstin (në ketë rast)
btnExitClick.
- Te butoni clear duke selektuar dhe në event-in në Click shenojme tekstin (ne kete shembull)
btnClearClick dhe klikohet dy herë në të.
-Te kontrola Panel (me emrin panel1) te event-i MouseUp me tekstin panel1_MouseUp.
Në MouseDown (në ketë rast) me emrin panel1_MouseDown, pastaj ne MouseMove me
tekstin panel1.
- Për ta vendos ngjyrën e bardhë në Panel, duke selektuar në të, pastaj në Properties dhe në
vetinë BackColor zgjedhim ngjyrën White.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace animation_1 { public partial class Form1 : Form { bool paint = false; SolidBrush color; public Form1() { InitializeComponent(); } private void btnExitClick(object sender, EventArgs e) { this.Close(); } private void btnClearClick(object sender, EventArgs e) { Graphics g1 = panel1.CreateGraphics(); g1.Clear(panel1.BackColor); } private void panel1_MouseUp(object sender, MouseEventArgs e)
Grafika kompjuterike
-145-
{ paint = false; } private void panel1_MouseDown(object sender, MouseEventArgs e) { paint = true; } private void panel1_MouseMove(object sender, MouseEventArgs e) { if (paint) // njejte sikur if(paint == true) { // formatimi I tekstit me ngjyre te kuqe color = new SolidBrush(Color.Red); Graphics g = panel1.CreateGraphics(); //e eshte mausi, ku e.X pozita ne boshtin X, ndersa e.Y pozita ne Y g.FillEllipse(color, e.X, e.Y, 10, 10); g.Dispose(); } } } }
Rezultati ne ekran:
Grafika kompjuterike
-146-
Shembull 2: Të krijohet programi i cili vë në lëvizje objektin (elipse).
Kodi:
Në Forme shtohet një buton (me emrin button1) using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace animation_ball { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private int x = 50, y = 50; private void button1_Click_1(object sender, EventArgs e) { x += 15; // x = x + 15 y += 10; // y = y + 10 Invalidate(); // } protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; Brush red = new SolidBrush(Color.Red); // vizatimi i elipses me ngjyre te kuqe dhe dimensione (50, 50) g.FillEllipse(red, x, y, 50, 50); base.OnPaint(e); } } }
Rezultati ne ekran:
Grafika kompjuterike
-147-
Shembull 3: Të krijohet programi për animacionin e dhënë në figurën e mëposhtme.
Kodi: Hapat në kod:
a) Krijimi i dy labelave: labela Piket (Name: label1) dhe labela 0 (Name: piketLabel);
b) Duke selektuar në Forme, pastaj në Events tek Paint (Form1_Paint) dhe tek MouseDown (Form1_MouseDown);
c) Duke klikuar me tastin e djathte mbi emrin e projektit në Solution Explorer, në ketë rast emri i projektit anim_piket -> Properties -> Resources -> Add Resource -> Add Existing File… ku bashkangjitet imazhi me ekstension p.sh .jpg, në ketë rast është me emrin buton.jpg
d) Në Forme vendoset Timer - i (nga ToolBox-i.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace anim_piket { public partial class Form1 : Form { private Rectangle figura = new Rectangle(0, 0, 60, 60); private Random random = new Random(); private int piket = 0; public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { vizatoButon(e.Graphics); } private void Form1_MouseDown(object sender, MouseEventArgs e) { int diffx = e.X - figura.X; int diffy = e.Y - figura.Y; // Math.Sqrt funksioni per rrenjen katrore double diff = Math.Sqrt(diffx * diffx - diffy * diffy); if (diff < 40) { // rritja e pikeve per nje piket = piket + 1; // labela e pikave
Grafika kompjuterike
-148-
piketLabel.Text = piket.ToString(); } } private void vizatoButon(Graphics paper) {
// levizja e figures (ne kete rast butonit ne koordinatat x dhe y ne menyre random
figura.X = random.Next(240); figura.Y = random.Next(240); // anim_piket eshte emri i projektit te krijuar // buton eshte emri i figures qe gjendet ne Resources te formes paper.DrawImage(anim_piket.Properties.Resources.buton, figura); } private void timer1_Tick(object sender, EventArgs e) { this.Invalidate(); } } }
Rezultati ne ekran:
Shembull 4: Animacioni i tekstit “ Grafika Kompjuterike” në Forme:
Kodi:
Së pari në Forme vendoset kontrolla Timer dhe në Properties caktohen parametrat:
Enabled True
Interval 50
(Name) TimerAnimacion.
Duhet klikuar dy here ne Timer dhe duhet gjeneruar kodin brenda metodes: private void TimerAnimacion_Tick(object sender, EventArgs e) {…kodi…} using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D;
Grafika kompjuterike
-149-
using System.Linq; using System.Text; using System.Windows.Forms; namespace anim_test { public partial class Form1 : Form { public Form1() { InitializeComponent(); } protected int GradientiAktual = 10; protected int GradientiHapit = 5; private void TimerAnimacion_Tick(object sender, EventArgs e) { Graphics g = CreateGraphics();
Font font = new Font("Microsoft Sans Serif", 24, FontStyle.Bold, GraphicsUnit.Point);
string tekst = "Grafika Kompjuterike!"; SizeF madhesiaTekstit = new SizeF(g.MeasureString(tekst, font)); // pozita e tekstit ne zonen e klientit
PointF pozitaTekstit = new PointF(Convert.ToSingle(ClientSize.Width - madhesiaTekstit.Width) / 2,
Convert.ToSingle(ClientSize.Height - madhesiaTekstit.Height) / 2); // Fillimi dhe fundi i pikes se gradientit PointF fillimiGradientit = new PointF(0, 0); PointF fundiGradientit = new PointF(GradientiAktual, 200); // brusha per vizatimin e tekstit LinearGradientBrush brusha = new LinearGradientBrush(fillimiGradientit, fundiGradientit, Color.Blue, BackColor); // vizatimi i tekstit ne qender te zones g.DrawString(tekst, font, brusha, pozitaTekstit); GradientiAktual = GradientiAktual + GradientiHapit; if (GradientiAktual == 500) { GradientiHapit = -5; } else if (GradientiAktual == -50) { GradientiHapit = 5; } } } }
Grafika kompjuterike
-150-
Rezultati ne ekran:
Shembull 5: Të shkruhet programi për animacion për mbushje të progresbar-it.
Kodi:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace animacion_1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } int Total = 100; int Current = 100; bool adding = false; Rectangle progressbar = new Rectangle(20, 20, 200, 40); Graphics gr; Timer t = new Timer(); public int percent(double total, double current) { return (int)((current / total) * 100); } public void drawBar(Brush color) { gr = CreateGraphics(); gr.FillRectangle(Brushes.White, progressbar); gr.DrawRectangle(new Pen(color), progressbar);
Grafika kompjuterike
-151-
gr.FillRectangle(color, new Rectangle(progressbar.X, progressbar.Y, (progressbar.Width * (percent(Total, Current))) / 100, progressbar.Height));
} private void Form1_Load(object sender, EventArgs e) { t.Interval = 10; t.Tick += new EventHandler(t_tick); t.Start(); } void t_tick(object sender, EventArgs e) { if (adding) { if (Current < Total) { Current++; } if (Current == 100) { adding = false; } } else { if (Current > 1) { Current--; } if (Current == 1) { adding = true; } } drawBar(Brushes.Red); } } }
Rezultati ne ekran:
Grafika kompjuterike
-152-
Shembull 6: Animacion i nje butoni permes WPF (Windows Presentation Foundation)
aplikacionit.
Kodi:
Hapat: 1. New Project WPF Aplication Name (emri i projektit) OK. 2. Në MainWindow përmes toolbox-it vendosim një buton (me emrin button1). 3. Duhet shtuar Namespace-in using System.Windows.Media.Animation;
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WPF_animation1 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { DoubleAnimation animacion = new DoubleAnimation(); animacion.From = 50; animacion.To = 200; // Autoreversee kthen formen e butonit ne gjendjen e meparshme animacion.AutoReverse = true; // Funksioni RepeatBehavvior nuk e ndal animacionin asnjehere animacion.RepeatBehavior = RepeatBehavior.Forever; // Koha per animacion te butonit, ne kete rast 1 sekond animacion.Duration = new Duration(TimeSpan.FromSeconds(1)); button1.BeginAnimation(Button.HeightProperty, animacion); } } }
Grafika kompjuterike
-153-
Rezultati ne ekran:
Shembull 7: Animacioni i rrotullimit të një drejtkëndeshi përmes WPF (Windows Presentation
Foundation) aplikacionit.
Kodi:
Hapat: 1. New Project WPF Aplication Name (emri i projektit) OK. 2. Në MainWindow përmes toolbox-it vendosim një buton (me emrin button1). 3. Në MainWindow vendosim një kontrollë Rectangle (me emrin rectangle1). Për të mbushur me
ngjyrë drejtkëndeshit duhet shkuar në Properties Brushes Fill në ketë rast ngjyra Blue. 4. Duhet shtuar Namespace-in using System.Windows.Media.Animation;
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WPF_anim2 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { DoubleAnimation animacion = new DoubleAnimation(); animacion.From = 0;
Grafika kompjuterike
-154-
animacion.To = 360; // rrotullimi deri ne 360 shkallle // koha per rrotullim, ne kete rast dy sekonda animacion.Duration = new Duration(TimeSpan.FromSeconds(2)); //...Funksioni RepeatBehavvior nuk e ndal animacionin asnjehere animacion.RepeatBehavior = RepeatBehavior.Forever; RotateTransform rrotullimi = new RotateTransform(); rectangle1.RenderTransform = rrotullimi; rrotullimi.BeginAnimation(RotateTransform.AngleProperty, animacion); } } }
Rezultati ne ekran:
Shembull 8: Animacioni i rrotullimit të rrotës përmes WPF (Windows Presentation
Foundation) aplikacionit.
Kodi:
Hapat: 1. New Project WPF Aplication Name (emri i projektit) OK. 2. Në MainWindow përmes toolbox-it vendosim një image (me emrin image1), pastaj bashkëngjesim
foton (.jpeg) në Properties Source Add zgjedhim lokacionin e fotos. 3. Duhet shtuar Namespace-in using System.Windows.Media.Animation;
4. Për të shënuar kodin, selektojme ne MainWindow dhe duke klikuar dy here.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WPF_rrota
Grafika kompjuterike
-155-
{ public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { DoubleAnimation animacion = new DoubleAnimation(); animacion.From = 0; animacion.To = 360; animacion.Duration = new Duration(TimeSpan.FromSeconds(2)); RotateTransform rrotullimi = new RotateTransform(); image1.RenderTransform = rrotullimi; // rrotullimi i imazhit rreth pikes se origjines (0.5, 0.5) image1.RenderTransformOrigin = new Point(0.5, 0.5); animacion.RepeatBehavior = RepeatBehavior.Forever; rrotullimi.BeginAnimation(RotateTransform.AngleProperty, animacion); } } }
Rezultati ne ekran:
Grafika kompjuterike
-156-
Përmbajtja
HYRJE 2
Programet aplikative për CAD dhe dokumentim teknik 4
Programimi dhe grafika 5
Njësitë harduerike për paraqitjet grafike 8
Sistemi Raster-Scan 10
SISTEMI I NGJYRAVE 13
DRITA AKROMATIKE 13
ZGJEDHJA E VLERAVE TE INTENSITETIT 14
APROKSIMIMI I GJYSËMTONEVE 17
NGJYRAT KROMATIKE 20
Aspekti psikofizik i ngjyrave 21
DIAGRAMI KROMATIK I CIE-së 24
MODELET E NGJYRAVE PËR GRAFIKËN RASTERIKE 28
MODELI RGB I NGJYRAVE 29
MODELI CMY I NGJYRAVE 30
Modeli YIQ i ngjyrave 31
Modeli HSV i ngjyrave 32
PROGRAMIMI I OBJEKTEVE PRIMITIVE 34
Objekti GRAPHICS 35
Objekti POINT 36
Objekti RECTANGLE 37
Objekti COLOR 37
Objekti FONT 38
Objekti PEN 39
Objekti GRAPHICSPATH 39
Grafika kompjuterike
-157-
Objekti BRUSH 40
Objekti SOLIDBRUSH 41
Vizatimi i formave të ndryshme 41
Vizatimi i përhershëm 42
Metodat për vizatim 45
Metoda DRAWLINE 46
Metoda DRAWRECTANGLE 46
Metoda DRAWELLIPSE 47
Metoda DRAWPIE 47
Metoda DRAWPOLYGON 49
Metoda DRAWCURVE 49
Metoda DRAWBEZIER 50
Metoda DRAWSTRING 52
OBJEKTI ME NGJYRA TË NDRYSHME (GRADIENTI) 52
Gradienti linear 53
Gradienti i shtegut 54
ALGORITMET PËR VIZATIMIN E OBJEKTEVE PRIMITIVE DYDIMENSIONALE 56
SKANIMI DHE KONVERTIMI I LINJËS 56
ALGORITMI THEMELOR INKREMENTAL 56
ALGORITMI I PIKËS SË MESME TË LINJËS 58
ALGORITMI I PIKËS SË MESME TË RRETHIT 62
MBUSHJA E DREJTKËNDËSHAVE 65
OBJEKTET PRIMITIVE ME TRASHËSI TË MËDHA 66
REPLIKIMI I PIKSELAVE 67
ALGORITMI I LËVIZJES SË LAPSIT 68
SHKURTIMI I REGJIONEVE TË VIZATIMIT 68
ALGORITMI I COHEN-SUTHERLAND-IT PËR SHKURTIM TË LINJAVE 70
Grafika kompjuterike
-158-
TRANSFORMIMET GJEOMETRIKE DYDIMENSIONALE 76
TRANSFORMIMET THEMELORE GJEOMETRIKE DYDIMENSIONALE 76
ZHVENDOSJA 76
SHKALLËZIMI 77
ROTACIONI 78
KOORDINATAT HOMOGJENE DHE PREZENTIMI I TRANSFORMIMEVE DYDIMENSIONALE
PËRMES MATRICAVE 80
KOMPOZICIONI I TRANSFORMIMEVE DYDIMENSIONALE 85
TRANSFORMIMI I KOORDINATAVE DRITARE NË VIEWPORT 88
DETYRA DHE USHTRIME 91