MFF UK / Ústav teoretické fyziky / Tomáš Ledvinka |
|
Grafický stav
Mimo jiné je součástí grafického stavu
Princip grafického stavu má svůj původ již u souřadnicových zapisovačů, kde se barva měnila výměnou malovacího pera, a běžná poloha byla opravdu polohou pera nad papírem. Pro nás znamená existence grafického stavu, že vystačíme s jedinou procedurou stroke pro malování čáry, ať už je barevná, čárkovaná, rovná nebo křivá. Cvičení: Měňte barvy Cvičení: Vynechte přepnutí do barevného módu a změňte počet parametrů u všech volání procedury setcolor tak aby měly jeden parametr (0.0 = černá,1.0 = bílá). Cvičení pro zvídavé: Přidejte do příkladů 1 a 3 před
newpath příkaz Příkazem setcolor se mění nenávratně barva
jíž malujeme, podobně newpath nenávratně ničí
dosavadní cestu. Protože barva i aktuální cesta jsou
součástí grafického stavu, můžeme si je schovat pomocí
procedury gsave, která na
vnitřní zásobník (jiný, než ten pro předávání paramtrů
procedurám) uloží kompletní grafický stav. Nyní můžeme
dle potřeby měnit barvu, měřítka, aktuální polohu atd.a
až skončíme, obnovíme původní grafický stav zavoláním
procedury grestore. 2.8346 2.8346 scale Obecně příkaz
Cvičení: Napište program v Pascalu, který namalujte (tedy vytvoří postscripový soubor, který se vykreslí jako) ony kompletní n-úhelníky z minulé přednášky. Poznámka: Operacemi moveto lineto lineto moveto linet Křivky V praxi bychom neměli používat cestu složenou ze stovek kousků. Pokud jde o malování plných čar vystačíme s jejím rozložením na více kratších cest (až na artefakty při napojování, které jsou vidět u tlustých čar, viz Příklad 3). Pokud je cesta obzvlášť křivá a na její konstrukci bychom potřebovali příliš mnoho úseček tak, aby nebyla viditelně polámaná, máme k dispozici proceduru na malování křivky curveto. Ta maluje parametrickou křivku [x(t),y(t)], kde funkce x(t) a y(t) jsou jsou kubické polynomy. (Mimochodem, úsečka je také takovou parametrickou křivkou, ale polynomy jsou jen prvního stupně.)
Třetí stupeň byl zvolen proto, aby si člověk mohl zvolit
nejen počáteční a koncový bod křivky (na to stačí
úsečka - první stupeň), ale také tečny v obou koncových
bodech (viz obrázek). To že tečný vektor[dx(t)/dt,dy(t)/dt] v
bodě [x0,y0] (tedy v t=0 ) míři do bodu [x1,y1] se z derivace
výše uvedených polynomů v t=0 pozná snadno. O něco méně
je vidět, že v hodnotě parametru t=1, je [x(t),y(t)]=[x3,y3],
a ješte skrytější je fakt, že tečna míří z [x3,y3] do
bodu [x2,y2].
Následující obrázek ilustruje, jak dobrou aproximací
skutečné křivky mohou tyto kubické křivky být. Příklad Když už mluíme o parametrických křivkách, nelze vynechat zmínku o těch nejznámějších, Lissajousových obrazcích. Zde je program, který je za nás namaluje program LissaPS; { Maluje Lissajousovy obrazce Umí je malovat čarou nebo vyplnit Postscriptový obrázek vypíše na standardní výstup } const Vybarvit = true; var AktualniPoloha : record x,y : real; OK : boolean; end; procedure KusKrivky(Ax,Ay, Bx,By, Cx,Cy, Dx,Dy : real); {Používá výše uvedené vzorečky a proloží body ABCD kubický oblouk} var x1,y1,x2,y2 : real; begin { nejdriv spocist polohu ridicich bodu } x1 := (18*Bx-5*Ax+2*Dx-9*Cx)/6.0; x2 := (2*Ax-5*Dx+18*Cx-9*Bx)/6.0; y1 := (18*By-5*Ay+2*Dy-9*Cy)/6.0; y2 := (2*Ay-5*Dy+18*Cy-9*By)/6.0; { na pocatku cesty musi byt newpath & moveto } if (not AktualniPoloha.OK) then Writeln('newpath'); if (not AktualniPoloha.OK) or (AktualniPoloha.x<>Ax) or (AktualniPoloha.y<>Ay) then Writeln(Ax:4:2,' ',Ay:4:2,' moveto'); { pokazde pak curveto } Writeln(x1:4:2,' ',y1:4:2,' ',x2:4:2,' ',y2:4:2,' ',Dx:4:2,' ',Dy:4:2,' ',' curveto'); AktualniPoloha.x := Dx; AktualniPoloha.y := Dy; AktualniPoloha.OK:= true; end; procedure Obtahni; begin Writeln('stroke'); AktualniPoloha.OK:= false; end; procedure Vybarvi; begin Writeln('fill'); AktualniPoloha.OK:= false; end; procedure Lissajous(sx, sy, Polomer, fazex,fazey : real; kx,ky:integer); {[sx,sy] je stred, faze* jsou faze obou harm. oscilatací ve stupních} var i : integer; N : integer; Ax,Ay,Bx,By,Cx,Cy,Dx,Dy : real; function x(m:integer) :real; begin x:=sx+Polomer*sin(fazex+2*Pi/N*kx*(i+m/3.0)); end; function y(m:integer) :real; begin y:=sy+Polomer*sin(fazey+2*Pi/N*ky*(i+m/3.0)); end; begin N := kx; if N<ky then N:=ky; N := N*8; {videli jsme, ze 4 staci na kruznici} fazex := fazex*Pi/180.0/kx; fazey := fazey*Pi/180.0/ky; {uz jsou v radianech} for i := 0 to N-1 do begin KusKrivky( x(0),y(0), {pocatecni bod krivky} x(1), y(1), { t = 1/3 } x(2), y(2), { t = 2/3 } x(3), y(3) {koncovy bod oblouku krivky} ); end; if Vybarvit then Vybarvi else Obtahni; Writeln; end; Procedure SetColor(r,g,b:byte); {R G B v rozsahu 0..255} begin Writeln(r/255.0:6:3,g/255.0:6:3,b/255.0:6:3,' setcolor'); end; const R = 50; {polomer v milimetrech} begin Writeln('/DeviceRGB setcolorspace'); Writeln('2.8346 2.8346 scale'); {milimetry} Writeln('105 148.5 translate'); {do stredu A4} Writeln('0.1 setlinewidth'); {tenke cary} SetColor(255,174,17); Lissajous(-R,R, 40, 0,0, 1,2); SetColor(155,0,0); Lissajous(R,R, 40, 0,0, 3,4); SetColor(130,0,130); Lissajous(-R,-R, 40, 0,0, 7,8); SetColor(11,80,50); Lissajous(R,-R, 40, 10,0, 15,16); Writeln('showpage'); end. Výstup tohoto programu je potřeba přesměrovat do souboru,
a ten si poté můžeme prohlédnout, vytisknout či poslat
emailem.
Příkaz start nám spustí ten program,
který má v počítači na starosti postscriptové obrázkya pak
uvidíme: a nebo
Cvičení: Upravte program tak, aby místo křivek používal lomenou čáru. Použít můžete následující proceduru procedure Lomenice(Ax,Ay, Bx,By, Cx,Cy, Dx,Dy : real); begin { na pocatku cesty musi byt newpath & moveto } if (not AktualniPoloha.OK) then Writeln('newpath'); if (not AktualniPoloha.OK) or (AktualniPoloha.x<>Ax) or (AktualniPoloha.y<>Ay) then Writeln(Ax:4:2,' ',Ay:4:2,' moveto'); { pokazde pak 3x lineto } Writeln(Bx:4:2,' ',By:4:2,' lineto ',Cx:4:2,' ',Cy:4:2,' lineto ',Dx:4:2,' ',Dy:4:2,' ',' lineto'); AktualniPoloha.x := Dx; AktualniPoloha.y := Dy; AktualniPoloha.OK:= true; end; Výsledek by pak měl vypadat takto: Poznámky pro život a ne zkoušku: Jazyk Postscript vziknul jako jazyk pro ovládání počítačových tiskáren a proto je největším odborníkem na písmenka. Protože může být někdy užitečné doplnit do obrázku pár písmenek, je v následujícím příkladě shrnuto několik nejpotřebnějších procedur pro práci s textem.
Vidíme, že
Procedura selectfont má za první parametr název písma,
druhý je jeho velikost. Vypadá to, že bychom už měli o jazyce postscript vědět
to nejpodstatnější. Třeba bychom si mohli myslet, že když
si budme prohlížet postscriptový soubor narazíme na série
příkazů 213 321 moveto 545 545 lineto 45 544 moveto 577
889 lineto 54 889 lineto ....
Programu nejlépe porozumíme, přeložíme-li si začátek podle tabulky
a uvědomíme-li si, že procedury moveto, lineto a ještě jednou lineto vyzvednou ze zásobníku každá dva parametry. Pak je zřejmé, že procedura t jich potřebuje šest. Zájemce o další informace o jazyce Postscript může použít dokumenty, které firma Adobe dává volně k dipozici, především pak učebnici, kterou lze vygooglovat dotazem "postscript bluebook pdf" (240 stran), případně referenční příručku ("postscript PLRM pdf", 912 stran). Konec poznámek pro život a ne zkoušku. |
. |