Grafika Kompjuterike meteriali per gjenreaten 2013

158
Universiteti i Prishtinës Fakulteti i Inxhinierisë Elektrike dhe Kompjuterike GRAFIKA KOMPJUTERIKE (Materiali i ligjëratave dhe ushtrimeve) Adnan Maxhuni Artan Mazrekaj Prishtinë, 2013

description

Couse Lecture dfasefwegf wegfw er gtwer gweg wegw wegt wergt w4e wet wetwe we twe tw wetwet wertgert45t q5e ge ewifhwe ff. fi hefh iehwifhihewifrhwei qwef ew . ewt eiwhj iqhweri ghih erhge . afh ifhi ihweifhi hwe4i ghqi4e egh ierh giaehio rg. wei hiwefhfnha fhnfcfbnuiavacdasbsaseha.

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