Час 4 - израчунавање координата¶
У досадашњим цртежима смо координате углавном очитавали помоћу миша или су унапред биле задате у тексту задатка. У овом поглављу ћемо видети како неке координате можемо израчунати на основу познавања неких других координата.
Однос између координата¶
У овом поглављу ће нам веома важан бити међусобни однос положаја и величина објеката на екрану. Увећавањем x координате објекти се померају надесно, умањивањем x координате на лево, умањивањем y координате померају се на горе, а увећавањем y координате, померају се на доле.
Одговори на наредна питања да провериш да ли ово добро разумеш.
- Q-27: Kоје су координате тачке која се налази 10 пиксела лево од тачке
(50,70)?
- Q-28: Kоје су координате тачке која се налази 10 пиксела испод тачке
(50,70), на истој вертикали?
Q-29: Правоугаоник је нацртан помоћу pg.draw.rect(prozor, boja, (100,
150, 80, 90))
. Како се може нацртати правоугаоник исте величине
који се налази 30 пиксела лево и 30 пиксела изнад овог правоугаоника?
Q-30: Круг је нацртан помоћу pg.draw.circle(prozor, boja, (100, 200),
40)
. Како се може нацртати круг исте величине који се налази
изнад овог круга и додирује га?
Симетрично пресликане координате¶
Често ће цртежи које цртамо бити симетрични у односу на неку хоризонталну или вертикалну праву. На пример, ако је прозор ширине 300 пиксела, тада је његова средина удаљена 150 пиксела од леве ивице. Ако желимо да два круга распоредимо симетрично око те средине екрана (на пример, желимо да то буду два ока) и ако први круг има центар у тачки (110,80), тада други круг треба да има центар у тачки (190,80). Наиме, хоризонтално растојање од леве тачке до средине треба да буде исто као хоризонтално растојање од те средине до десне тачке. Пошто је лево растојање једнако 150 - 110 = 40, зато десно растојање треба да буде једнако 150 + 40 = 190. Тачке су на истој висини, па им је y координата једнака. Веома слично се одређују координате и када је оса симетрије било која друга хоризонтална или вертикална права.
Поступак одређивања параметара правоугаоника и елипсе која је симетрично пресликана мало се разликује од оног за круг или дуж. Треба водити рачуна о томе да је горње лево теме правоугаоника описаног око тражене елипсе у ствари слика горњег десног темена правоугаоника описаног око познате елипсе.
Провери да ли ово разумеш тако што ћеш одговорити на следећих неколико питања.
Ако је прозор ширине 300 пиксела, које су координате тачке која је симетрична тачки (100, 100) у односу на вертикалну средину прозора (резултат напиши у облику уређеног пара)?
Ако је прозор висине 300 пиксела, које су координате тачке која је симетрична тачки (100, 100) у односу на хоризонталну средину прозора (резултат напиши у облику уређеног пара)?
- Q-32: У прозору ширине 600 пиксела, нацртан је правоугаоник помоћу
pg.draw.rect(prozor, boja, (150, 200, 80, 100))
. Како се може нацртати правоугаоник који је симетрична слика тог правоугаоника у односу на вертикалну средину екрана?
Утврди своје знање о симетричном пресликавању тачака тако што ћеш урадити наредни задатак.
Мачка¶
Напиши програм који црта главу мачке. Глава мачке је потпуно симетрична у односу на средину екрана.
Уши ове мачке могу да се прикажу као попуњени троуглови. Како се уши надовезују на главу, по два темена сваког троугла могу да буду изабрана са више слободе (довољно је да буду негде у глави). Осим два троугла који представљају уши, имамо још:
два круга (глава и врх њушке)
шест елипси (очи, зенице и делови њушке)
шест линија (бркови)
Приликом цртања користе се боје gray
, darkgray
, black
,
yellow
и green
.
Притисни дугме „Прикажи пример”, па очитај координате свих тачака. x-координате тачака на десној половини слике се не могу очитавати, али се могу израчунати користећи симетрију.
import pygame as pg, random
import pygamebg
(sirina, visina) = (300, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Мачка")
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(PyGame_practice1a_cat)
Центрирани правоугаоници и елипсе¶
Иако се цртање правоугаоника или елипсе врши тако што се задају координате горњег левог темена, често имамо потребу да нацртамо правоугаоник или елипсу којима су познате координате средишта и димензије. Размисли о томе како се то може урадити, па кроз наредна питања провери да ли си у праву.
Q-33: Знаш да желиш да нацрташ правоугаоник ширине 80 и висине 40 тако да му је центар у тачки 100 и 100. Коју наредбу можеш да употребиш за то?
Q-34: Да би се нацртала елипса са центром у тачки (80, 100), чије су полуосе 60 и 40 пиксела, потребно је извршити позив функције:
Прилагоди сада наредни програм тако што ћеш направити жути правоугаоник и плаву елипсу димензија 100 пута 80 пискела чији је центар у центру прозора, тј. тачки (150, 150).
import pygame as pg, pygamebg
(sirina, visina) = (300, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Центрирани правоугаоник и елипса")
prozor.fill(pg.Color("white"))
pg.draw.rect(prozor, pg.Color("yellow"), (???, ???, ???, ???))
pg.draw.ellipse(prozor, pg.Color("blue"), (???, ???, ???, ???))
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(centrirani_pravougaonici_i_elipse)
Сличан, али још мало компликованији задатак је да се нацрта правоугаоник познатих димензија, који је центриран унутар другог датог правоугаоника. Прво можеш да израчунаш средиште задатог, описаног правоугаоника, а затим да израчунаш координате горњег левог темена уписаног правоугаоника тако што од средишта одузмеш половину ширине и половину висине уписаног правоугаоника. Провери да ли ово разумеш, тако што ћеш одговорити на следеће питање.
Q-35: Правоугаоник плаве боје, ширине 40 и висине 30 пиксела треба да буде центриран у жутом правоугаонику чија је ширина 120 и висина 100 пиксела и чије је горње лево теме у тачки (130, 170). Како се тај правоугаоник може нацртати?
У наредном програму можеш и да провериш како ово функционише.
import pygame as pg
import pygamebg
(sirina, visina) = (300, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Правоугаоник у правоугаонику")
prozor.fill(pg.Color("white"))
pg.draw.rect(prozor, pg.Color("yellow"), (230, 270, 120, 100))
pg.draw.ellipse(prozor, pg.Color("blue"), (???, ???, ???, ???))
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(centrirani_pravougaonik_u_pravougaoniku)
У специјалном случају када је спољни правоугаоник цео прозор, правоугаоник можемо центрирати тако што му x координату горњег левог темена поставимо на половину разлике између ширине прозора и ширине правоугаоника, а y координату поставимо на половину разлике између ширине између висине прозора и висине правоугаоника. На тај начин слободан простор око правоугаоника равномерном распоређујемо на леву и десну, односно на горњу и доњу маргину.
Напиши програм који црта црвени квадрат димензије 200 пиксела, зелени димензије 150 пиксела и плави димензије 100 пиксела који су центрирани у прозору димензије 300 пута 300 пиксела.
import pygame as pg
import pygamebg
(sirina, visina) = (300, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Центрирани квадрати")
prozor.fill(pg.Color("white"))
# crveni kvadrat
# zeleni kvadrat
# plavi kvadrat
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(centrirani_kvadrati_u_prozoru)
Центрирана слика¶
Пошто су слике правоугаоног облика, оне се такође могу центрирати на унутар прозора на исти начин као и било који други правоугаоник.
Прилагоди програм који на екрану приказује слику мачке учитану из
датотеке macka.png
тако да та слика буде центрирана у средини
екрана.

Да би се слика приказала на средини екрана, очитавамо прво њене
димензије. То можемо урадити помоћу функција get_width()
и
get_height()
, које враћају ширину и висину слике. Координате се
онда добијају као половина разлике између димензија екрана и димензија
слике која се приказује (сличица је центрирана јер се празан простор
равномерно распоређује са његове обе стране).
# bojimo pozadinu u belo
prozor.fill(pg.Color("white"))
# učitavamo slicicu iz datoteke macka.png
slika = pg.image.load("macka.png")
# prikazujemo sličicu na sredini ekrana
(x, y) = ((sirina - slika.get_width()) / 2, (visina - slika.get_height()) / 2)
prozor.blit(slika, (x, y))
(ucitavanje_i_prikaz_slike_sredina)
Центрирани текст¶
Прилагоди програм који на екран исписује поруку „Здраво свете” тако да тај текст буде центриран у средини екрана.
Пошто желимо да текст буде центриран, ту позицију можемо израчунати
тако што одредимо прво ширину и висину текста. За то можемо поново
употребити функције get_width()
и get_height()
као и у случају
слике, а можемо употребити и функцију font.size()
чији је
параметар ниска чија се величина одређује. Координате левог угла се
онда одређује на исти начин као и у случају слике.
import pygame as pg
import pygamebg
(sirina, visina) = (300, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Zdravo svete!")
# bojimo pozadinu prozora u belo
prozor.fill(pg.Color("white"))
# font kojim će biti prikazan tekst
font = pg.font.SysFont("Arial", 40)
# poruka koja će se ispisivati
poruka = "Zdravo svete!"
# gradimo sličicu koja predstavlja tu poruku ispisanu crnom bojom
tekst = font.render(poruka, True, pg.Color("black"))
# određujemo veličinu tog teksta (da bismo mogli da ga centriramo)
(sirina_teksta, visina_teksta) = (tekst.get_width(), tekst.get_height())
# položaj određujemo tako da tekst bude centriran
(x, y) = (???, ???)
# prikazujemo sličicu na odgovarajućem mestu na ekranu
prozor.blit(tekst, (x, y))
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(font_sredina)
Пројекат - Кућица¶
Циљ овог пројекта је да направимо програм који црта кућицу. Приликом цртања кућице применићемо знање о израчунавању координата. Да би лакше дошли до крајњег решења, одговори на наредни низ питања која се сва односе на цртеж кућице.

Основу кућице чини жути правоугаоник ширине 180 и висине 160 пиксела. Ако је прозор у коме се црта димензије 300 пута 300 пиксела, ако је испод кућице остављена маргина од 20 пиксела и ако је правоугаоник хоризонтално центриран унутар прозора, кoje су координате горњег левог угла жутог правоугаоника (напиши их у облику уређеног пара)?
Изнад врха крова остављена је маргина од 20 пиксела. Које су координате тачке на којој се налази врх крова?
Q-36: Кров је нацртан у облику испуњеног многоугла (тј. троугла). Чиме се може допунити наредба за исцртавање pg.draw.polygon(prozor, pg.Color(„red”), ???) да би се нацртао кров.
Леви и десни прозор су распоређени симетрично. Које су координате горњег левог угла десног прозора, ако је леви прозор исцртан наредбом pg.draw.rect(prozor, pg.Color(„skyblue”), (80, 140, 50, 50)).
Q-37: Врата димензије 60 пута 80 пиксела су постављена симетрично у односу на средину кућице. Како се може израчунати положај горњег левог темена врата? Означи све поступке који су тачни.
Q-38: Која од наредних наредби исцртава хоризонталну линију на десном прозору.
Q-39: Желимо да нацртамо вертикалну црну дуж по средини левог прозора, који је нацртан као квадрат димензије 50, чије је горње лево теме у (80,140). Означи тврђења која исправно одређују координате те дужи.
На основу свега реченог можеш и да нацрташ кућицу.
import pygame as pg, random
import pygamebg
(sirina, visina) = (300, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Кућица")
# osnova kuće
# krov
# levi prozor
# desni prozor
# vrata
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(PyGame_house)
Домаћи задатак - Медведић¶
Напиши програм који исцртава главу играчкице медведића.
Задатак се решава пажљивим одређивањем координата свих
кругова. Кругови треба да буду испуњени одређеном бојом и затим
уоквирени танком црном кружницом. То постижемо тако што два пута
позовемо функцију pg.draw.circle
, први пут без прослеђеног петог
параметра који одређује дебљину кружнице (чиме постижемо да се црта
испуњен круг), а други пут са прослеђеним параметром дебљине (чиме
постижемо да се нацрта кружница). Да бисмо у избегли дуплирање кода,
дефинисаћемо помоћну функцију uokviren_krug
који ћемо позивати
приликом цртања медведа. Параметре ћемо јој наводити на исти начин као
код функције pg.draw.circle
. Потруди се да цртеж који нацрташ буде
апсолутно симетричан у односу на средину екрана.
import pygame as pg
import pygamebg
(sirina, visina) = (300, 300) # otvaramo prozor
prozor = pygamebg.open_window(sirina, visina, "Медведић")
# bojimo pozadinu prozora u belo
prozor.fill(pg.Color("white"))
# procedura kojom se crta obojen krug okruzen crnom kruznicom
def uokviren_krug(prozor, boja, centar, poluprecnik):
# crtamo ispunjen krug
pg.draw.circle(prozor, boja, centar, poluprecnik)
# uokvirujemo ga crnom kruznicom
pg.draw.circle(???, ???, ???, ???, ???)
# crtamo levo uvo
uokviren_krug(prozor, pg.Color("yellow"), (90, 80), 45)
# crtamo desno uvo
???
# crtamo glavu
uokviren_krug(prozor, pg.Color("yellow"), (150, 150), 100)
# crtamo njusku
???
# crtamo levo oko
uokviren_krug(prozor, pg.Color("black"), (100, 120), 15)
# crtamo desno oko
???
# crtamo nos
???
# prikazujemo prozor i čekamo da ga korisnik isključi
pygamebg.wait_loop()
(meda)