Delphi-rajzolas


 * // Rajzolás Delphiben //**

A Delphiben több komponensnek is van ún.Canvas (rajzvászon) tulajdonsága, melyeken lehetőség van rajzolni, illetve szolgálhat kész rajzok, képek bemutatására is. Ezzel a tuladonsággal a következő komponensek rendelkeznek: (lásd az alábbi ábrán) //A// Pen vonalak rajzolására szolgál (van neki színe-Color, stílusa-Style (pl.psSolid, psDot, psDash, psDashDot, psDashDotDot, psClear,...), vastagsága-Width), a Brush (ecset) alakzatok belső tartományának kiszínezésére szolgál, a Font szöveg bevitelére, a Pixels a koordináták meghatározására, a PenPos pedig arra, hogy a ceruzának mi a poziciója. pl. Canvas.Pen.Color:=clRed; a ceruza színe piros Canvas.Pen.Style:=psDot; a ceruza pontozott vonalat fog rajzolni Canvas.Pen.Width:=2; 2 vastagságú vonalat rajzol

//A// ** rajzvászon (Canvas) ** egy téglalap alakú háló, mely kis négyzetekből (pixelekből, képpontokból) áll. Egy-egy pixel helyzetét annak vízszintes (X) és függőleges (Y) koordinátájával adhatjuk meg. A vászon bal felső sarka jelenti a (0,0) koordinátájú pontot, míg a jobb alsó pontot a (ClientWidth-1, ClientHeight-1) koordinátával adhatjuk meg. A Canvas egy TCanvas típusú objektum, mely a többi objektumhoz hasonlóan rendelkezik saját tulajdonságokkal és metódusokkal. A vászonra mindenhova rajzolhatunk, kivéve oda nem, ahol más elemek vannak elhelyezve. A rajzolás egyik módja, hogy a pixeleket kiszínezzük. pl. a (10,20) koordinátájú pixelnek így adunk sárga színt: Canvas.Pixels[10,20]:=clYellow; A szín megadható az RGB függvény segítségével. (RGB-Red,Green,Blue- a három alapszín). function RGB(R:byte,G:byte,B:byte):longint; pl. RGB(255,0,0) piros színt ad RGB(0,255,0) zöld színt ad RGB(0,0,255) kék színt ad

// **Feladatok** // __** 1.feladat **__ Írjunk egy olyan programot, mely a Form alkalmazás bal felső negyedét 10000 db. véletlen színű pixellel tölti fel. Lépések: 1.Kezdjünk úgy alkalmazást (File/New Application) 2.A Form1 OnPaint eseményére gépeljük be a következőket:


 * procedure TForm1.FormPaint(Sender: TObject);**
 * var i:integer;**
 * Color:longint;**
 * begin**
 * Randomize;**
 * for i:=1 to 10000 do**
 * begin**
 * Color:=RGB(Random(255),Random(255),Random(255));**
 * Canvas.Pixels [Random(ClientWidth div 2), Random(Clientheight div 2)]:=Color;**
 * end;**
 * end;**

3. Mentsük le a mappánkba az egész projectet (File/SaveAll).

feladat letöltése itt: //A// pixelek színezésére a Pixels tulajdonságot használjuk. Mit jelent a for ciklusban a 10000 szám? Ha változtatjuk az ablak méretét, észrevehetjük, hogy nem frissül a kifestett tartomány mérete. Ehhez azt kell megcsinálni, hogy az OnResize eseményre be kell írni a következő utasítsást:
 * procedure TForm1.FormResize(Sender: TObject);**
 * begin**
 * Repaint;**
 * end;**

__** 2.feladat **__ Írjunk egy programot, mely egy kört rajzol meg, melynek sugara megegyezik az ablak szélességeének negyedével, közepe pedig az ablak közepén helyezkedik el. (Az órajárással ellentétesen haladjon a pixelek kiszínezése). A kör tekinthető az ellipszis speciális esetének, de most egy másik módszerrel rajzoljuk meg. A kör középpontja legyen x0,y0. Az OnPaint eseményre gépeljük be a következőket: feladat letöltése itt:
 * procedure TForm1.FormPaint(Sender: TObject);**
 * var xc,yc,r,x,y:integer;**
 * a:real;**
 * begin**
 * xc:=ClientWidth div 2; yc:=ClientHeight div 2; {a kozeppont pozicionalasa}**
 * r:=xc div 2; {a kör sugara}**
 * a:=0;**
 * repeat**
 * x:=round(xc+r*cos(a)); {a pont pozícionálása}**
 * y:=round(yc+r*sin(a));**
 * Canvas.Pixels[x,y]:=clRed; {a pont színe piros lesz}**
 * a:=a+1/r; {ennyivel mozdul el a szög}**
 * until a>=2*pi;**
 * end;**

