$$ \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.

Час 6 - релативне координате - утврђивање

На прошлом часу смо се упознали са релативно задатим координатама и предностима тог механизма цртања. Утврдимо ово кроз још неколико примера.

Саобраћајни знак од једнакостраничних троуглова

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

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

Приликом цртања саобраћајног знака потребно је да одредимо поступак којим се црта једнакостранични троугао ако му је познато сидро постављено у тежиште \(T\) за које ћемо претпоставити да има координате \((t_x, t_y)\) и ако му је позната димензија (то може бити било дужина странице \(a\), било висина \(h\), јер се из једне од ових димензија друга једноставно израчунава на основу чувене везе \(h = \frac{a\sqrt{3}}{2}\), која се лако изводи применом Питагорине теореме на правоугли троугао чија је једна катета висина једнакостраничног троугла, друга половина странице, а хипотенуза је страница једнакостраничног троугла).

../_images/jednakostranicanTrougaoZnak.png

Пошто, како из математике знамо, тежиште троугла дели тежишну дуж (у овом случају то је уједно и висина) у односу \(2:1\), координате темена \(A\) и \(B\) су у односу на ову тачку померене (транслиране) на горе за \(\frac{1}{3}h\), док је тачка \(C\) померена на доле за \(\frac{2}{3}h\).

Координате x ових тачака одређујемо у односу на тачку \(T\), односно дужину странице \(a\). Тачка \(А\) је померена од тежишта за \(\frac{а}{2}\) ка левој ивици прозора. Тачка \(В\) је померена од тежишта за \(\frac{а}{2}\) средину ка десној ивици. Тачка \(C\) се хоризонално налази на линији тежишта.

Дакле, тачка \(A\) има координате \((t_x-\frac{a}{2}, t_y-\frac{h}{3})\), тачка \(B\) има координате \((t_x+\frac{a}{2}, t_y-\frac{h}{3})\), док тачка \(C\) има координате \((t_x, t_y+\frac{2h}{3})\).

Пошто је потребно да нацртамо два троугла, можемо дефинисати функцију за цртање троугла и позвати је два пута (за исто тежиште, али различите боје и димензије). Тежиште ћемо поставити хоризонтално на средину прозора, док ћемо га вертикално поставити тако да троугао делује центриран по средини екрана. Оставићемо простор (маргину) од по 30 пиксела изнад и испод троугла, а тежиште троугла ћемо поставити тако да преосталу висину дели у односу 1:2.

На основу претходне дискусије допуни наредни програм.

Проблеми приликом израчунавања параметара кругова

Подсетимо се да за разлику од функција за цртање линија и правоугаоника које примају и реалне аргументе, функција за цртање кругова захтева да су координате центра круга и дужина полупречника искључиво цели бројеви. Ово може довести до одређених проблема у програмима у којима се ти аргументи израчунавају у програму. Када видиш поруку TypeError: integer argument expected, got float, тада знај да је проблем у томе што је функцији за цртање круга уместо целог прослеђен неки реалан број и тај проблем можеш лако решити коришћењем неког облика заокруживања бројева.

