Geometrick´e praktikum Jan Laˇstoviˇcka 28. dubna 2015
1
Kreslen´ı objekt˚ u v rovinˇ e
Zaˇcneme mal´ ym pˇr´ıkladem. Nahrajte knihovnu lisp-gl naˇcten´ım (napˇr´ıklad z nab´ıdky File > Load...) souboru load.lisp a vyhodnot’te n´asleduj´ıc´ı k´od: (opengl () (color (color-point :red)) (polygon (vertex (point 0 0)) (vertex (point 500 0)) (vertex (point 0 200)))) Otevˇre se nov´e okno s ˇcerven´ ym troj´ uheln´ıkem. V´ ysledek je zachycen na obr´ azku 1. Postupnˇe si rozebereme pr´avˇe pouˇzit´ y k´od. Zaˇcneme makrem opengl, kter´e vykresluje obsah do novˇe vytvoˇren´eho OpenGL okna. Zjednoduˇsen´a syntax makra je n´ asleduj´ıc´ı: (opengl () form∗ ) Smyslem v´ yraz˚ u je kreslit obsah okna. Pˇri potˇrebˇe pˇrekreslit okno jsou tyto v´ yrazy postupnˇe vyhodnocov´any. Funkce color mˇen´ı aktu´aln´ı barvu. Do dalˇs´ı zmˇeny jsou vˇsechny objekty kresleny nastavenou barvou. Funkce jako sv˚ uj argument bere bod z jednotkov´e krychle urˇcuj´ıc´ı barvu v RGB modelu. Funkce color-point vrac´ı bod v krychli reprezentuj´ıc´ı barvu zadanou jej´ım n´ azvem. Tedy (color (color-point :red)) nastav´ı aktu´aln´ı barvu na ˇcervenou. Makro polygon kresl´ı konvexn´ı polygon. Jeho argumenty jsou v´ yrazy, kter´e jsou postupnˇe vyhodnocov´any. Jejich v´ yznamem je zad´av´an´ı vrchol˚ u polygonu. Funkce vertex bere dvourozmˇern´ y bod, kter´ y je posl´an do grafick´e karty jako dalˇs´ı vrchol polygonu. Funkce point vytvoˇr´ı bod o zadan´ ych souˇradnic´ıch. Pˇred zad´ an´ım u ´kol˚ u si pˇredstav´ıme funkce pro pr´aci s body a vektory. Ty budou uˇziteˇcn´e pro ˇreˇsen´ı u ´kol˚ u. Uˇz jsme si pˇredstavili funkci 1
Obr´azek 1: Troj´ uheln´ık point na vytv´ aˇren´ı bod˚ u. Podobnˇe pracuje fuknce vect vytv´aˇrej´ıc´ı vektory. N´asleduj´ıc´ı funkce pracuj´ı jak s vektory tak body. Funkce coordinates vrac´ı souˇradnice bodu nebo vektoru v seznamu. Funkce x, y a z zjiˇst’uj´ı prvn´ı, druhou a tˇret´ı souˇradnici. Dimenzi prostoru, ve kter´em se bod nebo vektor nach´ az´ı, zjist´ıme funkc´ı dimension. N´ asoben´ı skal´ aru vektorem realizuje funkce mult, kter´a bere koeficient n´asoben´ı a vektor. Dva vektory sˇc´ıt´a funkce plus. K bodu vektor pˇriˇcte funkce plus. Vektor vedouc´ı od jednoho bodu k druh´emu zjist´ı funkce minus. U vektoru, kter´ y je z prostoru dimenze dva, zjiˇst’uje funkce phi jeho odchylku od kladn´e poloosy x. Funkce rotate otoˇc´ı vektor dimenze dva o zadan´ yu ´hel. ´ Ukol 1. Napiˇste funkci regular-polygon, kter´a bere stˇred (bod), polomˇer a poˇcet vrchol˚ u. Funkce nakresl´ı pravideln´ y mnoho´ uheln´ık vepsan´ y do kruˇznice. Vrchol mnoho´ uheln´ıku smˇeˇruje nahoru. ´ Ukol 2. Naprogramujte funkci circle, kter´a bere stˇred (bod) a polomˇer, kresl´ıc´ı kruˇznici. ´ Ukol 3. Napiˇste funkci star kresl´ıc´ı hvˇezdu. Funkce bere stˇred (bod), dva polomˇery (r1 a r2 ) a poˇcet c´ıp˚ u. Hvˇezdˇe je opsan´a kruˇznice o polomˇeru r1 a do hvˇezdy je vepsan´ a kruˇznice o polomˇeru r2 . C´ıp hvˇezdy smˇeˇruje nahoru.
2
2
Konvexn´ı polygony
Makro opengl neumoˇzn ˇuje ukl´ad´an´ı vlastnost´ı kreslen´ı (napˇr. barva objektu) a ani definici obsluh uˇzivatelsk´ ych akc´ı (napˇr. kliknut´ı myˇsi). Tuto funkcionalitu poskytuje obecnˇejˇs´ı makro opengl-canvas jehoˇz zjednoduˇsen´a syntax je n´ asleduj´ıc´ı: (opengl-canvas () ({var | (var [init-form])}∗ ) (function-name lambda-list form∗ )∗ ) Druh´ y argument makra je definice promˇenn´ ych kresl´ıc´ıho pl´atna, kter´e se definuj´ı stejnˇe jako u makra let. Za promˇenn´ ymi n´asleduje definice lok´aln´ıch funkc´ı podobn´ a jako u makra labels. N´asleduje v´ yˇcet funkc´ı, kter´e lze takto definovat. Funkce display nebere ˇz´adn´ y argument a star´a se o kreslen´ı obsahu na pl´ atno. Funkce mouse-press-primary bere bod. Je vol´ana v pˇr´ıpadˇe, ˇze doˇslo ke zm´ aˇcknut´ı hlavn´ıho (prim´arn´ıho) tlaˇc´ıtka myˇsi. Do argumentu je d´ ana pozice myˇsi. Funkce mouse-press-secondary funguje stejnˇe jako mouse-press-primary s t´ım rozd´ılem, ˇze je vol´ana v pˇr´ıpadˇe stisku sekund´ arn´ıho tlaˇc´ıtka. V tˇele funkc´ı je moˇzno pˇristupovat k promˇenn´ ym pl´atna (ˇc´ıst jejich hodnotu a nastavovat ji makrem setf). Po zpracov´an´ı kliku myˇsi je okno pˇrekresleno. N´ asleduj´ıc´ı pˇr´ıklad zobraz´ı okno s troj´ uheln´ıkem jehoˇz barva se mˇen´ı po stisku tlaˇc´ıtka myˇsi. (opengl-canvas () ((color :red)) (display () (color (color-point color)) (polygon (vertex (point 0 0)) (vertex (point 500 0)) (vertex (point 0 100)))) (mouse-press-primary (point) (if (eql color :red) (setf color :blue) (setf color :red)))) Pˇred zad´ an´ım u ´kol˚ u si pˇredstav´ıme funkci cross-product, kter´a vr´at´ı vektorov´ y souˇcin dvou vektor˚ u dimenze tˇri. Pˇripomeˇ nme, ˇze v´ ysledkem je vektor kolm´ y k obˇema zadan´ ym vektor˚ um smˇeˇruj´ıc´ı do poloprostoru urˇcen´eho pravidlem prav´e ruky. S pouˇzit´ım pˇredstaven´e funkce splˇ nte n´asleduj´ıc´ı u ´koly. ´ Ukol 1. Napiˇste funkci, kter´ a rozhodne, zda je polygon zadan´ y jako seznam vrchol˚ u (bod˚ u) konvexn´ı. 3
´ Ukol 2. Napiˇste funkci rozhoduj´ıc´ı, zda je bod v konvexn´ım polygonu. ´ Ukol 3. Vytvoˇrte okno s n´ asleduj´ıc´ım chov´an´ım. Po stisku hlavn´ıho tlaˇc´ıtka se pˇrid´ a vrchol do konvexn´ıho polygonu. Po prvn´ıch dvou stisc´ıch, kdy se zad´ avaj´ı prvn´ı dva vrcholy polygonu, z˚ ustane okno pr´azdn´e. Po tˇret´ım stisku se zobraz´ı troj´ uheln´ık. Dalˇs´ı body budou pˇrid´avan´e mezi prvn´ı a posledn´ı vrchol polygonu, ale pouze v pˇr´ıpadˇe, ˇze polygon z˚ ustane konvexn´ı. V opaˇcn´em pˇr´ıpadˇe se zobraz´ı (pomoc´ı funkce capi:display-message) chybov´a hl´aˇska. Pokud se do takto vznikaj´ıc´ıho polygonu klikne sekund´arn´ım tlaˇc´ıtkem, dojde k zmˇenˇe jeho barvy.
3
Souˇ radn´ y syst´ em modelu
Vrcholy polygon˚ u jsou zad´ avan´e v souˇradn´em syst´emu modelu. Jeho v´ ychoz´ı nastaven´ı je n´ asleduj´ıc´ı. Poˇc´atek se nal´ez´a v lev´em doln´ım rohu. Osa x smˇeˇruje vpravo a osa y nahoru. Mˇeˇr´ıtko os je nastaveno tak, aby jednotka mˇela velikost jednoho pixelu. N´asleduj´ıc´ı tˇri funkce slouˇz´ı k transformaci souˇradn´eho syst´emu modelu. Funkce c-s-translate (c-s je zkratkou za coordinate system) bere vektor zadan´ y v souˇradn´em syst´emu modelu. Funkce posune poˇc´ atek o vektor. Funkce c-s-scale bere dva koeficienty (ˇc´ısla). Funkce zmˇen´ı mˇeˇr´ıtka os podle zadan´ ych koeficient˚ u (prvn´ı koeficient je pouˇzit na osu x). Nakonec funkce c-s-rotate otoˇc´ı osy o zadan´ yu ´hel proti smˇeru hodinov´ ych ruˇciˇcek. Pˇred kreslen´ım obsahu okna je souˇradn´ y syst´em vr´acen do sv´e v´ ychoz´ı polohy. Pˇri kreslen´ı je k dispozici z´asobn´ık, na kter´ y je moˇzn´e ukl´adat souˇradn´e syst´emy modelu makrem with-c-s-pushed. Makro bere v´ yrazy. Nejdˇr´ıve vloˇz´ı souˇradn´ y syst´em modelu na z´asobn´ık, pot´e postupnˇe provede v´ yrazy a na z´ avˇer odebere souˇradn´ y syst´em ze z´asobn´ıku a uˇcin´ı jej aktu´aln´ım. Pˇred zad´ an´ım u ´kolu si pˇredstav´ıme zp˚ usob zpracov´an´ı stisku kl´avesy. K tomuto u ´ˇcelu slouˇz´ı funkce key-press makra opengl-canvas oˇcek´avaj´ıc´ı znak. Po stisku kl´ avesy je funkce zavol´ana a znak kl´avesy je j´ı pˇred´an jako argument. Objekt reprezentuj´ıc´ı znak c z´ısk´ame vyhodnocen´ım #\c. ´ Ukol 1. Vytvoˇrte okno s robotickou paˇz´ı zachycen´e na n´asleduj´ıc´ım obr´azku.
4
Ke kreslen´ı paˇze m˚ uˇzete pouˇz´ıt pouze ˇctverec o hranˇe d´elky jedna. Paˇze se bude natahovat a oh´ ybat stiskem tlaˇc´ıtek + a -.
4
Tˇ ret´ı dimenze
Pl´ atno pracuj´ıc´ı s trojrozmˇern´ ym prostorem se vytvoˇr´ı makrem opengl-canvas nastaven´ım promˇenn´e dimension na 3. Souˇradn´ y syst´em prostoru nav´ıc obsahuje osu z, kter´ a je ve v´ ychoz´ı pozici kolm´a na osy x a y a smˇeˇruje smˇerem k uˇzivateli. Funkce pracuj´ıc´ı s trojrozmˇern´ ym prostorem oˇcek´avaj´ı jako argumenty trojrozmˇern´e body a vektory. Napˇr´ıklad funkce vertex oˇcek´av´a trojrozmˇern´ y bod. N´ asleduj´ıc´ı k´od nakresl´ı dva do sebe zaklesl´e troj´ uheln´ıky. (opengl-canvas () ((dimension 3)) (display () (color (color-point :red)) (polygon (vertex (point 0 0 100)) (vertex (point 500 0 100)) (vertex (point 0 100 100))) (color (color-point :blue)) (polygon (vertex (point 0 0 0)) (vertex (point 200 0 200)) (vertex (point 200 100 200))))) V trojrozmˇern´em prostoru maj´ı rotuj´ıc´ı funkce (rotate a c-s-rotate) nepovinn´ y argument rotation-vector, coˇz je trojrozmˇern´ y vektor, kolem kter´eho 5
se bude toˇcit. Napˇr´ıklad pˇr´ıkaz (c-s-rotate pi (vect 1 0 0)) otoˇc´ı soustavu kolem kladn´e ˇc´ asti osy x o 180◦ . Implicitnˇe je tento argument vektor o souˇradnic´ıch (0, 0, 1). Rozˇs´ıˇr´ıme si syntax makra opengl-canvas o moˇznost zad´avat moduly: (opengl-canvas (modul∗ ) variables functions∗ ) Moduly lze zad´ avat tak´e do makra opengl: (opengl (modul∗ ) form∗ ) Modul 3d nastav´ı dimenzi pl´atna na 3, posune poˇc´atek do stˇredu okna a postupnˇe rotuje kolem kladn´ ych ˇc´ast´ı os x, y a z o u ´hly, kter´e je moˇzn´e mˇenit stisky n´ asleduj´ıc´ıch kl´ aves. Osu x rotuj´ı kl´avesy w a s, osu y kl´avesy a a d a osu z kl´ avesy r a f. N´asleduj´ıc´ı k´od nakresl´ı troj´ uheln´ık, se kter´ ym je moˇzn´e stisky kl´ aves rotovat. (opengl (3d) (color (color-point :red)) (polygon (vertex (point 0 0 0)) (vertex (point 500 0 0)) (vertex (point 0 100 0)))) Rozˇs´ıˇr´ıme si reperto´ ar funkc´ı pracuj´ıc´ı s body a vektory. Funkce normalize vr´at´ı vektor velikosti jedna stejn´eho smˇeru jako zadan´ y vektor. Funkce minus-origin bere bod a vr´ at´ı vektor vedouc´ı z poˇc´atku (bod o nulov´ ych souˇradnic´ıch) k zadan´emu bodu. Naopak funkce plus-origin vr´at´ı k zadan´emu vektoru bod, kter´ y vznikne seˇcten´ım poˇc´atku a vektoru. ´ Ukol 1. Nakreslete pravideln´ y osmistˇen vepsan´ y do jednotkov´e koule se stˇredem v poˇc´ atku. ´ Ukol 2. Nakreslete subdivizi troj´ uheln´ıku (bude vysvˇetleno na semin´aˇri) s vrcholy leˇz´ıc´ımi na jednotkov´e kouli se stˇredem v poˇc´atku. ´ Ukol 3. Pomoc´ı subdivize osmistˇenu nakreslete aproximaci jednotkov´e koule.
5
ModelView Matice
Vrcholy polygonu m˚ uˇzou b´ yt transformov´any n´asleduj´ıc´ım zp˚ usobem. V makru opengl-canvas m˚ uˇze b´ yt definov´ana funkce vertex-transformation, kter´ a mus´ı br´ at bod a vracet opˇet bod. Tato funkce bude vol´ana na kaˇzd´ y vrchol zadan´ y funkc´ı vertex. Vrchol polygonu bude m´ıt souˇradnice v´ ysledn´eho bodu. 6
Bˇehem vykon´ av´ an´ı funkc´ı pl´atna (napˇr´ıklad pˇri kreslen´ı) je moˇzn´e z´ıskat pˇr´ıstup k jeho promˇenn´ ym n´ asleduj´ıc´ım makrem: (with-canvas-variables (variable∗ ) form∗ ) Ve v´ yrazech makra je moˇzn´e ˇc´ıst a nastavovat vyjmenovan´e promˇenn´e. ´ Ukol 1. Vytvoˇrte pl´ atno pracuj´ıc´ı s dvourozmˇern´ ym prostorem s ModelView matic´ı. ´ Ukol 2. Napiˇste n´ asleduj´ıc´ı funkce mˇen´ıc´ı ModelView matici. Funkce m-v-matrix-set-identity nastav´ı matici na jednotkovou. Funkce m-v-matrix-translate zmˇen´ı matici tak, aby se posunul poˇc´atek b´aze modelu o zadan´ y vektor. Funkce m-v-matrix-scale zmˇen´ı matici tak, aby se vyn´asobily vektory b´aze modelu zadan´ ymi koeficienty.
6
N´ avrat na zaˇ c´ atek
´ Ukol 1. Napiˇste n´ asleduj´ıc´ı funkce pracuj´ıc´ı s vektorov´ ym prostorem R2 : vectors-plus (sˇc´ıtaj´ıc´ı dva vektory) a scalar-vector-mult (n´asob´ıc´ı vektor skal´ arem). ´ Ukol 2. Napiˇste funkce point-vector-plus (sˇc´ıtaj´ıc´ı bod a vektor) a points-minus (vracej´ıc´ı rozd´ıl dvou bod˚ u) pracuj´ıc´ı s afinn´ım prostorem R2 (se zamˇeˇren´ım 2 R ). ´ Ukol 3. Vytvoˇrte pl´ atno pracuj´ıc´ı s afinn´ım prostorem R2 , kter´e bude m´ıt afinn´ı b´ azi. Afinn´ı b´ azi reprezentujte tˇr´ıprvkov´ ym seznamem, kde prvn´ı dva prvky budou vektory b´ aze a tˇret´ı prvek bude jej´ı poˇc´atek. Zaˇrid’te, aby souˇradnice vrchol˚ u byly zad´ avan´e vzhledem k t´eto b´azi. ´ Ukol 4. Napiˇste funkce affine-base-set-canonical (nastav´ı aktu´aln´ı afinn´ı b´ azi na kanonickou), affine-base-translate (posune poˇc´atek afinn´ı b´aze o vektor zadan´ y souˇradnicemi ve vektorov´e b´azi aktu´aln´ı afinn´ı b´aze), affine-base-scale (vyn´ asob´ı vektory afinn´ı b´aze zadan´ ymi koeficienty) a affine-base-rotate (orotuje vektory afinn´ı b´aze proti smˇeru hodinov´ ych ruˇciˇcek o zadan´ yu ´hel). ´ Ukol 5. Pˇridejte do pl´ atna z´asobn´ık na ukl´ad´an´ı afinn´ıch b´az´ı. Napiˇste funkci affine-base-push, kter´a vloˇz´ı aktu´aln´ı afinn´ı b´azi na z´asobn´ık, a funkci affine-base-pop, kter´a odebere afinn´ı b´azi ze z´asobn´ıku a uˇcin´ı ji aktu´ aln´ı.
7
7
St´ıny
Pˇredstav´ıme si zp˚ usob, kter´ ym lez vypoˇc´ıt´avat barvy vrchol˚ u polygonu. Funkce vertex-compute-color makra opengl-canvas bere bod a vrac´ı barvu. Je vol´ ana na kaˇzd´ y vrchol zadan´ y funkc´ı vertex. Vr´acen´a barva se stane barvou vrcholu. Promˇenn´a pl´atna current-color je nav´az´ana na aktu´ aln´ı barvu, kterou mˇen´ı funkce color. Promˇennou je dovoleno pouze ˇc´ıst. ´ Ukol 1. Vytvoˇrte trojrozmˇern´ y objekt, kter´ y bude vrhat st´ın na v´ami vybranou rovinu. Uˇzivatel si m˚ uˇze vybrat, jestli svˇetlo s rovnobˇeˇzn´ ymi paprsky bude na sc´enu dopadat z vrchu nebo z jednoho konkr´etn´ıho smˇeru, kter´ y si vyberete vy, nebo z libovoln´eho smˇeru, kter´ y zad´a on.
8
Svˇ ela
Vrcholu zadan´emu funkc´ı vertex je pˇriˇrazen aktu´aln´ı norm´alov´ y vektor kresl´ıc´ıho pl´ atna. Ten lze mˇenit funkc´ı normal berouc´ı vektor. Zadan´ y norm´alov´ y vektor je transformov´ an funkc´ı pl´atna normal-transformation (bere vektor a vrac´ı opˇet vektor). Aktu´ aln´ı norm´alov´ y vektor je nav´az´an na promˇennou pl´atna curent-normal. Funkce clear-color bere barvu (bod z jednotkov´e krychle) a nastav´ı aktu´ aln´ı mazac´ı barvu. Funkce clear-canvas (nebere ˇz´adn´ y argument) pˇrekryje pl´ atno aktu´ aln´ı mazac´ı barvou. ´ Ukol 1. Vyst´ınujte objekt tak, aby na nˇej dopadalo svˇetlo ze zadan´eho smˇeru. ´ Ukol 2. Dodejte odlesky.
9
B´ ezierova kˇ rivka
Dosud jsme kreslili jen konvexn´ı polygony makrem polygon. N´asleduje syntax makra gl-block umoˇzn ˇuj´ıc´ı kreslit dalˇs´ı primitiva OpenGL. (gl-block primitive form∗ ) Kde primitive je jeden z n´ asleduj´ıc´ıch symbol˚ u: points, lines, line-strip, line-loop, polygon, quads, quad-strip, triangles, triangle-strip, triangle-fan. V´ yrazy makra slouˇz´ı k zad´ av´ an´ı vrchol˚ u primitiva (funkc´ı vertex). V´ yznam primitiv je pops´ an na obr´ azku 2. ´ Ukol 1. Napiˇste funkci vectors-linear-combination, kter´a vr´at´ı line´arn´ı kombinaci zadan´ ych vektor˚ u se zadan´ ymi koeficienty. 8
Obr´ azek 2: Primitiva OpenGL ´ Ukol 2. Napiˇste funkci points-combination, kter´a vr´at´ı affin´ı kombinaci zadan´ ych bod˚ u se zadan´ ymi koeficienty. ´ Ukol 3. Nakreslete kvadratickou B´ezierovu kˇrivku. ´ Ukol 4. Nakreslete B´ezierovu kˇrivku zadanou n ˇr´ıd´ıc´ımi body. ´ Ukol 5. Vytvoˇrte pl´ atno, kter´e umoˇzn´ı uˇzivateli zad´avat ˇr´ıd´ıc´ı body B´ezierovy kˇrivky.
9