__** 3.feladat **__ Írjunk egy programot, mely kirajzolja a Ying-Yang alakzatot. Használjuk a körívet rajzoló metódust, melynek középpontja (xc,yc), sugara r, a szög a-tól b-ig mozog. Úgy oldjuk meg a feladatot, hogy a rajzolás a **Rajzolj** gombra kattintva valósuljon meg, a sugár pedig szintén megadható legyen a megfelelő **Edit** mezőn kereszül. A körív megrajzolásához használjunk egy saját metódust, melynek törzsét a **public** részben kell megadni a **TForm1** osztályon belül:
 * public**
 * procedure Koriv(xc,yc:integer;a,b:real);**
 * end;**

A metódus megvalósítását tegyük az implementációs részbe, a neve elé a **TForm1** prefixet kell tenni, hogy egyértelmű legyen, hogy ez melyik osztályhoz tartozik:
 * procedure TForm1.Koriv(xc,yc,r:integer;a,b:real);**
 * var s:real;**
 * x,y:integer;**
 * begin**
 * s:=a;**
 * repeat**
 * x:=round(xc+r*cos(s)); y:=round(yc-r*sin(s));**
 * Canvas.Pixels[x,y]:=clBlue;**
 * s:=s+1/r;**
 * until s>b;**
 * end;**

