Zadanie

Ako je možné, že zadania kategórie Z a O boli hotové už v auguste a v polovici septembra sa stále nedali odovzdávať riešenia? Lebo KSPáci prerábajú celú stránku (stará stránka zostarla a pokazila sa). Prerábacie práce idú pomalšie ako sme si pôvodne mysleli a teda niektoré veci meškajú. Odovzdávanie príkladov na novej stránke už funguje, ale mnohé časti stánky stále nie sú v použiteľnom stave, čo teda znamená, že odovzdávať nemôžete.

Jednou z vecí, ktorá na novej stránke chýba je dizajn. No a viete ako to chodí, na robenie dizajnu treba vedieť písať v CSS, ktoré väčšina vedúcich neovláda a tí čo ho ovládajú musia robiť iné veci.

Ale vy, účastníci, ste veľmi šikovné deti a určite nám s tým CSSkom trochu pomôžete. Aby stánka nebola nudná, ale akčná a ohromujúca, potrebujeme, aby sa všetky tlačidlá mohli otáčať a zväčšovať.

Úloha

Tlačidlo si pre jednoduchosť predstavíme ako obdĺžnik. Obyčajné nezväčšené tlačidlo vieme nastaviť tak, že mu nastavíme rozmery a pozíciu. V CSS na to slúžia atribúty width (šírka), height (výška), left (vzdialenosť od ľavého okraja obrazovky) a top (vzdialenosť od horného okraja obrazovky).

Keď chceme aby bolo tlačidlo väčšie či menšie, jednoducho mu správne nastavíme width a height. Ak chceme tlačidlo otočiť, použijeme na to transform: rotate(Udeg), čo otočí tlačidlo okolo jeho stredu o uhol U stupňov v smere hodinových ručičiek. Dôležité je, že táto transformácia sa udeje až po tom, ako sa tlačidlo umiestni podľa left, top, width a height.

Nám však otáčanie okolo stredu nestačilo, a potrebujeme tlačidlá otáčať podľa rôznych bodov. Popis tlačidla si predstavujeme takto:

  1. Najprv tlačidlu určíme rozmery \((w,h)\) a pozíciu ťažiska \((x_t,y_t)\) – jeho vzdialenosti od ľavého a horného okraja obdĺžnika.
  2. Následne určíme pozíciu ťažiska na obrazovke, \((x_o, y_o)\).
  3. Potom tlačidlo otočíme okolo ťažiska v smere hodinových ručičiek o uhol \(\alpha\).
  4. Napokon tlačidlo zväčšíme okolo ťažiska \(s\) násobne.

Na vstupe dostanete popis tlačidiel podľa našej predstavy a vašou úlohou je vygenerovať CSS kód, ktorý zobrazí tlačidlá správne.

Formát vstupu

Na prvom riadku vstupu je číslo \(n\) udávajúce počet tlačidiel. Nasleduje \(n\) riadkov, z ktorých každý popisuje jedno tlačidlo. Popis tlačidla pozostáva z 8 čísel, \(w\), \(h\), \(x_t\), \(y_t\), \(x_o\), \(y_o\), \(\alpha\), \(s\), pričom prvých \(7\) čísel je celých a posledné čislo je reálne, s presne jednou cifrou za desatinnou čiarkou. Čísla su udávané v pixloch. Platí, že \(1\leq w, h\leq 1000\), \(0\leq x_c \leq w\), \(0\leq y_c\leq h\), \(0\leq x_o, y_o\leq 1000\), \(0\leq\alpha<360\), \(0 < s\leq 10\).

Formát výstupu

Pre kazdé tlačidlo na vstupe vypíšte jeden riadok – CSS príkaz na zobrazenie tlačidla vo formáte: “.itemN {width: Wpx; height: Hpx; left: Lpx; top: Tpx; transform: rotate(Udeg); }”.

To znamená, že \(N\)-té tlačidlo s rozmermi \((W,H)\) sa najprv umiestni tak, aby jeho ľavý horný roh bol na pozícii \((L,T)\) a následne sa otočí okolo svojho stredu o \(U\) stupňov. Rozmery a pozíciu píšeme v pixloch.

Formát musíte dodržať presne, všetky čísla musia mať presne jednu cifru za desatinnou čiarkou (výsledok zaokrúhlite) a musí platiť, že \(0\leq U <360\).

Príklad

Input:

2
200 100 50 75 400 200 45 0.5
200 100 50 75 400 200 90 2.0

Output:

.item1 { width: 100.0px; height: 50.0px;  
left: 376.5px; top: 183.8px; 
transform: rotate(45.0deg); }
.item2 { width: 400.0px; height: 200.0px; 
left: 250.0px; top: 200.0px; 
transform: rotate(90.0deg); }

V ukážkovom výstupe je z technických príčin každý riadok rozdelený na tri. Váš program má vypísať jedno pravidlo len na jeden riadok.

Zistiť skutočné rozmery a uhol otočenia tlačidla je triviálne. Takže ostáva vypočítať left a top teda pozíciu ľavého horného rohu obdĺžnika pred otočením okolo stredu.

  1. krok je vypočítať, ako sa musíme pohnúť z bodu \((x_0, y_0)\) aby sme sa dostali do stredu obdĺžnika. Zoberieme vektor \((x_t, y_t) - (\frac{w}{2}, \frac{h}{2})\), vynásobíme ho \(s\)-kom a otočíme o uhol \(\alpha\). Vzorec na otáčanie vektora si môžete ľahko spočítať na papieri alebo ak používate C++, môžete využiť komplexné čísla. Keď bod \((x_0, y_0)\) posunieme o tento otočený vektor, dostaneme sa do stredu obdĺžnika. Všetky uvedené premenné \(w\), \(h\), \(x_t\), \(y_t\), \(x_0\), \(y_0\), \(s\) a \(\alpha\) máme uvedené na vstupe.

  2. krok je posunúť sa zo stredu obdĺžnika o \(\frac{w s}{2}\) vľavo a o \(\frac{h s}{2}\) hore a sme v ľavom hornom rohu obdĺžnika.

Toto bolo celé riešenie. Také jednoduché! Jeho časová zložitosť je \(O(1)\) na tlačidlo, dokopy o \(O(n)\).

Keď implementujete geometrické úlohy, najmä tie zložitejšie, oplatí sa naprogramovať si vlastnú štruktúru bod a pretypovať si operátory \(+\) a \(-\), aby sa vám body ľahko sčítavali a naprogramovať si funkcie na otáčanie bodov, skalárny súčin, vektorový súčin a ďalšie, ktoré sa v geometrii často používajú. Bod a vektor samozrejme považujeme za to isté.

Najmä v zložitejších úlohách vám to zjednoduší kód a ušetríte tým mnoho času a chýb.

Diskusia

Tu môžte voľne diskutovať o riešení, deliť sa o svoje kusy kódu a podobne.

Pre pridávanie komentárov sa musíš prihlásiť.