Az angol oval szó jelentése magyarul ovális; szó szerint tojás alakú, a latin ovum (tojás) szóból eredően. Ovális formákat számos helyen láthatunk a hétköznapi életben, például: kanál, versenypálya, tükör, úszómedence, tojás, rögbi labda, emberi szem. Az ovális alakzatok közös jellemzője, hogy zártak, konvexek, nem tartalmaznak egyenes vonalat vagy csúcsot, és sok esetben tengelyesen szimmetrikusak.
Az ovális forma hasonlít az ellipszishez, de nem azonos vele. Úgy is mondhatjuk, hogy minden ellipszis ovális, de nem minden ovális alakzat ellipszis. Valójában az ovális alakzatnak az említett közös jellemzőkön kívül nincs pontos geometriai definíciója, viszont az ellipszisnek mint tudjuk van: olyan pontok halmaza a síkban, amelyek két adott ponttól (fókuszpontok) mért távolságainak összege állandó.
Például ovális formát létre lehet hozni két azonos sugárral rendelkező átlapolódó körből kiindulva, de az alakzat nem felel meg az ellipszis definíciójának.
Miért érdekes mindez?
Azért, mert a tkinter modul Canvas grafikus elemén ki tudunk rajzoltatni egy ovális alakzatot a create_oval() metódussal, megadva a befoglaló négyszög bal felső és jobb alsó sarokpontjainak koordinátáit. Ha ezt megtesszük, akkor egy ellipszishez hasonló formát kapunk.
Bizonyos alkalmazásokban szeretnénk pontos ellipszist rajzolni, ezért jó lenne tudni, hogy a create_oval() által kirajzolt alakzat csak hasonlít egy ellipszishez, vagy ténylegesen egy ellipszist kapunk. Azonban a help a create_oval() metódusról csak ennyi információt ad:
„Help on function create_oval in module tkinter:
create_oval(self, *args, **kw)
Create oval with coordinates x1,y1,x2,y2.”
/És a tkinter alapját képező Tcl/Tk dokumentációja sem említi az ellipszist/
Ha a neten keresgélünk, akkor szintén azt olvashatjuk, hogy a metódus oválist rajzol, és csak ritkán említik, hogy egy ellipszist.
Próbáljuk, akkor magunk kideríteni mi a helyzet.
Mivel a kirajzolt ovális forma pontjai nem állnak rendelkezésre, így az ellipszist leíró egyenletbe történő behelyettesítéssel ezt nem tudjuk ellenőrizni. Jobb híján marad a vizuális összevetés. Ahhoz, hogy ez minél pontosabb tudjon lenni, a következőket tesszük:
– Kirajzolunk egy ellipszist a paraméteres egyenletei alapján (lásd pl. Wikipédia Ellipszis (görbe) szócikknél)
– Kirajzoltatunk egy oválist a Canvas create_oval() metódussal, ahol a befoglaló négyszög oldalai ugyanolyan hosszúak, mint az ellipszis nagy- és kistengelye. Az ovális alakzatot valamilyen kitöltő színnel jelenítjük meg.
Ha az ovális valójában egy ellipszis, akkor az általunk rajzolt ellipszis az ovális körvonala lesz. Ha viszont az ovális nem ellipszis, akkor ezt vizuálisan kell, hogy érzékeljük.
Az ezt megvalósító programot láthatjuk alább. A kommentek segítik a megértést.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
import tkinter as tk from math import sin, cos, pi class OvalTestApp(tk.Tk): def __init__(self, canvas_width=1200, canvas_height=600): super().__init__() self.title('Canvas oval és ellipszis') # Vászon grafikus elem, amelyen az ovalis és ellipszis alakzatokat kirajzoljuk. self.canvas = tk.Canvas(self, width=canvas_width, height=canvas_height) self.canvas.pack() def draw_point(self, x, y, color='black'): """Egy x, y koordinátákkal megadott pontot a color színű kis négyzettel jelenít meg.""" dp = 3 self.canvas.create_rectangle(x - dp, y - dp, x + dp, y + dp, fill=color, width=0) def draw_oval(self, center_point: tuple[int, int], delta_center: tuple[int, int], fill_color='light yellow'): """A Canvas creat_oval() metódusával állít elő egy ovális alakzatot, amelynek középpontja center_point, valamint a befoglaló négyszög jobb alsó sarokpontja a középponttól +delta_center vektorral eltolt pont, a bal felső sarokpont a középponttól -delta_center vektorral eltolt pont. Az alakzatot kitöltő színt a fill_color argumentummal lehet megadni. """ top_left_point = center_point[0] - delta_center[0], center_point[1] - delta_center[1] bottom_right_point = center_point[0] + delta_center[0], center_point[1] + delta_center[1] self.canvas.create_oval(top_left_point, bottom_right_point, fill=fill_color, width=1) def draw_ellipse(self, center_point: tuple[int, int], a: int | float, b: int | float, outline_color = 'blue'): """Egy center_point középpontú ellipszist rajzol ki az ellipszis paraméteres egyenletei alapján, amelyek x = a*cos(theta), y=b*sin(theta), ahol 0 <= theta < 2*PI, valamint az a és b a fél nagy- és kistengely. """ # Mivel egy ellipszis kerülete a féltengelyek összegével közelítőleg arányos, ezért a felbontást (pontsűrűséget) # a féltengelyek összegével arányosan növeljük, hogy elegendő pontot kapjunk a folytonos körvonal érzékeléshez. num_of_points = int(30 * (a + b)) dtheta = 2 * pi / num_of_points # A szögnövekmény. angles = (i * dtheta for i in range(num_of_points + 1)) # Az adott pontszámhoz tartozó szögek sorozata. # Az ellipszis pontjainak kirajzolása. for x, y in ((a * cos(theta) + center_point[0], b * sin(theta) + center_point[1]) for theta in angles): self.draw_point(x, y, outline_color) def run(self): self.mainloop() # TESZT oval_test_app = OvalTestApp() oval_test_app.draw_ellipse((300, 150),200, 120) oval_test_app.draw_oval((300, 150),(200, 120)) oval_test_app.draw_ellipse((300, 450),200, 80) oval_test_app.draw_oval((300, 450),(200, 80),fill_color='light green') oval_test_app.draw_ellipse((900, 300),240, 240, outline_color='red') oval_test_app.draw_oval((900, 300),(240, 240), fill_color='white') oval_test_app.run() |
Néhány változatra lefuttatva, a kirajzolt formákat a következő ábrán láthatjuk.

Az eredményképekből levonhatjuk a következtetést, hogy a Canvas create_oval() metódusa ellipszist (vagy speciálisan, ha a befoglaló négyszög egy négyzet, akkor egy kört) jelenít meg. Ha nem így lenne, akkor az oval alakzat az ábrán vagy kitakarná az ellipszis bizonyos pontjait vagy a vászon háttérszíne látszódna.
A grafikus felhasználói felület létrehozásával, benne a Canvas elem 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.