$$ \newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} \newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} \renewcommand{\mod}{\,\mathrm{mod}\,} \renewcommand{\div}{\,\mathrm{div}\,} \newcommand{\metar}{\,\mathrm{m}} \newcommand{\cm}{\,\mathrm{cm}} \newcommand{\dm}{\,\mathrm{dm}} \newcommand{\litar}{\,\mathrm{l}} \newcommand{\km}{\,\mathrm{km}} \newcommand{\s}{\,\mathrm{s}} \newcommand{\h}{\,\mathrm{h}} \newcommand{\minut}{\,\mathrm{min}} \newcommand{\kmh}{\,\mathrm{\frac{km}{h}}} \newcommand{\ms}{\,\mathrm{\frac{m}{s}}} \newcommand{\mss}{\,\mathrm{\frac{m}{s^2}}} \newcommand{\mmin}{\,\mathrm{\frac{m}{min}}} \newcommand{\smin}{\,\mathrm{\frac{s}{min}}} $$

Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link.
Nažalost nismo trenutno u mogućnosti da obradimo vaš zahtev.
Molimo vas da pokušate kasnije.

Час 5 - релативно задавање координата и димензија

Померање објеката по екрану

Често цртеж који нацртамо није на одговарајућој позицији и желимо да га померимо. Прилагоди наредни пример тако да се сви објекти који сачињавају цртеж кућице помере за 100 пиксела на горе тако да цртеж кућице буде центриран (као када притиснеш дугме „Прикажи пример”).

Пре него што пређеш на решавање тог задатка, подсети се још једном каква је веза између промене положаја објеката и промене њихових координата тако што ћеш одговорити на наредна питања.

    Q-35: Желимо да померимо цртеж који се састоји од неколико облика надесно за 100 пиксела. Означи тачна тврђења.

  • Уместо pg.draw.circle(prozor, boja, (x, y), r, d) позваћемо pg.draw.circle(prozor, boja, (x+100, y), r, d).
  • Тачно
  • Уместо pg.draw.circle(prozor, boja, (x, y), r, d) позваћемо pg.draw.circle(prozor, boja, (x-100, y-100), r, d).
  • Покушај поново
  • Уместо pg.draw.rect(prozor, boja, (x, y, w, h), d) позваћемо pg.draw.circle(prozor, boja, (x+100, y, w+100, h), d).
  • Покушај поново
  • Уместо pg.draw.rect(prozor, boja, (x, y, w, h), d) позваћемо pg.draw.rect(prozor, boja, (x+100, y, w, h), d).
  • Тачно
  • Уместо pg.draw.rect(prozor, boja, (x, y, w, h), d) позваћемо pg.draw.rect(prozor, boja, (x-100, y, w, h), d).
  • Покушај поново
    Како се помера објекат ако му се координате промене на следећи начин? Покушај поново!
  • помера се на горе
  • умањује се :math:`y` координата
  • помера се на доле
  • увећава се :math:`y` координата
  • помера се на лево
  • умањује се :math:`x` координата
  • помера се на десно
  • увећава се :math:`x` координата

У складу са овим, промени координате тако да се кућица помери.

Да би се кућица подигла за 100 пиксела на горе, потребно је од сваке \(y\) координате одузети 100.

Дакле, померање објеката по екрану није тешко (своди се на увећавање или умањивање неких координата), међутим, да би се цео цртеж померио потребно је променити координате свих објеката који чине цртеж, што може бити мукотрпно ако се цртеж састоји од великог броја објеката.

Повећавање и смањивање објеката

Често цртеж желимо да прилагодимо тако што ћемо га скалирати (смањити или повећати). Ако желимо да нацртамо двоструко већи круг, потребно је навести двоструко већи полупречник, а ако је потребно нацртати двоструко већи правоугаоник, потребно је навести двоструко већи већу дужину и ширину. Испробај ово на следећем цртежу тако што ћеш смањити димензије правоугаоника на 50, а полупречник круга на 25.

Као што видиш, објекти су се смањили, али круг више није уписан у правоугаоник и цртеж не изгледа више како би требало да изгледа (центар круга и горње лево теме правоугаоника су остали непромењени). Скалирање дужи и многоуглова је још теже, јер се у њима не користе димензије, већ само координате тачака.

Дакле, да бисмо смањили или повећали цртеж, потребно је да мењамо и димензије, али и координате које одређују положај објеката. Испробај шта би се десило када би сваки од бројева који се користе приликом цртања био помножен или подељен истим бројем.

    Q-36: Сви бројеви који се односе на координате и на величине у једном цртежу су подељени са 2. Како ће тиме да се промени цртеж?

  • Цртеж ће се дупло смањити и помериће се ка горњем левом углу прозора.
  • Тачно
  • Цртеж ће се дупло смањити и остаће на истом месту.
  • Покушај поново
  • Цртеж ће остати исте величине и помериће се ка доњем десном углу прозора.
  • Покушај поново
  • Цртеж ће се дупло повећати и помериће се ка горњем левом углу прозора.
  • Покушај поново

Множењем свих аргумената функција истим бројем, дакле, успешно скалирамо цртеж, међутим, цртеж уједно бива померен, што је понекад непожељно. Скалирање цртежа уз задржавање положаја генерално није једноставно учинити, међутим, у наставку ћемо видети како да цртеже направимо тако да их лако можемо и померати и скалираити.

Израчунавање координата у односу на главну тачку и димензију

У досадашњим примерима смо у функцијама за цртање координате задавали навођењем конкретних бројевних вредности (на пример, 100, 50, 20). За такве цртеже рећи ћемо да су задати коришћењем апсолутних координата. У наставку ћемо видети да је често и лакше и боље да се координате представљају променљивама и то тако да се све координате израчунавају само на основу координата једне карактеристичне тачке коју ћемо називати главна тачка или сидро (енгл. anchor) и на основу димензије цртежа. То ће нам омогућити да цео цртеж померамо само изменама координата главне тачке и да га скалирамо само променом димензије, али и да лако нацртамо више идентичних цртежа чији се положај и величина може разликовати. За такве цртеже рећи ћемо да су задати коришћењем релативних координата.

Слово М

Напиши програм који помоћу дужи исцртава слово M.

Приликом цртања слова А координате смо очитали са цртежа и директно унели у програм. Сада ћемо нацртати слово М. Да би дужи биле лепо поравнате, потребно је да две горње тачке буду на истој висини и да две доње тачке буду на истој висини, да су две леве тачке на истој ширини и да су две десне тачке на истој ширини и да је средња тачка по ширини тачно на средини између левих и десних тачака.

../_images/slovoM.png

Ако мало боље проучимо положај 5 карактеристичних тачака можемо видети да све оне користе само три могуће вредности координате \(x\) (на пример, 50, 100 и 150) и само три могуће вредности координате \(y\) (на пример, 50, 120 и 150). Ове вредности можемо представити променљивама gore, dole, levo, desno, sredina_x и sredina_y, које на почетку програма иницијализујемо (постављамо) на одговарајуће вредности. Предност оваквог писања кода је у томе да ако буде потребе да се промени положај или величина слова М можемо то постићи изменом вредности променљивих којима су координате описане (промена на једном месту). Прва усправна дуж која гради слово М задата је координатама (levo, gore) и (levo, dole). Права паралелна овој дужи описана је координатама (desno, gore) и (desno, dole), а унутрашње дужи са (levo, gore), (sredina_x, sredina_y) и (desno, gore).

Можемо отићи и један корак даље и све координате израчунати само на основу положаја једне карактеристичне тачке цртежа и његове димензије. На пример, за карактеристичну тачку можемо узети тачку у средини, у којој се спајају две косе линије. Тако одабране карактеристичне тачке цртежа називају се сидра.

Сада вома једноставно можемо да променимо димензију и положај слова М. Поиграј се мало са вредношћу променљивих dim, sredina_x и sredina_y и посматрај како се мења нацртано слово. Дакле, када је цртеж нацртан релативно, у односу на неко сидро и димензију, он се лако може померати по екрану и скалирати, само тако што му се промени вредност сидра. Ово нам омогућава да цртање издвојимо у функцију која као параметре прихвата координате сидра и димензију и тако можемо лако нацртати неколико појављивања истог облика.

Облак

Круговима можемо нацртати и неке занимљиве облике. Нацртајмо сунце и облак на плавом небу.

Облак

Данас се мало наоблачило. На основу претходног програма дефинисаћемо функцију која исцртава облак на задатој позицији, задате величине, у задатој нијанси сиве боје, а затим ћемо је неколико пута позвати да бисмо нацртали неколико облака.

Приметимо да смо облак нацртали помоћу три круга и да су координате и полупречници ових кругова задати апсолутно, помоћу конкретних бројева. Да бисмо омогућили цртање неколико облака различитог положаја и величине, потребно је да пређемо на релативно задате координате. Природно је да за сидро узмемо центар средишњег круга, а да за димензију облака узмемо његов полупречник. Из претходног примера се може видети да се полупречник мањих кругова добија множењем већег полупречника са \(\frac{5}{8}\). Такође, видимо да су центри тих кругова на истој висини као центар великог круга и да се налазе на кружници. Стога, ако претпоставимо да велики круг има центар у тачки \((x, y)\) и да му је полупречник r, тада први мали круг има центар у тачки \((x-r, y)\), а други у тачки \((x+r, y)\) и оба имају полупречник \(\frac{5r}{8}\).

