Тема: створення моделей рівномірного прямолінійного руху об’єкта, руху об’єкта на площині з перешкодами та з вибором шляху мовою PHP.
Мета: надати учням приклад створення моделі руху об’єкта на площині з перешкодами мовою PHP.
Обладнання: комп'ютери зі встановленими ОС, браузером, середовищем програмування мовою PHP (наприклад, XAMPP), ImageMagick, APNG Assembler, Apng2gif, (дана) інструкція.
Структура уроку
Хід уроку
1. Організаційний момент
Вітання з класом. Перевірка присутності і готовності учнів до уроку. Перевірка виконання домашнього завдання.
2. Актуалізація опорних знань
Дати тлумачення таким вказівкам мовою PHP.
for ($i=1; $i<4, $i++) {…;} switch ($i) { case 0: $i=0; break; case 1: $i=11; break; case 2: $i=222; break; } if ($b) $i=0; else $i=1; $t = new Array(); $t[count($t)] = $x;
Порівняти з очікуваним.
3. Вивчення нового матеріалу
Створення комп'ютерної моделі рівномірного прямолінійного руху об’єкта на площині з оминанням перешкод
передбачає:
або кожного разу перевантажувати сторінку із зображенням і змиритися з мерехтінням екрану;
або всі зображення звести в один файл gif-анімації, який завантажити один раз і демонструвати анімацію без мерехтіння екрану.
Надалі буде описано втілення другого способу.
GIF (Graphics Interchange Format — «формат обміну зображеннями») — 8-бітний растровий графічний формат, що використовує до 256 чітких кольорів із 24-бітного діапазону RGB.
Формат було розроблено компанією CompuServe у 1987 році, і з того часу набув широкої популярності у всесвітній павутині завдяки своїй відносній простоті та мобільності. Одними з головних особливостей формату є підтримка анімації та прозорості. Для стискання файлів використовує LZW-компресію.
На момент упорядкування цього тексту вбудовані функції PHP не даювали можливості створити gif-анімацію (Graphics Interchange Format), а додаткові бібліотеки (GifCreator, GIFEncoder) не були сумісними з акуальними версіями PHP+XAMPP. За цих умов виявилося доцільним використати можливості багато платформного засобу
ImageMagick, який можна запустити вказівкою Терміналу.
Створення gif-анімації вказівкою Терміналу:
згідно з переліком у файлі order.txt :
convert -delay 100 -loop 0 @order.txt r.gif
Примітка. Істотний недолік першого підходу полягає у тому, що порядок: 1, 10, 100, 11, 12, ... , 2, 20, 21 ..., який використовує Magic Image для заміщення зірочки *, видається неприродним для пересічного користувача. Якщо занумерувати файли кадрів багатоцифровими числами у порядку бажаної появи, отримаємо результат, далекий від бажаного — зі стрибками вперед і назад у часі. Для подолоння цього недоліку можна використати другий спосіб. Але при довгій послідовності кадрів буде використано лише перші (370 для послідовності кадрів, що виникне при розв'язанні завдання 4 — див. далі). На жаль, пояснення цього факту (наприклад, наявність якихось обмежень на довжину чи об'єм послідовності) на момент упорядкування тексту не виявлено.
APNG (Animated Portable Network Graphics — анімована переносна графіка мереж) — формат зображень, побудований на форматі PNG, що передбачає можливість зберігання анімації (аналог GIF) і кольорів прозорості (8 біт на противагу одному прозорому кольору в GIF-зображенні). Розширення назви файлу — png.
APNG Assembler — консольна програма перетворення послідовності файлів PNG у формат APNG.
Виклик програми без вказання джерела вказівкою Терміналу apngasm призводить до виведення на екран такої довідки використання:
APNG Assembler 2.91 Usage : apngasm output.png frame001.png [options] apngasm output.png frame*.png [options] Options : 1 10 : frame delay is 1/10 sec. (default) -l2 : 2 loops (default is 0, forever) -f : skip the first frame -hs## : input is horizontal strip of ## frames (example: -hs12) -vs## : input is vertical strip of ## frames (example: -vs12) -kp : keep palette -kc : keep color type -z0 : zlib compression -z1 : 7zip compression (default) -z2 : Zopfli compression -i## : number of iterations (default -i15)
У перекладі українською це виглядає так:
Використання: apngasm output.png frame001.png [параметри] apngasm output.png frame*.png [параметри] Параметри: 1 10 : затримка кадру становить 1/10 сек. (за замовчуванням) -l2 : 2 петлі (як усталено 0, завжди) -f : пропустити перший кадр -hs## : введення - горизонтальна смуга ## кадрів (приклад: -hs12) -vs## : введення - вертикальна смуга ## кадрів (приклад: -vs12) -kp : зберегти палітру -kc : зберегти кольоротип -z0 : стиснення zlib -z1 : стиснення 7zip (як усталено) -z2 : стиснення Zopfli -i## : кількість ітерацій (як усталено -i15)
Наразі формат анімованого PNG підтримано браузерами Mozilla Firefox i Opera. Решта браузерів відображають зазвичай лише перший кадр. Тому є сенс перетворювати анімований PNG у GIF, який успішно відображають усі сучасні браузери.
Apng2gif консольна програма перетворення APNG у формат GIF.
Виклик програми без вказання джерела вказівкою Терміналу apng2gif призводить до виведення на екран такої довідки використання:
apng2gif 1.8 Usage : apng2gif anim.png [anim.gif] [-t tlevel] [-b bcolor] tlevel: transparency threshold level (format: -t 128) bcolor: background blend color (format: -b "#808080" or -b 128 128 128) When -b is used, -t is ignored. Default is -t 128, no bcolor.
У перекладі українською це виглядає так:
Використання: apng2gif anim.png [anim.gif] [-t tlevel] [-b bcolor] tlevel: пороговий рівень прозорості (формат: -t 128) bcolor: колір змішування тла (формат: -b "# 808080" або -b 128 128 128) При використанні -b буде знехтувано -t. Як усталено -t 128, без bcolor.
При великій кількості кадрів може виникнути проблема некоректного вказівника (на кадр) — див. приклад виведення повідомлення про переривання перетворення на даних завдання 4.
apng2gif 1.8 Reading 'output.png'... 6323 frames. 3 colors. Writing 'output.gif'... free(): invalid pointer Перервано (збережено знімок оперативної пам’яті)
Тому на момент упорядкування цього тексту при виконанні завдання 4 ми обмежимося створенням анімованих png, поданих на початку цього розділу.
Виклик вказівки Терміналу з коду PHP має такий синтаксис:
exec ($command, $output, $code);
Тут:
$command — рядок, в якому записано вказівку;
$output — масив, який буде заповнено рядками виведення. Якщо масив вже містить будь-які елементи, то exec додасть нові елементи в кінець масиву;
code — код статус повернення.
Вказівка exec повертає останній рядок з результату вказівки, false — у разі виникнення помилки.
При спробі вказівкою PHP викликати вказівку Терміналу для породження анімованого PNG упорядник зіткнувся з невиконанням цієї вказівки без жодного повідомлення про негаразди. Хоча та сама вказівка Терміналу, введена з клавіатури, працює бездоганно. Тому авторське розв'язання завдання 4 не містить такого завершення:
$out = array();// масив для виведення вказівки Терміналу $code = 0; // код повернення вказівки Терміналу // "склеювання" кадрів r*.png в одну gif-анімацію exec("apngasm output.png r*.png",$out,$code); echo "<center><img src='output.png'></center>";
Але таке завершення стане слушним після вирішення проблеми запуску утиліти apngasm з коду PHP.
4. Інструктаж з ТБ
5. Вироблення практичних навичок
Завдання 1. Скласти алгоритм руху об’єкта прямокутним полем з оминанням перешкод (наприклад, відрізків прямих ліній) при таких обмеженнях:
рух можливий лише як зміна абсциси або ординати центра об'єкта на деяку сталу величину s. Інакше кажучи, як стрибок по між сусідніми вузлами деякої ґратки, що розбиває площину на квадрати з довжиною сторони s;
дані про перешкоди в алгоритм можуть надходити лише як відповідь на запит про можлимість руху на відстань s по горизонталі чи вертикалі з поточного розташування;
у початковий момент рухомий об’єкт дотикається до середини лівої межі прямокутного поля;
у кінцевий момент рухомий об’єкт має дотикатися правої сторони поля.
Вхідні дані (розташування перешкод і співвідношення між розмірами поля, об'єкта й величиною стрибка) ґарантують існування розв'язку — відповідної траєкторії руху.
Створений за допомогою конкурсу ідей алгоритм проходження лабіринту у темноті без його схеми порівняти з очікуваним.
Алгоритм (діяти до досягнення правої сторони поля)
Обійти перешкоду, полишаючи її праворуч, і знайти на шляху точку, з якої можна почати рух праворуч або почати обхід іншої перешкоди, розташованої (хоча б частково) правіше від поточної перешкоди. Інакше кажучи, поки не досягнуто правого краю поля або останнього розташування кроку, запам'ятованого на кроці 4, робити таке у кожному розташуванні об'єкта:
запам'ятати розташування у порядку обходу перешкоди;
якщо розташування — правіше від усіх пройдених, тобто абсциса (центра) об'єкта найбільша з усіх досягнутих, запам'ятати його місце у траекторії;
наступне переміщення здійснити у першому з можливих напрямків, заданих такою послідовністю різниць кутових аргументів нового напрямку і попереднього (напрям вимірювання традиційний — проти напрямку руху годинникової стрілки):
Змінити номер стану гри на 2 — об'єкт рухається у «точку відриву» від перешкоди, тобто у розташування з найбільшою абсцисою при обході останньої перешкоди.
Повернутися у «точку відриву».
Очистити пам'ять, відведену на запам'ятовування траєкторії обходу перешкоди.
Перейти до виконання пункту 1.
Примітка. Горизонтальну межу поля потрібно тлумачити як перешкоду при русі полем. Якщо кілька перешкод дотикаються до горизонтальної межі, то вони разом з цією межею утворюють одну перешкоду з точки зору виконавця алгоритму.
Поради щодо програмного втілення:
напрямки руху зручно занумерувати цілими числами 0, 1, 2, 3 відповідно для напрямків →, ↑, ←, ↓;
мають бути глобальними усі змінні, значення яких буде використано і, можливо, змінено при наступному виклику таймера:
Завдання 2. З файлів r*.png:
вказівкою Терміналу з використанням MagicImage створити зациклену gif-анімацію зі зміною кадрів щосекунди.
Досягнути цього самого послідовним застосуванням консольних програм apngasm і аpng2gif.
Завдання 3. Створити програму мовою PHP, яка виведе вміст поточної теки. Порівняти з очікуваним.
Завдання 4. Програмно втілити складений алгоритм руху білого круга прямокутним полем темно зеленого кольору з оминанням перешкод (наприклад, відрізків прямих ліній) жовтого кольору.
Вважати, що існує шлях для квадрата з горизонтальними і вертикальними сторонами, описаного навколо круга. Останнє припущення дає можливість спростити код перевірки можливості руху у певному напрямку за рахунок збільшення кількості виконуваних дій.
Вказівки до виконання завдання на основі розглянутого раніше коду показу руху білого круга зліва направо поверх перешкод жовтого кольору:
Описати змінні і надати їм початкових значень. Виробити пропозиції у результаті конкурсу ідей і порівняти з очікуваним кодом, який потрібно вставити на початку коду PHP.
$igame = 0;// стан гри $idir = 0;// напрям руху $xb = 0;// найбільше досягнуте значення абсциси $jb = 0;// номер точки таєкторії з найбільшим // досягнутим значенням абсциси $jt = 0;// поточний номер точки траєкторії при поверненні // у точку "відриву" за найменшу кількість кроків $tr=array(); //траєкторія центрів круга $incjt = true;// зростання поточного номера точки таєкторії // при поверненні у "точку відриву від перешкоди" // за найменшу кількість кроків $can = array(true,true,true,true); // $can[$j] - чи можна рухатися у напрямку $j $r = 8; // радіус рухомого круга $s = 2; // крок переміщення круга по горизонталі чи вертикалі $w = 800; // розміри поля по горизонталі $h = 450; // розміри поля по вертикалі $x = $r; // поточна абсциса центра круга $y=$h/2; // поточна ордината центра круга $x0 = $x; // абсциса центра круга у попередній момент $y0 = $y; // ордината центра круга у попередній момент $n0 = 0; // номер кадру анімації // зображення поля з перешкодами жовтого кольору $field = ImageCreateFromPng("field.png"); // жовтий колір перешкод $yellow = imagecolorallocate($field,255,255,0);
Створити анімовані png після створення послідовності кадрів, що відображають рух білого круга темно-зеленим полем із перешкодами жовтого кольору.
Записати створений код PHP і анімовані png у вказану вчителем теку.
Повідомити вчителя про завершення роботи над проектом.
6. Підбиття підсумків уроку
Обговорення проблем виконання завдання. Виставлення оцінок.
7. Домашнє завдання
У разі потреби доробити завдання.
Для охочих: удосконалити програму — дозволити переміщення центра білого круга у точки з цілими координатами, віддаленими від початкового положення на відстань, що не перевищує s за умови, що при зміні однієї з координат кінцевого розташування на 1 можна отримати точку, віддалену від початкового розташування на відстань, що не перевищує s — див. малюнок, на якому:
При одночасному зростанні s і розмірів подання перешкод така дискретна модель (зі скінченою кількістю розташувань круга) є гарним наближенням неперервної моделі, у якій можливим є довільне розташування круга без перетину з перешкодами з довільним напрямком переміщення на певну відстань. Файл для опрацювання (із зображенням перешкод) може місти істотно більше пікселів, ніж його зображення на екрані монітора.
Іншим наближенням такої моделі є модель з довільним розташуванням круга без перетину з перешкодами, але векторами переміщення з такими координатами:
Якщо сумістити початки векторів, то їхні кінці будуть вершинами правильного 4n-кутника. Кратність 4 кількості вершин вибрано для того, щоб мати можливість рухатися по горозонталі праворуч і ліворуч та по вертикалі вгору й униз. У цьому випадку:
цілі координати відображення фігури будуть наближеннями дійсних значень;
для зменшення кількості виконуваних дій опрацювання пікселів (особливо для великих значень n):
доцільно здійснювати не для кожного напрямку окремо, а для усіх напрямків одночасно у кільці з радіусами обмежувальних кіл r, r + s;
при виявленні пікселя частини зображення перешкоди визначати аналітично найбільші і найменші кутові аргументи напрямків руху, для якого ця перешкода перешкоджає руху у відповідному напрямку;
дані про заборонені напрямки зберігати як список пар початків і кінців інтервалів значень номерів напрямків;
файл із зображеннями перешкод (для опрацювання пікселів) відображати на екрані монітора з істотним зменшенням (щодо розмірів у пікселях).
Для обох моделей алгоритм перевірки можливості руху у певному напрямку вимагає істотного доопрацювання з використанням рівняння прямої на площині.
Текст упорядкував Олександр Рудик.