Зато ћемо често у задацима у којима цртамо кругове, за израчунавање координата центара и полупречника кругова уместо реалног дељења (оператора /) користити целобројно дељење (оператор //) или ћемо користити заокруживање реалних бројева (функцијом round или функцијом int).

Провери да ли ово разумеш тако што ћеш одговорити на наредно питање.

    Q-38: Након позива pg.draw.circle(prozor, boja, (x, y), r) пријављена је грешка TypeError: integer argument expected, got float. Шта може бити узрок те грешке?

  • Није наведен добар број параметара у позиву функције `pg.draw.circle`
  • Покушај поново
  • Координате центра не могу бити реални бројеви
  • Тачно
  • Редослед параметара у позиву није исправан
  • Покушај поново
  • Полупречник круга не сме да буде негативан број
  • Покушај поново
  • Потребно је навести још дебљину кружнице
  • Покушај поново

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

Цвет

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

../_images/roze_cvet.png

За цртање круга потребно је знати координате центра и дужину полупречника круга. Пречник свих кругова је једнак, самим тим и полупречник \(r = \frac{a}{2}\). Нека је тачка О центар жутог, централног круга. Координате ове тачке означимо са \((c_x, c_y)\). Ова тачка се налази у центру прозора и њене координате једнаке су половини висине, односно ширине прозора. Координате осталих центара кругова изразићемо такође преко координата \((c_x, c_y)\) . Координате тачке \(А_1\) означимо са \((x_1, y_1)\). Тачка \(А_1\) је за \(a\) померена (транслирана) од тачке О по оси \(x\), тако да је \(x_1\), прва координата ове тачке једнака \(x_1 = c_x + a\), а друга координата ове тачке \(y_1\) једнака је \(y\) координати тачке О, тј. \(y_1 = c_y\). Координате тачке \(А_2\) означимо са \((x_2, y_2)\). Ова тачка је у односу на тачку О померена (транслирана) за \(\frac{a}{2}\) по оси \(x\), односно за висину \(h = \frac{a \sqrt{3}}{2}\) једнакостраничног троугла \(\triangle OA_1A_2\) по оси y. На основу овога закључујемо да су координате тачке \(А_2\), \((x_2, y_2) = (c_x+\frac{a}{2}, c_y + h)\). Координате центра осталих кругова одређујемо на сличан начин.

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

Прелазак са апсолутних на релативне координате

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

На пример, ако се црта круг помоћу pg.draw.circle(prozor, boja, (cx, cy), r), тада га можемо усидрити у тачку (x, y) тиме што позив заменимо са pg.draw.circle(prozor, boja, (x + (cx - x), y + (cy - y)), r). На пример, Ако круг нацртан помоћу pg.draw.circle(prozor, boja, (100, 50), r) желимо да усидримо у тачку (x, y) = (50, 100), тада ћемо га цртати помоћу pg.draw.circle(prozor, boja, (x + 50, y - 50), r). Слично можемо урадити и у случају осталих облика.

Провери да ли ово разумеш тако што ћеш одговорити на наредних неколико питања.

    Q-39: Желимо да прилагодимо цртеж који се састоји од наредних облика, тако да се све црта у односу на сидро са координатама x=100, y=100.

    Које наредбе ће бити део прилагођеног цртежа?

  • pg.draw.circle(prozor, pg.Color("red"), (x, y), 50, 1)
  • Тачно
  • pg.draw.line(prozor, pg.Color("red"), (x-50, x-50), (150, 150))
  • Покушај поново
  • pg.draw.line(prozor, pg.Color("red"), (x+50, y-50), (x-50, y+50))
  • Тачно
  • pg.draw.rect(prozor, pg.Color("red"), (x-50, y-50, x, y))
  • Покушај поново

    Q-40: Круг нацртан наредбом pg.draw.circle(prozor, boja, (180, 80), 60) део је цртежа који желимо да прилагодимо тако да му основна тачка (сидро) буде у одређено променљивама x = 100 и y = 100. Која наредба ће бити део тако прилагођеног цртежа?

  • pg.draw.circle(prozor, pg.Color("red"), (x, y), 60)
  • Покушај поново
  • pg.draw.circle(prozor, pg.Color("red"), (180, 240), 60)
  • Покушај поново
  • pg.draw.circle(prozor, pg.Color("red"), (100, 100), 60)
  • Покушај поново
  • pg.draw.circle(prozor, pg.Color("red"), (x + 80, y - 20), 60)
  • Тачно
  • pg.draw.circle(prozor, pg.Color("red"), (x + 180 , y + 240), 60)
  • Покушај поново

Покрени сада наредни програм и видећеш лице човечуљка. Прилагоди цртеж тако да се црта релативно у односу на сидро које се налази у центру плавог круга (у почетку је то \((100, 100)\)). Покретањем програма провери да ли ти је решење добро. Ако је све урађено како треба, цртеж ће се исправно померати док се миш помера.

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

    Q-41: Круг нацртан наредбом pg.draw.circle(prozor, boja, (180, 80), 60) део је цртежа који желимо да прилагодимо тако да му главна тачка (сидро) буде у одређено променљивама x = 100 и y = 100, и да му основна величина буде a=5. Која наредба ће бити део тако прилагођеног цртежа?

  • pg.draw.circle(prozor, pg.Color("red"), (x, y), 12*a)
  • Покушај поново
  • pg.draw.circle(prozor, pg.Color("red"), (x - 36*a, x - 48*a), 12*a)
  • Покушај поново
  • pg.draw.circle(prozor, pg.Color("red"), (x + 16*a, y - 4*a), 12*a)
  • Тачно
  • pg.draw.circle(prozor, pg.Color("red"), (20*a, 20*a), 60)
  • Покушај поново
  • pg.draw.circle(prozor, pg.Color("red"), (x + 16*a , y - 4*a), 60)
  • Покушај поново

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