Forgatható ellipszis, ellipszisív és téglalap

Ha a tkinter modul Canvas példányán meghívott create_oval(), create_arc() és create_rectangle() metódusokkal létrehozott ellipszist, ellipszisívet és téglalapot egy adott forgáspont körül forgatjuk, akkor azt tapasztaljuk, hogy azok nem a vártnak megfelelően, vagyis nem alaktartó módon forognak el, hanem torzulnak, és az ellipszis tengelyei, valamint a téglalap oldalai továbbra is a vízszintes és függőleges koordináta-tengelyekkel lesznek párhuzamosak. Ennek oka, hogy az említett síkalakzatokat a befoglaló téglalap két pontjával, az ellentétes sarokpontokkal lehet és kell meghatározni a létrehozó metódusokban. Forgatáskor ezek a sarokpontok fordulnak, és az új két pont egy új befoglaló téglalapot határoz meg, amelyben az adott síkalakzat létrejön.

Ez a működésmód azonban korlátozza a vászon elemen létrehozható grafikákat. Hogyan lehetne ezt a korlátot feloldani?

Egy lehetséges megoldás, hogy a Canvas create_polygon() metódusával létrehozható sokszöggel valósítjuk meg a téglalapot. Az alaktartóan forgatható ellipszist, valamint az ellipszisív alapjául szolgáló ellipszist pedig megfelelően nagy számú csúcsponttal rendelkező sokszöggel közelítjük. /A megfelelően nagy szám itt azt jelenti, hogy a kirajzoláskor már nem látszik, hogy valójában sokszög jelenik meg./

Ehhez a Canvas osztáy egy altípusát definiáljuk CustomCanvas néven. Ennek egy lehetséges megvalósítását láthatjuk alább. Ez kiterjeszti a Canvas képességeit a create_rotatable_rectangle(), create_rotatable_ellipse() és create_rotatable_arc() nyilvános metódusokkal, amelyek alaktartóan forgatható téglalapot, ellipszist és ellipszisívet jelenítenek meg sokszögekkel megvalósítva. Ezeket használja a create_rotatable() metódus is, amelynek egy str típusú argumentummal lehet megadni, hogy melyik alakzatot akarjuk előállíttatni. Ezeken felül az osztályban definiált még a rotate() nyilvános metódus, amely egy adott azonosítójú alakzatot megadott szöggel, megadott forgáspont körül forgat el.

A CustomCanvas osztály, illetve metódusainak használatára illusztratív alkalmazási példaként egy stilizált macskafejet rajzolunk ki ellipsziseket és ellipszisíveket használva, valamint egy téglalapokból kialakított kalapot, amelyet a macskafej tetejére helyezünk. Végül az egész rajzot kicsit jobbra elforgatjuk. Ennek programkódja:

A programkódok elérhetők itt is: https://github.com/python…/rotatable_ellipse_arc_rectangle

Az eredmény a következő ábrán látható. Ilyen grafikát csupán a Canvas alapmetódusait használva nem tudnánk megalkotni.

Ha ez így egész jól működik, akkor felmerülhet a kérdés, hogy miért nem eleve így van megvalósítva a tkinter ellipszise, ellipszisíve és téglalapja? Ennek alapvetően memóriatakarékossági és feldolgozási idő csökkentési oka van. Ha a befoglaló téglalappal határozzuk meg e síkidomokat, akkor összesen két pontot, vagyis négy koordinátaértéket, azaz négy float számot kell tárolni minden egyes alakzathoz. Ha sokszöggel valósítjuk meg ezeket, akkor sokkal többet. Bár téglalap esetén csak négyet (már ez is duplázás), de ellipszis esetén több százat. Ez sok száz vagy ezer alakzat esetén tekintélyes memóriafelhasználást eredményez. Továbbá, a Canvas implementáció így jól optimalizált sok rajzelem kezelésére. Ha azonban egy rajzelem, mint például egy sokszög, sok pontból áll, akkor a kódnak sorban egymás után végig kell pásztáznia ezeket a pontokat. Ez viszont hátrányosan befolyásolhatja az egéresemények feldolgozásának idejét a vászon ezen objektumot tartalmazó területén.

A grafikus felhasználói felület létrehozásával, példákkal illusztrált részletes leírásával a Python tudásépítés lépésről lépésre című e-könyv „Grafikus felhasználói felület készítése” fejezete foglalkozik. E bejegyzés példája kapcsán érdemes még a „Készétel fogyasztás – a szabványos könyvtár moduljainak használata” fejezet „Speciális konténer típusok” és „Speciális iterátorok” alfejezeteit is átnézni.

Érdekel a Python tudásépítés lépésről lépésre az alapoktól az első asztali alkalmazásig című e-könyv.