../_images/oblak.png

На основу овога можемо једноставно дефинисати функцију која црта облак и затим је неколико пута позвати.

Домаћи задатак - глава робота

Нацртај наранџасту главу робота квадратног облика, која има црне очи и уста правоугаоног облика.

Глава робота

Претходни програм приказује тражену главу робота. Желимо да глава буде центрирана унутар прозора. Такође, желимо да уста центрирамо хоризонтално унутар главе. Подсетимо се зато, за почетак, како то можемо нацртати правоугаоник ако су му познате координате центра (овај пут помоћу релативних координата).

    Q-37: Знаш да желиш да нацрташ правоугаоник ширине a и висине b тако да му је центар у тачки cx и cy. Коју наредбу можеш да употребиш за то?

  • pg.draw.rect(prozor, boja, (cx, cy, a, b))
  • Покушај поново
  • pg.draw.rect(prozor, boja, (cx, cy, 2*a, 2*b))
  • Покушај поново
  • pg.draw.rect(prozor, boja, (cx - a/2, cy - b/2, a, b))
  • Тачно
  • pg.draw.rect(prozor, boja, (cx - a, cy - b, 2*a, 2*b))
  • Покушај поново

Прикажимо математичке операције којима смо израчунали све потребне координате када смо цртеж задавали у апсолутним координатама. Прозор је димензија 300 пута 300 пиксела, а глава робота 200 пута 200 пиксела. То значи да на маргине одлази по 50 пиксела и стога се горње лево теме главе робота налази у тачки са координатама \((50, 50)\). Можемо приметити да су ширина два ока и ширина размака око очију (размаци од ивице главе до очију и размак између очију) једнаки. Дакле, укупно 5 ширина ока тј. размака испуњава ширину главе робота, одакле следи да су и ширина ока и ширина размака око очију једнаке петини ширине главе, тј. 40 пиксела. Претпоставићемо да је то уједно и висина ока (јер су очи квадратног облика), као и димензија размака од горње ивице главе робота до горње ивице очију, тако да ће се горње лево теме левог ока налазити у тачки са координатама \((90, 90)\) (величина размака је додата на обе координате горњег левог темена главе), а горње лево теме десног ока налазити у тачки са координатама \((170, 90)\) (на координату \(x\) горњег левог темена левог ока која је једнака 90 додата је ширина ока од 40 пиксела и ширина размака између очију која је такође 40 пиксела). Претпоставићемо да су уста исте висине као и око, али двоструко шира од њега, да је размак од дна уста до дна главе исти као размак између врха главе и врха очију и да су уста хоризонтално центрирана. Пошто је вертикална средина екрана на линији са координатом \(x\) која је једнака 150, координате горњег левог темена уста су \((110, 170)\) (прва је добијена тако што је од координате \(x\) средине прозора одузета половина ширине уста, а друга је добијена тако што је од координате \(y\) дна уста одузета величина размака и висина уста).

Програм можемо прилагодити тако да се све координате аутоматски рачунају на основу правила које смо применили у претходној рачуници, на основу сидра (cx, cy) постављеног у средиште прозора и на основу димензије екрана. Тиме ћемо постићи да цео цртеж робота може лако да мења величину и свој положај на екрану (величина ће зависити само од димензије главе, а положај само од координата центра главе тј. сидра које је за почетак постављено у центар прозора).

../_images/glava_robota.png

Допуни наредни програм, а затим мењај димензију главе и њен центар и посматрај како се мења слика на екрану.

Домаћи задатак - Роботица Мица

Ако ти је претходни задатак био интересантан и желиш још мало да вежбаш рад са координатама, настави у истом духу и реши и наредни задатак.

Напиши програм који исцртава целу роботицу Мицу (као што је приказано на слици). Tело (труп) јој је квадратног облика, центар му се налази у центру екрана, а димензија му је задата променљивом telo. Остале димензије су већ задате у програму који треба да допуниш, а ти треба да одредиш неке недостајуће координате.

../_images/robot_koordinate.png

Програм је могао бити можда мало једноставнији да смо наводили апсолутне координате (конкретне бројеве), међутим, чињеница да смо све координате рачунали на основу датих координата центра и величине тела робота нам омогућава да исти програмски кôд употребимо за цртање неколиико робота. Потребно је да цртање издвојимо у функцију, чији ће параметри бити центар и димензија тела робота.