Ezután kitehetjük a megfelelő komponenseket (**Panel- ezen lesz btRajzolj, btTorolj, edR és egy label, melynek caption-je: R**). A **btRajzolj** gombra a kövekező eseményt kell begépelni: //**end;**// A **btTorolj** gombra pedig gépeljük be a következőt:
 * procedure TForm1.btRajzoljClick(Sender: TObject);**
 * var xc,yc,r:integer;**
 * begin**
 * xc:=(ClientWidth-Panel1.Width) div 2;**
 * yc:=ClientHeight div 2; //{a kozeppont koordinatai}//**
 * r:=StrToInt(edR.text**//**);**// **{atveszi a sugar erteket az Edit komponensbol}**
 * Koriv(xc,yc,r,0,pi); {felso felkor}**
 * Koriv(xc+r div 2, yc, r div 2, pi, 2*pi);** **{also felkor r/2 sugarral}**
 * Koriv(xc-r div 2,yc, r div 2, 0,pi); {//felso felkor /2 sugarral}//**
 * procedure TForm1.btToroljClick(Sender: TObject);**
 * begin**
 * refresh;**
 * end;**

feladat letöltése itt:

__** 4.feladat **__ Írjunk egy olyan programot, mely N darab (véletlen szám) kört rajzol meg, melyeknek a sugarai R nagyságúak, melyek középpontjai egy láthatatlan körön vannak, melynek szintén a sugara R! megoldás: felhasználjuk az előbbi példában megalkotott Koriv metódust, mely most így néz majd ki Koriv(x,y,r,0,2*pi). A lényeg ez: feladat letöltése itt:
 * procedure TForm1.FormPaint(Sender: TObject);**
 * var xc,yc,n,r,i,x,y:integer;**
 * begin**
 * xc:=ClientWidth div 2;**
 * yc:=Clientheight div 2;**
 * r:=yc div 2;**
 * randomize;**
 * n:=random(30);**
 * for i:=0 to n-1 do**
 * begin**
 * x:=round(xc+r*cos(2*pi*i/n));**
 * y:=round(yc+r*sin(2*pi*i/n));**
 * koriv(x,y,r,0,2*pi);**
 * end;**
 * end;**

//** Grafikai primitívek **// Minden rajz, kép, ábra tekinthető grafikai primitívek halmazának: pontok, vonalak, ellipszisek, körívek stb. Ez azt jelenti, hogy a program, mely ki kell hogy rajzoljon egy képet, kell hogy alkalmazzon bizonyos primitíveket, melyekkel megrajzolhatók a kép bizonyos grafikus elemei. A rajzvásznon a következő primitívekkel találkozunk: Canvas, LineTo, PolyLine, Polygon, Rectangle, Polygon, Ellipse, TextOut, stb.

**Vonalak rajzolása**

A Delphiben vonalakat a toll (Pen) segítségével tudunk rajzolni. Ez egy láthatatlan objektum, melynek mindig az utolsó pixelének a koordinátáját kell megadni. Alapértelmezetten a (0,0) koordinátától kezdődően rajzol. Ha máshonnan szeretnénk rajzolni, először a MoveTo(x,y) utasítással elmozdítjuk a toolunkat az (x,y) koordinátájú kezdőpontba. Innan fog majd tovább rajzolni a LineTo(x1,y1) koordinátájú pontig. A toll színét a Pen.Color adja meg, a vastagságát a Pen.Width, a stílusát Pen.Style.

__** 5.feladat **__ Rajzoljuk meg a lehető legnagyobb X-et tetszőleges színnel. A rajzolás a Rajzolj gombra kattintva valósuljon meg. A rajz törlése pedig a Törölj gombra történjen. __Lépések:__ 1. File/New/Application 2. Tegyünk a Form1-re 2 Buttont (btRajzolj, btTorolj). A **btRajzolj**-ra a következőket kell begépelni: A **btTorolj**-re pedig gépeljük be a következőket:
 * procedure TForm1.btRajzoljClick(Sender: TObject);**
 * begin**
 * Randomize;**
 * with Canvas do**
 * begin**
 * Pen.Width:=10; {a toll vastagsaga}**
 * Pen.Color:=RGB(Random(255),Random(255),Random(255));**
 * pen.Style:=psDot; {a vonal stilusa}**
 * MoveTo(0,0); {pozicionalas a bal felso sarokba}**
 * LineTo(ClientWidth-1,ClientHeight-1); {vonalat rajzol a jobb also sarokig}**
 * MoveTo(ClientWidth-1,0); {pozicionalas a jobb felso sarokba}**
 * LineTo(0,ClientHeight-1); {vonalat rajzol a bal also sarokig}**
 * end;**
 * end;**
 * procedure TForm1.btToroljClick(Sender: TObject);**
 * begin**
 * refresh;**
 * end;**

feladat letöltése itt: Próbáljuk ki a feladatot úgy is, hogy módosítunk a vonal vastagságán és a stílusán. __** 6.feladat **__ Írjunk egy programot, mely megrajzol egy szabályos N-szöget, melynek középpontja a Cliens felület középpontja lesz. A sokszög megrajzolása egy Rajzol gombra kattintva történjen meg, a sögszög csúcsainak számát egy SpinEdit komponenssel adjuk meg.

Az OnPaint eseményre rajzolunk, meg az alkalmazás indításakor aktivizálódik. Miután kiválsztjuk, melyik sokszöget szeretnénk megrajzolni, rá kell kattintanunk a Rajzolj gombra, amelyhez a következő eseményt kell rendelnünk:
 * procedure TForm1.FormPaint(Sender: TObject);**
 * var xc,yc,r,i,n:integer;**
 * begin**
 * with Canvas do**
 * begin**
 * xc:=(ClientWidth-Panel1.Width) div 2;**
 * yc:=ClientHeight div 2;**
 * r:=xc div 2;**
 * n:=SpinEdit1.Value;**
 * Pen.Width:=2;**
 * Pen.Color:=clblack;**
 * MoveTo(xc+r,yc);**
 * for i:=1 to n do**
 * LineTo(round(xc+r*cos(2*pi*i/n)),round(yc-r*sin(2*pi*i/n)));**
 * end;**
 * end;**
 * procedure TForm1.btRajzoljClick(Sender: TObject);**
 * begin**
 * repaint;**
 * end;**

feladat letöltése itt: __** 7.feladat **__ Írjunk egy olyan programot, mely N szögű csillagot rajzol, képzeletbeli R1 és R2 sugarakkal, ahol a szögek eltérése 2pi/N! Két szomszédos pont két különböző körön helyezkedik el. feladat letölthető itt:
 * procedure TForm1.btRajzoljClick(Sender: TObject);**
 * var xc,yc,R,R1,R2,N,i:integer;**
 * begin**
 * xc:=(ClientWidth-Panel1.Width) div 2;**
 * yc:=ClientHeight div 2;**
 * R1:=StrToInt(edR1.Text);**
 * R2:=StrToInt(edR2.Text);**
 * N:=StrToInt(edN.Text);**
 * Canvas.MoveTo(xc+R1,yc);**
 * for i:=1 to N do**
 * begin**
 * if i mod 2=1 then R:=R2 else R:=R1;**
 * Canvas.LineTo(round(xc+R*cos(2*pi*i/n)),round(yc+R*sin(2*pi*i/n)));**
 * end;**
 * end;**

Minden rajzvászon rendelkezik beépített metódusokkal, melyek egyszerű alakzatokat rajzolnak, mint pl.téglalapokat, lekerekített szélű téglalapokat, ellipsziseket, körszeleteket, köríveket stb. Az ellipszisek osztálya tartalmazza a kört is, mint speciális esetet. A zárt vonalakat ki lehet tölteni színnel. Az egyszerű alakzatokon kívül léteznek még törött vonalak is és sokszögek is.
 * // Egyszerű alakzatok //**

A rectangle eljárással lehet téglalapot rajzolni. A paraméterei a téglalap egyik átlójának koordinátái. pl. Canvas.Rectangle(10,10,50,50); Ez egy olyan téglalap lesz, melynek bal felső csúcsa a (10,10) koordinátájú pont, a jobb alsó csúcsa pedig az (50,50) koordinátájú pont. Tehát ez valójában egy négyzet lesz. A kontúrvonal színét, stílusát, és vastagságát a Pen tulajdonsággal adjuk meg, míg a téglalap belső tartományának kitöltőszínét és stílusát a Brush tulajdonsággal. pl. a következő részlet egy kék-fehér-piros zászlót rajzolna meg
 * Téglalap **
 * with Canvas do**
 * begin**
 * brush.color:=clBlue;**
 * rectangle(10,10,90,30);**
 * brush.color:=clWhite;**
 * rectangle(10,30,90,50);**
 * brush.color:=clRed;**
 * rectangle(10,50,90,70);**
 * end;**

Hogyan tüntethető el a körvonal?

__** 8.feladat **__ Írjunk egy programot, mellyel N darab négyzetet rajzolunk, melyek átlóinak közös a metszéspontja, és az oldalaik mértani sorozatot alkoznak, ahol 0<q<1. Kell egy Panel komponens, rajta 2 Button (Rajzolj, Újból), 2 Edit(edN, edQ),2 Label (N,Q).
 * OnClick** esemény a **Rajzolj** gombra:
 * procedure TForm1.btRajzoljClick(Sender: TObject);**
 * var a,x,y,n,i:integer;**
 * q:real;**
 * begin**
 * x:=(ClientWidth-Panel1.Width) div 2;**
 * y:=ClientHeight div 2;**
 * a:=x*2;**
 * n:=StrToInt(edN.Text);**
 * q:=StrToFloat(edQ.Text);**
 * Canvas.Pen.Width:=2;**
 * for i:=1 to n do**
 * begin**
 * Canvas.Rectangle(x-a div 2, y-a div 2, x+a div 2, y+a div 2);**
 * a:=round(a*q);**
 * end;**
 * end;**
 * OnClick** esemény az **Újból** gombra:
 * procedure TForm1.btUjbolClick(Sender: TObject);**
 * begin**
 * refresh;**
 * end;**

feladat letöltése itt:

A kör és az ellipszis az Ellipse metódussal rajzolhatók. __Általános formája:__ Az x1,y1,x2,y2 paraméterek egy olyan téglalap átlójának koordinátái, mely az adott ellipszis köré szerkeszthető (értelemszerűen, ha ez négyzet, akkor kör lesz az ellipszisből).
 * Kör és ellipszis **
 * Canvas.Ellipse(x1,y1,x2,y2);**

__** 9.feladat **__ Írjunk egy programot, mely tetszőleges sugarú köröket rajzol az alkalmazáson (Form1-en), a körök középpontjai az alkalmazás vízszintes tengelyén vannak. A köröket balról jobbra haladva rajzoljuk.
 * procedure TForm1.FormPaint(Sender: TObject);**
 * var x,y,r:integer;**
 * begin**
 * x:=0;y:=ClientHeight div 2; Randomize;**
 * with Canvas do**
 * begin**
 * Pen.Width:=3;**
 * Brush.Color:=clYellow;**
 * r:=random(y);**
 * while x<=ClientWidth do**
 * begin**
 * Ellipse(x,y-r,x+2*r,y+r);**
 * x:=x+2*r;**
 * r:=random(y);**
 * end;**
 * end;**
 * end;**

feladat letöltése itt:
 * Körív-Arc**

Az Arc metódus körívet rajzol, egy ellipszis (vagy egy kör) meghatározott részét. __Általános alak:__ Canvas.Arc(x1,y1,x2,y2,x3,y3,x4,y4); Az x1,y1,x2,y2 paraméterek az ellipszist definiálják, az x3,y3 és x4,y4 pontokkal adjuk meg a körív kezdő- és végpontját. A kezdőpont az ellipszis és az ő középpontján áthaladó egyenes metszéspontjának x,y koordinátája, a végpont pedig az ellipszis és az ő középpontján áthaladó egyenes metszéspontjának x,y koordinátája.


 * Törött vonalak és sokszögek - PolyLine és Polygon**

__** 10.feladat **__ Írjunk egy olyan programot, mely egy ötszöget rajzol és abba egy M betűt. feladat letöltése itt:
 * OnPaint** esemény:
 * procedure TForm1.FormPaint(Sender: TObject);**
 * begin**
 * with Canvas do**
 * begin**
 * Pen.Width:=10;**
 * Brush.Color:=clYellow;**
 * Polygon([Point(150,20),Point(260,100),Point(220,220),Point(80,220),**
 * Point(40,100)]);**
 * PolyLine([Point(110,160),Point(110,100),Point(150,160),Point(190,100),**
 * Point(190,160)]);**
 * end;**
 * end;**

__Gyakorló feladatok:__ 1. Rajzoljuk le az olimpiai karikákat! 2. Rajzoljunk egy házat! feladat letöltése itt: