VKACL — туториал и справочник
О проекте
VKACL — язык программирования, который Виктор Германович Кон (доктор физико-математических наук, Курчатовский институт) придумал в 1991 году, ещё работая на Фортране, и развивает до сих пор. Главной целью с самого начала была быстрая работа с графикой; вычисления, файлы, окна, PDF и всё остальное выросли вокруг неё. Долгое время язык назывался просто ACL, но это сокращение занято многим другим, и теперь автор называет его по имени сайта — vkacl. (Название «МЛЯП» — «мой личный язык программирования» — относится к сообществу во ВКонтакте, а не к языку.)
Это не учебный проект: на VKACL написана рабочая среда, которой автор пользуется каждый день, и восемь десятков готовых программ — для картинок, PDF, числовых массивов, графиков, сайтов, слайдов.
С чего начинать
Автор советует новичкам не начинать с программирования. Сначала скачать интерпретатор и пользоваться готовыми программами — многим этого достаточно. Если что-то в готовой программе не устраивает, её текст открыт, и её можно поправить. Так постепенно и приходит язык.
Поэтому у этой книги три входа:
| Если вы хотите… | Начните с |
|---|---|
| пользоваться готовыми программами | Начало работы и Готовые программы |
| писать свои программы | Что такое VKACL и дальше по туториалу |
| найти, как работает конкретная команда | Справочник команд |
Откуда взяты сведения
- описание языка на сайте автора: справочник, суперкоманды, готовые программы, примеры с разбором;
- сам интерпретатор —
aclp.jarиз дистрибутиваvkacl.zip(23.05.2026, интерпретатор от 05.09.2025). Там, где описание допускает два прочтения, поведение проверялось запуском настоящего интерпретатора.
Тексты автора здесь не переписаны дословно: всё изложено заново, по-другому устроено и местами дополнено тем, что выяснилось при проверке.
Что нужно знать сразу
| Ожидание | Реальность |
|---|---|
< и > — сравнения |
Это минимум и максимум, и они связывают сильнее + и * |
| Любой текст вне команд — комментарий | Только если в нём нет символа # |
| После команды можно сразу писать пояснение | После #c, #d, #v, #e сначала нужен ! — он закрывает их аргументы |
| Имя команды пишется целиком | Значимы первые 1–3 буквы: #pr, #pri, #print — одно и то же |
Где взять интерпретатор
Дистрибутив — на странице vkacl:
архив vkacl.zip и переносная Java 8 (JRE), которую не нужно устанавливать —
достаточно распаковать папку. Подробно — в главе Начало работы.
В этом проекте есть и собственная реализация ядра языка — она запускает примеры прямо на страницах книги (см. Песочница и Реализация на Rust). Графики, окон и готовых программ в ней нет: для настоящей работы нужен интерпретатор автора.
Правовая заметка
Язык VKACL, его интерпретатор, описания и готовые программы принадлежат Виктору Кону. Эта книга — независимое изложение, написанное заново.
Начало работы
Название VKACL составлено из первых букв слов Victor Kohn Advanced Command Language. Устроена система как Линукс: небольшое ядро — интерпретатор языка, написанный на Java, — и неограниченная периферия — программы на самом VKACL. Автор называет их а-программами.
Эта глава — о том, как поставить настоящий интерпретатор и запустить первую готовую программу. Писать код для этого не нужно.
Что скачать
Всё лежит на странице vkacl:
| Файл | Что это | Размер |
|---|---|---|
vkacl.zip |
интерпретатор и все готовые программы | около 10 МБ |
| переносная JRE 1.8.0_91 | Java для Windows, ссылка на странице | около 64 МБ |
vkacld.zip |
демонстрационные файлы (по желанию) | около 9 МБ |
Java нужна любая 64-битная, но удобнее всего переносная версия со страницы автора: её не нужно устанавливать.
Как поставить
- Распакуйте JRE так, чтобы получилась папка
C:\jre1.8.0_91. - Распакуйте
vkacl.zipв любое место — например,C:\vkacl. - Всё. Ничего не регистрируется в системе.
Папку с JRE и папку с программой можно целиком записать на флешку и запускать
на любом компьютере. Тогда в bat-файлах нужно поменять букву диска C: на
букву флешки.
В папке программы:
| Что | Зачем |
|---|---|
aclp.jar |
сам интерпретатор |
_runp.bat |
запуск в режиме проигрывателя — для готовых программ |
_rund.bat |
запуск в режиме среды разработки — для своих программ |
_runp.sh, _rund.sh |
то же для Линукса |
program.acl |
программа-меню, которую показывает проигрыватель |
pro/ |
основная рабочая папка; сюда программы кладут результаты |
proc/, s/ |
библиотеки и программы из хранилища |
help.txt |
справка, её показывает кнопка Help |
Если Java стоит в другом месте, поправьте первую строку bat-файла:
set path=C:/jre1.8.0_91/bin;%path%
java -jar aclp.jar 2
Число после aclp.jar выбирает режим: 2 — проигрыватель, 0 — среда
разработки.
Два режима
Проигрыватель (_runp.bat). Окна среды нет — сразу появляется меню из
кнопок:
| Кнопка | Что делает |
|---|---|
| Help | справка по работе с программой |
| File | выбрать и выполнить любой файл с кодом VKACL |
| Index | таблица номеров готовых программ — выбираете номер, программа запускается |
| Demo | демонстрация |
| SciPro | научные программы |
| Exit | выход |
Готовая программа сначала открывает в редакторе файл своих входных данных с примерами вариантов. Вы правите первые строки под свою задачу, сохраняете — и программа выполняется. Как именно заполнять входные данные каждой из восьмидесяти программ, описано в разделе Готовые программы.
Среда разработки (_rund.bat). Окно с меню и редактором: здесь пишут и
запускают свои программы. Проигрыватель из неё вызывается клавишами
Alt+B.
При запуске открывается чёрное окно
Это окно терминала Java, в которое она пишет свои сообщения. Закрывать его не нужно — но если программа зациклилась и не отвечает, закрытие этого окна надёжно её останавливает.
Что дальше
- Пользоваться готовыми программами — каталог и руководства.
- Писать свои — со следующей главы, Что такое VKACL. Примеры туториала можно запускать прямо на странице в песочнице или в среде разработки автора.
Готовые программы
Вместе с интерпретатором VKACL поставляется набор из восьмидесяти готовых программ, написанных автором языка Виктором Коном. У каждой есть номер, и каждая делает одну практическую работу: собирает PDF из картинок, рисует график по файлу чисел, делает сайт из текста, режет картинки, ищет слово в файлах и так далее.
Чтобы пользоваться ими, программировать не нужно. Программа открывает текстовый файл с примером входных данных — одной-двумя строками чисел и имён файлов. Вы исправляете пример под свою задачу, закрываете редактор — и программа выполняется.
Автор советует новичкам именно такой порядок: сначала скачать интерпретатор и поработать с готовыми программами, и только потом, когда станет понятно, что они умеют, заглядывать в их код и менять его. Этот раздел — для первого шага.
Описания составлены по сайту автора (aclp-info), по текстам внутри файлов входных данных и по самому коду программ из архива
vkacl.zipот 23.05.2026. Там, где источники расходятся, указано, как ведёт себя код.
Установка
Всё скачивается со страницы ACLnews.
| Что | Зачем | Обязательно? |
|---|---|---|
vkacl.zip (≈ 9,7 МБ, версия 23.05.2026) |
интерпретатор и все готовые программы | да |
| архив JRE 1.8.0_91 для Windows (≈ 64 МБ, ссылка на Яндекс-диск там же) | Java, без которой интерпретатор не работает | если Java не установлена |
vkacld.zip (≈ 9 МБ) |
файлы для примеров и для кнопки Demo | очень желательно |
vktot.zip |
словарь для проверки опечаток в большом редакторе (программа №25) | нет |
По шагам:
- Распакуйте
vkacl.zipв любое место, например вC:\vkacl. Установки нет — это и есть вся программа. - Распакуйте архив JRE в корень диска
C:, чтобы получилась папкаC:\jre1.8.0_91. Именно этот путь записан в bat-файлах. Если Java у вас уже установлена (любая 64-битная), этот шаг можно пропустить. - Из
vkacld.zipвозьмите две папки: папку0положите внутрь папкиpro(получитсяC:\vkacl\pro\0), папкуzip— в главную папку программы (получитсяC:\vkacl\zip). Почти все примеры входных данных ссылаются на файлы изpro/0/, поэтому без этого архива примеры не сработают. (Автор пишет, что можно просто положить сам архив в главную папку — кнопка Demo распакует его сама; надёжнее разложить папки вручную.)
Папку программы вместе с папкой JRE можно записать на флешку и запускать на чужом компьютере. Тогда в первой строке bat-файлов поменяйте букву диска:
set path=C:/jre1.8.0_91/bin;%path%
java -jar aclp.jar 2
Два режима запуска
| Файл | Режим | Для кого |
|---|---|---|
_runp.bat (Линукс: _runp.sh) |
проигрыватель — окна нет, сразу появляется меню из кнопок | для тех, кто пользуется готовыми программами |
_rund.bat (Линукс: _rund.sh) |
среда разработки — окно с меню и редактором кода | для тех, кто пишет свои программы |
Из среды разработки проигрыватель тоже вызывается — клавишами Alt+B.
При запуске через bat-файл открывается чёрное окно терминала: туда Java пишет свои сообщения. Не закрывайте его. Но если программа «зависла» и не реагирует, закрытие этого окна надёжно её останавливает.
Меню проигрывателя
| Кнопка | Что делает |
|---|---|
| Help | показывает справку help.txt |
| File | выбрать любой файл на компьютере и «исполнить» его по расширению: файл .acl выполняется как программа VKACL, картинки, сайты, музыка и видео открываются системой, .dat рисуется графиком, .mid проигрывается, остальное открывается в редакторе |
| Index | таблица из 99 номеров — главная кнопка для запуска готовых программ |
| Demo | та же таблица, но программы запускаются с демонстрационными данными |
| SciPro | научные программы автора; каждую нужно отдельно скачать со страницы Depository в папку s |
| Exit | выход |
Как запустить программу по номеру
- Запустите
_runp.bat. Появится меню. - Нажмите Index. Откроется таблица из 99 кнопок. Сейчас работают номера 1–79 и 99; на остальные программа ответит, что они ещё не готовы.
- Выберите номер. Откроется редактор с файлом входных данных этой программы. В верхних строках — готовые варианты входных данных, ниже — инструкция автора (она местами устарела; актуальное описание — на сайте и на страницах этого раздела).
- Исправьте нужную строку или допишите свою. Поставьте курсор в самое начало той строки, которую хотите выполнить.
- Нажмите Esc (или выйдите через меню редактора). Файл сохранится, и программа выполнится с данными из выбранной строки. Если передумали — закройте окно редактора крестиком: программа не запустится, изменения не сохранятся.
- Посмотрите результат. Программы пишут файлы в папки, указанные во входных данных, а многие ещё и показывают результат: картинку в окне, PDF или сайт — в программе, которая открывает такие файлы в системе.
- Ответьте на вопросы проигрывателя:
- Wait / Go — «файл готов». Wait — открыть его сейчас, Go — не открывать и идти дальше;
- Job is done! Continue? — Yes запускает ту же программу ещё раз (удобно подбирать параметры), No — выход из неё;
- Would you like to run other program? — Yes снова показывает таблицу номеров, No возвращает в главное меню.
Исправленные входные данные запоминаются: в следующий раз программа
откроет их в том же виде. Хранятся они в файле idc00.txt в главной папке —
строка с номером N относится к программе N.
Как записывать входные данные
У программ разные данные, но правила записи почти везде одинаковые.
Одна строка — один вариант. Строк с вариантами может быть сколько угодно; выполняется та, в начале которой стоит курсор. В самой первой строке курсор может стоять и во второй позиции — так он оказывается сразу после открытия файла. Если курсор стоит в другом месте, программа сообщит об ошибке и предложит исправить.
Поля разделяются пробелами. Внутри поля пробелов быть не должно. Там, где
нужен текст с пробелами (подпись над графиком, заголовок), пишут символ _
вместо пробела — программа сама превратит его в пробел.
Пути к файлам и папкам. Можно писать путь относительно главной папки
программы (pro/1/) или полный путь с буквой диска (C:/photo/, букву —
заглавной). Годятся оба разделителя, / и \. Надёжнее относительные пути:
в некоторых программах длина пути ограничена (около 40 символов), да и в
строке данных короткий путь удобнее. Пробелов в путях быть не должно.
Нужен ли разделитель в конце имени папки — зависит от программы, это указано
в таблицах.
Пробел в конце строки. После последнего поля должен стоять пробел.
Поскольку его не видно, автор в примерах часто пишет после пробела лишнюю
букву E: программа её не читает, но видно, что пробел есть.
Осторожно: там, где важно число полей, лишняя буква меняет смысл строки.
Не ставьте её в программах №2 (обычный режим), 6, 12, 17, 27, 46, 53, 56, 62,
75, 76, а также в многострочных данных №1, 8, 39, 66, где строка целиком —
это текст, имя файла или адрес. Подробности — в описании каждой программы.
Многострочные данные. Некоторые программы берут не строку под курсором, а первые строки файла: №1, 8, 10, 11, 12, 13, 14, 28, 39, 49, 50, 57, 66, 78. У них позиция курсора не важна, выполняется только верхний вариант. Запасные варианты держите ниже и при необходимости переносите наверх.
Числовые файлы .dat
Многие программы работают с матрицами чисел в двоичном виде. Такой файл —
это просто подряд записанные числа по 4 байта (формат float языка Java,
старшие байты впереди), без заголовка. Размер матрицы в файле не хранится:
его надо знать и указывать во входных данных. Проверка простая — размер файла
в байтах равен 4 × ширина × высота.
Матрица записывается по строкам. Для программ, которые рисуют карты, первая строка файла — нижняя строка картинки.
Перевести текстовую таблицу чисел в такой файл умеет программа №16, обратно — №43. Подробный пример — в разборе №21.
Папки и файлы
| Где | Что там |
|---|---|
| главная папка | aclp.jar (интерпретатор), bat-файлы, program.acl (меню проигрывателя), help.txt |
pro00.txt |
код всех программ, по одной на строку (строка N — программа N; символ ~ заменяет перевод строки) |
idc00.txt |
ваши входные данные — тоже по строке на программу |
idcd00.txt |
входные данные для кнопки Demo |
pri00.txt |
старая копия кода программ; меню проигрывателя её не использует |
runsys.bat |
вспомогательный файл, через который программы открывают готовые PDF и сайты; если что-то не открылось само, кликните его |
jsc1.txt, jsc2.txt |
команды операционной системы для программы №76 |
pro/ |
главная рабочая папка; сюда многие программы пишут результаты |
pro/0.par, pro/0.acl |
временные копии входных данных и кода запущенной программы |
pro/0/ |
файлы для примеров из vkacld.zip |
pro/1/, pro/2/ |
папки-черновики, которые используются в примерах |
pro/b/ |
служебные файлы: шаблоны сайтов, фоновые картинки, таблица Менделеева |
pro/pdf/ |
рабочая папка программы №61 |
pro/sites/ |
проекты сайтов программы №44 |
zip/ |
архив презентации для программы №27 |
s/ |
научные программы (кнопка SciPro) |
vkNP/ |
настройки большого редактора; в 17-й строке vkNP/par.txt надо указать путь к своему браузеру |
Внимание. Кнопка Demo перед некоторыми демонстрациями очищает папки
pro/1/иpro/2/, чтобы подготовить исходные файлы. Не храните там ничего ценного — для своих файлов заведите отдельные папки.
Если что-то пошло не так
- Программа ничего не сделала. Проверьте, что курсор стоит в начале нужной строки и что после последнего поля есть пробел.
- Сообщение об ошибке и выход из программы. Чаще всего это неверные входные данные: не тот размер матрицы, опечатка в имени файла, лишнее поле. Запустите проигрыватель заново и сверьтесь с описанием.
- PDF или сайт готов, но не открылся. Кликните
runsys.batв главной папке или найдите файл менеджером файлов. - Программа зависла. Закройте чёрное окно терминала.
Каталог
Программы сгруппированы по назначению. Номер — ссылка на подробное описание.
Картинки — pictures.md
| № | Название | Для чего |
|---|---|---|
| 06 | PICs on MAT | собрать одну картинку из таблицы одинаковых картинок |
| 07 | PICs to ICONs | уменьшенные копии (иконки) всех картинок папки |
| 08 | SLIDE MAKER | слайд или заставка из картинок и надписей (разбор) |
| 34 | INDEX | копии картинок папки с именами вида «шапка + номер» |
| 35 | PNG to JPG | перевести все PNG папки в JPG |
| 40 | PIC to FRAG | вырезать фрагмент картинки мышью или по числам |
| 45 | PICs to CUT2 | разрезать каждую картинку папки пополам |
| 47 | PIC to RSFrag | фрагмент картинки после поворота и масштабирования |
| 51 | SCR to PIC | снимки экрана по нажатию клавиши (например, с видео) |
| 54 | IMG VIEW | просмотр картинок, несколько штук на экране, увеличение |
| 58 | PIC MOD | яркость, контраст, гамма и другие операции над пикселями |
| 59 | PICs SUP | сложить несколько картинок с весами |
| 60 | PICs PRO | перемножить или поделить картинки |
| 68 | PNG to EPS | перевести все PNG папки в EPS |
| 73 | IMG MOD 2 | массово изменить высоту картинок или вписать их в рамку |
PDF — pdf.md
| № | Название | Для чего |
|---|---|---|
| 09 | PDF PRESENT | PDF-презентация из картинок папки |
| 10 | PDF to PART | новый PDF из выбранных страниц другого PDF |
| 11 | PDFs to PDF | объединить несколько PDF в один |
| 12 | PDF PAGEs | узнать размеры страниц PDF |
| 13 | PIC on PDF | положить картинки поверх страницы PDF |
| 14 | TXT on PDF | написать текст поверх страницы PDF |
| 39 | PDF to PRINT | лист A4 с картинками для печати |
| 61 | SWP4rus | PDF из TeX-файла редактора SWP с русским текстом |
Числовые массивы и матрицы — arrays.md
| № | Название | Для чего |
|---|---|---|
| 16 | TXT to DAT | текстовая таблица чисел → двоичный файл .dat |
| 17 | MAT to FRAG | вырезать прямоугольный фрагмент матрицы |
| 18 | MAT to Smooth | сгладить матрицу гауссианом (серия ширин) |
| 19 | MAT RESIZE | изменить размер матрицы интерполяцией |
| 32 | TIFF to TAGs | параметры TIFF-файла (размер, разрядность, сжатие) |
| 33 | TIFFs to DATs | матрицы из всех TIFF-файлов папки |
| 37 | ADGF | подобрать функцию Гаусса к кривой |
| 43 | DAT to TXT | двоичный файл .dat → текст |
| 46 | PIC to DAT | пиксели картинок → числовые матрицы |
| 48 | PIC to XYProf | средние профили картинки по X и по Y |
| 53 | MAT to LINE | значения матрицы вдоль отрезка |
| 55 | DAT MOD 2 | арифметика над всеми файлами папки |
| 65 | DAT MOD 1 | арифметика и преобразования одного массива |
| 71 | DAT to TIFF 1 | матрица → 16-битный TIFF |
| 77 | DAT MOD 1 | транспонирование, обрезка, сглаживание, отражение матрицы |
| 79 | MAT PROP | анализ 16-битных матриц детектора |
| 80 | — | вычислить функции по формулам «как в Excel» (в архиве 23.05.2026 ещё нет) |
Графики — graphs.md
| № | Название | Для чего |
|---|---|---|
| 03 | DAT to PNG 2 | картинки из матриц всех файлов папки |
| 20 | 1D PIC 1 | график одной или нескольких кривых |
| 21 | 2D MAP | карта матрицы в оттенках серого или в цвете (разбор) |
| 22 | 2D as SET 1D | квазитрёхмерный график — семейство сдвинутых кривых |
| 23 | 2D as AXON | аксонометрия поверхности z(x, y) |
| 24 | 2D as ANIM | анимация: сечения матрицы сменяют друг друга |
| 49 | EPS 1D | график кривых в EPS и PDF |
| 50 | EPS 2D | карта матрицы в EPS и PDF |
| 67 | 1D PIC 2 | графики для всех файлов папки |
| 70 | DAT to PNG 1 | картинка из фрагмента одной матрицы |
Тексты и файлы — text.md
| № | Название | Для чего |
|---|---|---|
| 02 | SYMBOL | сколько раз символ встречается в файле |
| 05 | FIND WORD | найти слово во всех файлах папки |
| 15 | CIPHER | редактор зашифрованных текстов |
| 25 | EDITOR | большой редактор текстов |
| 26 | LINE EDIT | править одну строку файла по номеру |
| 36 | COPY FILEs | склеить несколько файлов в один |
| 64 | TXT to FB2 | электронная книга FB2 из текста |
| 72 | DAT MOD 2 | замены текста во всех файлах папки, перекодировка, сортировка строк |
| 75 | Exe FILE | выбрать файл и открыть его по расширению |
Сайты — sites.md
| № | Название | Для чего |
|---|---|---|
| 01 | FOTO SITE | заготовка сайта фотографий с комментариями |
| 04 | SLIDE SHOW | сайт — слайд-шоу по картинкам папки |
| 38 | SIMP SITE | простой сайт из текстового файла |
| 44 | COMP SITE | сложный сайт по простой разметке |
| 52 | FOTO SHOW | сайт фото-шоу под музыку |
| 66 | WEB SITE | копия статьи из интернета: текст и картинки отдельно |
| 74 | CH LANG | сайт из текста с кнопкой перевода на другие языки |
Звук, анимация, игры — media.md
| № | Название | Для чего |
|---|---|---|
| 27 | LECTURE | показ презентации доклада или картинок папки |
| 41 | GAME PIC | игра-мозаика: собрать перемешанную картинку |
| 42 | GAME MOV | анимация движения упругих шаров |
| 63 | FM-PLAYER | проигрыватель mp3-файлов папки в браузере |
| 69 | vkSS | слайд-шоу под музыку с эффектными переходами |
| 99 | DEMO | рекламная анимация языка VKACL |
Автоматизация и система — system.md
| № | Название | Для чего |
|---|---|---|
| 28 | RUNNER | панель из 176 кнопок для часто нужных файлов |
| 29 | PLAYER | написать и сразу выполнить небольшую программу на VKACL |
| 56 | CHAIN 1 | выполнить несколько программ подряд |
| 57 | CHAIN 2 | цепочка программ, данные прямо в протоколе |
| 76 | SYSTEM | выполнить команды операционной системы по номерам |
| 78 | CHAIN 3 | цепочка программ для каждого файла папки |
Разное — other.md
| № | Название | Для чего |
|---|---|---|
| 30 | UNICODES | посмотреть, какие символы есть в шрифте |
| 31 | PTOE | таблица Менделеева — справочник и записная книжка |
| 62 | CALCUL | калькулятор выражений на 8 переменных (разбор) |
Подробные разборы
Три программы разобраны по шагам, от пустой папки до готового результата:
- №08 SLIDE MAKER — слайд из картинки и надписей;
- №62 CALCUL — калькулятор;
- №21 2D MAP — карта матрицы чисел, заодно и перевод текстовой таблицы в двоичный файл программой №16.
Где ещё почитать
- Описания готовых программ на сайте автора — первоисточник; автор обновляет его чаще, чем тексты внутри программ.
- Страница загрузки и новостей.
- Как писать свои программы — с главы Начало работы.
Картинки
Программы этой группы собирают, режут, пересчитывают и переименовывают
файлы картинок (JPG, PNG, иногда GIF). Общие правила записи входных данных —
в разделе Как записывать входные данные; примеры
используют файлы из архива vkacld.zip (папка pro/0/).
| № | Название | Для чего |
|---|---|---|
| 06 | PICs on MAT | одна картинка из таблицы картинок |
| 07 | PICs to ICONs | уменьшенные копии всех картинок папки |
| 08 | SLIDE MAKER | слайд из картинок и надписей |
| 34 | INDEX | копии картинок с номерами в именах |
| 35 | PNG to JPG | все PNG папки → JPG |
| 40 | PIC to FRAG | вырезать фрагмент |
| 45 | PICs to CUT2 | разрезать картинки пополам |
| 47 | PIC to RSFrag | фрагмент после поворота и масштаба |
| 51 | SCR to PIC | снимки экрана по клавише |
| 54 | IMG VIEW | просмотр картинок |
| 58 | PIC MOD | яркость, контраст, гамма |
| 59 | PICs SUP | сумма картинок с весами |
| 60 | PICs PRO | произведение или частное картинок |
| 68 | PNG to EPS | все PNG папки → EPS |
| 73 | IMG MOD 2 | массово поменять высоту или вписать в рамку |
№06. PICs on MAT — картинка из таблицы картинок
Что делает. Раскладывает несколько картинок одинакового размера таблицей (столько-то в строке, столько-то строк) с промежутками заданного цвета и сохраняет результат как одну картинку. Удобно для отчётов и каталогов. Готовая картинка сразу показывается в левом верхнем углу экрана; закрыть её — кликом по картинке или крестиком.
Что нужно заранее. Все картинки лежат в одной папке, имеют формат PNG или JPG и один и тот же размер (размер берётся по первой).
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | папка с картинками, с разделителем / в конце |
pro/0/ |
| 2 … k+1 | имена k картинок без расширения, в порядке заполнения таблицы; одно имя можно повторять | jad jad jad jad |
| k+2 | имя нового файла без расширения | all |
| k+3 | сколько картинок в строке таблицы | 2 |
| k+4 | сколько строк | 2 |
| k+5 | промежуток между картинками по горизонтали, px | 3 |
| k+6 | промежуток по вертикали, px | 3 |
| k+7 | номер цвета промежутков, от 1 до 256 | 250 |
Результат. Файл <папка>/<имя>.jpg или .png — того же типа, что
исходные картинки. Размер: ширина = столбцы × ширина картинки + промежутки.
Пример. Четыре копии портрета jad.jpg (220×250) таблицей 2×2:
pro/0/ jad jad jad jad all 2 2 3 3 250
Получится pro/0/all.jpg размером 443×503.
Тонкости.
- Картинок должно быть ровно «столбцы × строки». Если их больше или меньше, программа ничего не создаст и ничего не скажет.
- Расширение программа ищет сама: сначала
.png, потом.jpg. Если файла нет, появится сообщение с его именем. - Картинки раскладываются по строкам слева направо, начиная с верхней.
- Не ставьте в конце лишнюю букву
E: программа считает поля, и последние пять обязаны быть числами. - Цвета с номерами 244–256 заданы заранее, прочие по умолчанию чёрные. Нужный цвет проще всего подобрать пробой. Смешивать PNG и JPG в одной таблице не стоит.
№07. PICs to ICONs — уменьшенные копии картинок
Что делает. Для каждой картинки исходной папки делает копию заданной ширины (высота — пропорционально) и кладёт её в другую папку под тем же именем. Обычно так делают иконки для каталогов и сайтов.
Что нужно заранее. В исходной папке — только картинки JPG или PNG (размеры могут быть разными). Папка для копий должна существовать.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | исходная папка, с разделителем в конце | pro/1/ |
| 2 | папка для копий, с разделителем в конце | pro/2/ |
| 3 | ширина копий, px | 200 |
Результат. В папке копий — файлы с теми же именами, но всегда в формате
JPG (m91.png → m91.jpg). В конце программа сообщает, куда записаны копии.
Пример. Скопируйте m91.jpg … m95.jpg из pro/0/ в pro/1/, затем:
pro/1/ pro/2/ 200
Тонкости.
- Программа считает картинкой каждый файл исходной папки, поэтому посторонний файл приведёт к ошибке.
- Папки должны быть разными: иначе JPG-оригиналы будут перезаписаны копиями.
- Если папка пуста, программа попросит поменять её.
№08. SLIDE MAKER — слайд из картинок и надписей
Пошаговый разбор с примером — на странице Разбор: №08 SLIDE MAKER.
Что делает. Собирает картинку заданного размера — слайд презентации, объявление, заставку для видео — методом «вырезать и наклеить»: на основу кладёт картинки (со сдвигом, поворотом, наклоном и масштабом), а поверх пишет строки текста любым шрифтом, установленным на компьютере.
Что нужно заранее. Все используемые картинки лежат в папке pro/1/.
Туда же программа запишет результат.
Входные данные — несколько первых строк файла:
| Строка | Что писать | Пример |
|---|---|---|
| 1 | W H N1 N2, |, имя результата |
512 512 1 3|slide |
| 2 … N1+1 | X Y A Sx Sy Mx My, |, файл картинки |
256 256 0 0 0 9 9|000000.png |
| ещё N2 строк | X Y M K S R G B, |шрифт|текст |
256 100 5 1 30 0 255 0 |Arial|Привет |
Смысл чисел:
| Параметр | Значение |
|---|---|
| W, H | размер основы в пикселях |
| N1, N2 | сколько будет картинок и сколько надписей (столько строк и должно идти следом) |
| имя результата | без расширения; получатся файлы .png и .jpg |
| файл картинки | имя файла в папке pro/1/ с расширением |
| X, Y | для картинки — положение её центра, для надписи — точка привязки; отсчёт в пикселях от левого верхнего угла основы, Y растёт вниз |
| A | угол поворота картинки в градусах |
| Sx, Sy | сдвиговая (скашивающая) деформация; 0 0 — без неё |
| Mx, My | масштаб по осям; 1 1 — исходный размер |
| M | способ привязки надписи к точке X, Y (от 1 до 9, см. ниже) |
| K | начертание: 0 обычное, 1 жирное, 2 курсив, 3 жирный курсив |
| S | размер шрифта, px |
| R, G, B | цвет текста, каждая составляющая от 0 до 255 |
Привязка M: по горизонтали 1, 4, 7 — левым краем, 2, 5, 8 — серединой,
3, 6, 9 — правым краем; по вертикали 1–3 — низом, 4–6 — серединой высоты,
7–9 — верхом. Самая удобная — 5: текст центрируется в точке.
Результат. Два файла: pro/1/<имя>.png и pro/1/<имя>.jpg. Слайд
показывается на экране, затем программа спрашивает, не поменять ли параметры.
Yes снова открывает входные данные — можно подправить и посмотреть ещё
раз.
Пример (автора). Для него скопируйте 000000.png из pro/0/ в pro/1/.
512 512 1 3|slide
256 256 0 0 0 9 9|000000.png
256 100 5 1 30 0 255 0 |Arial|на полотно любого размера
256 200 5 1 30 255 0 0 |Arial|можно ставить картинки
256 300 5 1 30 255 255 255 |Arial|и тексты любых фасонов
Чёрная картинка 256×192, увеличенная в 9 раз, закрывает всю основу 512×512, а поверх идут три строки: зелёная, красная и белая.
Тонкости.
- Выполняется только верхний вариант. Запасные храните ниже и переносите наверх, когда понадобятся.
- После вертикальной черты до конца строки идёт имя файла или текст —
не ставьте в конце лишнюю букву
E, она станет частью имени или надписи. - Если картинки нет в
pro/1/, программа сообщит об этом и поставит вместо неё маленький светлый квадратpro/0/emsp.png. - Имя шрифта пишется как есть, пробелы в нём допустимы (
Arial narrow). Какие шрифты есть и какие символы в них — покажет программа №30. Надписи могут быть русскими. - Если N1 = 0, картинок нет — это не ошибка; основа остаётся одноцветной. Нужный фон проще всего получить первой картинкой-подложкой, как в примере.
№34. INDEX — копии картинок с номерами
Что делает. Копирует все файлы .jpg и .png из одной папки в другую,
давая им новые имена: «шапка» + трёхзначный номер + прежнее расширение
(abc001.jpg, abc002.png, …). Номера идут подряд в порядке файлов в
каталоге. Исходные файлы остаются на месте.
Что нужно заранее. Обе папки существуют.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | исходная папка | pro/0/ |
| 2 | папка для копий | pro/2/ |
| 3 | шапка — любые символы без пробелов, хотя бы один | abc |
Результат. В папке копий: abc001.jpg, abc002.jpg, …
Пример.
pro/0/ pro/2/ abc E
Тонкости.
- Учитываются только расширения
jpgиpng, написанные строчными буквами;.JPGи.jpegпропускаются. - Разделители
\программа сама превращает в/. - Если какой-то папки нет, программа сообщит, какой именно.
№35. PNG to JPG — перевод PNG в JPG
Что делает. Переводит все файлы .png исходной папки в формат JPG и
записывает их в другую папку с тем же именем. Остальные файлы не трогает.
Что нужно заранее. Обе папки существуют.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | исходная папка | pro/0/ |
| 2 | папка для JPG | pro/2/ |
Результат. pro/2/<имя>.jpg для каждого <имя>.png.
Пример.
pro/0/ pro/2/ E
Тонкости. Расширение png должно быть написано строчными буквами. Если
папка пуста, программа так и скажет.
№40. PIC to FRAG — вырезать фрагмент картинки
Что делает. Вырезает прямоугольный фрагмент из картинки JPG или PNG и сохраняет его в новый файл. Два режима: с одной картинкой (фрагмент можно выделить мышью) и пакетный — одинаковый фрагмент из серии пронумерованных файлов.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | рабочая папка, с разделителем в конце | pro/0/ |
| 2 | исходная картинка | m91.jpg |
| 3 | файл фрагмента; расширение .jpg или .png задаёт формат |
frag.jpg |
| 4, 5 | X, Y — левый нижний угол фрагмента, px | 0 0 |
| 6, 7 | W, H — ширина и высота фрагмента, px | 500 500 |
| 8 | N: 1 — одна картинка; больше 1 — пакетный режим на N файлов |
1 |
Режим N = 1. Картинка показывается на экране (слишком большая — уменьшенной), подсказка — в строке над панелью задач. Дальше одно из двух:
- нажать левую кнопку мыши в левом нижнем углу будущего фрагмента и, не отпуская, довести до правого верхнего — программа рисует рамку;
- нажать C и ввести четыре числа X Y W H (окно уже заполнено числами из входных данных) — так фрагмент получается точно нужного размера.
Фрагмент показывается и сразу записывается в файл.
Режим N > 1. Имена обеих картинок должны кончаться трёхзначным номером
перед точкой, а перед номером — хотя бы одна буква: vk001.jpg, f001.jpg.
Программа молча вырезает фрагмент X Y W H из первого файла, увеличивает номера
в обоих именах на 1 и повторяет, всего N раз.
Результат. <папка>/<файл фрагмента> (в пакетном режиме — серия файлов).
Пример.
pro/0/ m91.jpg frag.jpg 0 0 500 500 1
Тонкости.
- Числа, введённые после C, программа не запоминает — если они удачные, перепишите их во входные данные.
- В пакетном режиме давайте фрагментам другую букву, чем исходникам, иначе исходные файлы будут перезаписаны.
- Если расширение файла фрагмента не
jpgи неpng, фрагмент не сохранится.
№45. PICs to CUT2 — разрезать картинки пополам
Что делает. Каждую картинку исходной папки разрезает по вертикали на две половинки, как развороты книги на две страницы. Нужно для слайд-шоу в виде книги, но годится и для других целей.
Что нужно заранее. В исходной папке — только картинки JPG, PNG или GIF. Папка для результатов существует (может быть не пустой).
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | исходная папка, с разделителем в конце | pro/1/ |
| 2 | папка для половинок, с разделителем в конце | pro/2/ |
Результат. Для m91.jpg — файлы pro/2/m91-1.jpg и pro/2/m91-2.jpg,
всегда в формате JPG.
Пример.
pro/1/ pro/2/
Тонкости. По коду программы -1 — правая половина, -2 — левая;
проверьте на своей картинке, прежде чем готовить книгу.
№47. PIC to RSFrag — фрагмент после поворота и масштаба
Что делает. Поворачивает картинку на заданный угол, умножает её размеры на коэффициент и вырезает из середины прямоугольник заданного размера.
Что нужно заранее. Рабочая папка находится внутри папки программы (пока это обязательно).
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | рабочая папка | pro/0 |
| 2 | исходная картинка | jad.jpg |
| 3 | новая картинка; расширение .jpg или .png задаёт формат |
frag.jpg |
| 4, 5 | ширина и высота новой картинки, px | 100 100 |
| 6 | угол поворота, градусы | 90 |
| 7 | коэффициент масштабирования | 1.3 |
Результат. <папка>/<новая картинка>; она же показывается на экране.
Пример.
pro/0 jad.jpg frag.jpg 100 100 90 1.3
Тонкости.
- Центр вырезаемого прямоугольника совпадает с центром повёрнутой картинки. Если прямоугольник больше картинки, края заполняются цветом фона.
- Направление поворота проверьте на пробе: в программах №47 и №08 знак угла трактуется по-разному.
№51. SCR to PIC — снимки экрана по клавише
Что делает. Сохраняет снимки всего экрана в JPG по нажатию клавиши — не показывая себя и не мешая видео или видеоконференции, с которых снимают кадры. О том, что программа работает, говорит только маленький красный прямоугольник в правом верхнем углу экрана.
Входные данные — одна строка, лучше первая:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | папка для снимков, короткий путь (не длиннее 30 символов) | pro/2/ |
| 2 | номер, с которого продолжать нумерацию | 0 |
Как работать.
- Запустите программу, затем откройте видео. Окно видео не должно закрывать красный прямоугольник.
- Кликните по красному прямоугольнику — программа получит фокус.
- Enter — снимок; прямоугольник на миг мигнёт.
- Если переключались на другие окна, перед следующим снимком снова кликните по прямоугольнику.
- Пробел — выход.
Результат. Файлы <папка>/vk001.jpg, vk002.jpg, … Номер увеличивается
перед каждым снимком. При выходе программа сама записывает в первую строку
входных данных папку и последний номер — следующий сеанс продолжит нумерацию,
не затирая старые снимки.
Пример.
pro/2/ 0
Тонкости. Работает в режиме проигрывателя. Папку лучше брать внутри папки программы — путь короче; не пишите в имя папки пробелы и длинные русские фразы.
№54. IMG VIEW — просмотр картинок
Что делает. Показывает картинки PNG, JPG и GIF, в том числе несколько сразу, и позволяет увеличивать и уменьшать их.
Входные данные. Нет. Поставьте курсор в начало текста и нажмите Esc.
Как работать. Откроется окно выбора файла (начиная с папки программы). Один клик по файлу показывает эскиз, кнопка Select или двойной клик — картинку в натуральную величину (большая — с полосами прокрутки). Дальше:
| Действие | Что происходит |
|---|---|
| клик по картинке | картинка закрывается, снова окно выбора |
| → | картинка остаётся, можно выбрать ещё одну — так на экране собирается несколько картинок; двигать их за рамку окна |
| ↑ / ↓ | таблица из 99 чисел: картинка увеличится / уменьшится на выбранное число процентов (50 — в полтора раза) |
| Cancel в окне выбора | конец работы |
Тонкости. В режиме проигрывателя оставленные на экране картинки исчезают после выхода из программы.
№58. PIC MOD — яркость, контраст, гамма
Что делает. Пересчитывает цвета всех пикселей картинки по одной из восьми формул: делает светлее или темнее, контрастнее или мягче. Размер не меняется.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | рабочая папка (разделитель в конце можно не ставить) | pro/0 |
| 2 | исходная картинка JPG, PNG или GIF, с расширением | s9.jpg |
| 3 | имя новой картинки без расширения | s9n |
| 4 | номер операции, 1–8 | 1 |
| 5, 6 | параметры p1 и p2 (если операции нужен один, второй всё равно пишется) | 50 0 |
Операции (x — значение цвета от 0 до 255):
| № | Что делает |
|---|---|
| 1 | прибавляет p1 ко всем цветам |
| 2 | умножает все цвета на p1/1000 |
| 3 | растягивает диапазон: p1 → 0, p2 → 255 |
| 4 | сжимает диапазон: 0 → p1, 255 → p2 |
| 5 | умножает контраст на p1/1000, среднее сохраняется |
| 6 | гамма: 255·(x/255)^(p1/1000) |
| 7 | логарифмическая кривая с параметрами p1, p2 (формула — на сайте автора) |
| 8 | S-образная кривая 255/(1+exp((a2−x)/a1)), где a1=(p2−p1)/2, a2=(p2+p1)/2 |
Результат. <папка>/<новое имя>.jpg, всегда JPG; показывается на экране.
Пример. Сделать картинку светлее на 50 единиц:
pro/0 s9.jpg s9n 1 50 0
Тонкости. Если нет папки или файла, программа скажет об этом по-русски. Эффект операций проще всего понять пробой.
№59. PICs SUP — сумма картинок с весами
Что делает. Складывает несколько картинок, каждую со своим весом (веса могут быть отрицательными — это вычитание), и нормирует результат в диапазон 0–255. Полезно, например, для суммирования серии снимков одного объекта.
Входные данные — одна строка из пяти полей:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | рабочая папка | pro/0 |
| 2 | список картинок через запятую, с расширениями | m91.jpg,m92.jpg |
| 3 | имя результата без расширения; первая буква c — цветной, b — чёрно-белый |
cnew |
| 4 | веса через запятую (важны только отношения) | 50,50 |
| 5 | нормировка: 1 — отрицательное обнуляется, максимум → 255; 2 — весь диапазон от минимума до максимума → 0–255 |
2 |
Результат. <папка>/<имя>.jpg размером с первую картинку.
Пример.
pro/0 m91.jpg,m92.jpg cnew 50,50 2
Тонкости.
- Если имя результата начинается не с
cи не сb, программа откажется работать. - Разумно складывать картинки одинаковой ширины. Картинка поменьше «размазывается» по большой; в таком случае сначала вырежьте из большой фрагмент нужного размера (№40).
№60. PICs PRO — произведение или частное картинок
Что делает. Перемножает картинки (например, чтобы вырезать область по маске) или делит одну на другую; результат линейно приводится к диапазону 0–255.
Входные данные — одна строка из четырёх полей:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | рабочая папка | pro/0 |
| 2 | список картинок через запятую, с расширениями | m91.jpg,m92.jpg |
| 3 | имя результата без расширения; первая буква c — цветной, b — чёрно-белый |
cnew |
| 4 | 1 — умножение, 2 — деление |
1 |
Результат. <папка>/<имя>.jpg размером с первую картинку.
Пример.
pro/0 m91.jpg,m92.jpg cnew 1
Тонкости. При делении используются только две первые картинки; нули делителя заменяются единицами. Про размеры — то же, что у №59.
№68. PNG to EPS — перевод PNG в EPS
Что делает. Переводит все PNG-файлы папки в формат EPS — для вставки в статьи и в рисунки на PostScript.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | вариант: 1 — готовый к просмотру EPS; 2 — только код картинки для вставки в другой EPS |
1 |
| 2 | папка с PNG, с разделителем в конце | pro/1/ |
| 3 | папка для результатов (должна существовать), с разделителем в конце | pro/2/ |
Результат. pro/2/<имя>.eps (вариант 1) или pro/2/<имя>EPS.txt
(вариант 2) для каждого файла.
Пример.
1 pro/1/ pro/2/
Тонкости. В исходной папке не должно быть ничего, кроме PNG. Символ _
в путях к папкам программа заменяет на пробел, поэтому папки с _ в имени
не подойдут.
№73. IMG MOD 2 — высота и рамка для всех картинок папки
Что делает. Меняет сами файлы всех картинок папки. Вариант 1 — задаёт всем одну высоту, сохраняя пропорции. Вариант 2 — помещает каждую картинку в центр пустого кадра заданного размера (удобно после варианта 1, чтобы все кадры стали одинаковыми).
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | вариант, 1 или 2 |
2 |
| 2 | папка, с разделителем в конце | pro/1/ |
| 3 | h — новая высота (в варианте 2 не используется, но пишется) | 720 |
| 4, 5 | W, H — размер кадра (только для варианта 2) | 1280 720 |
Результат. Вариант 1: файлы перезаписываются (JPG остаётся JPG, PNG —
PNG). Вариант 2: результат пишется в JPG с тем же именем (для PNG рядом
появляется .jpg).
Пример.
1 pro/1/ 720 E
2 pro/1/ 720 1280 720 E
Тонкости.
- Преобразование необратимо — сначала сделайте копию папки.
- Обрабатываются все файлы папки без разбора, посторонних быть не должно.
- В варианте 2 картинка не масштабируется: если она больше кадра, края обрежутся.
Программы этой группы собирают PDF из картинок, склеивают и перекраивают готовые PDF, кладут поверх страницы картинки и надписи. Размеры в PDF задаются в пунктах (pt): лист A4 — это 596 × 843 pt (у автора встречается и 596 × 842).
Общие правила записи входных данных — в разделе Как записывать входные данные. Программы №10–14 и 39 читают несколько первых строк файла и выполняют только верхний вариант.
| № | Название | Для чего |
|---|---|---|
| 09 | PDF PRESENT | PDF-презентация из картинок папки |
| 10 | PDF to PART | новый PDF из выбранных страниц |
| 11 | PDFs to PDF | объединить несколько PDF |
| 12 | PDF PAGEs | размеры страниц PDF |
| 13 | PIC on PDF | картинки поверх страницы PDF |
| 14 | TXT on PDF | текст поверх страницы PDF |
| 39 | PDF to PRINT | лист с картинками для печати |
| 61 | SWP4rus | PDF из TeX-файла редактора SWP |
Запускайте эти программы через
_runp.bat. Если источник — повреждённый или вообще не PDF, Java не сможет его прочитать, выведет ошибку в чёрное окно терминала и остановит интерпретатор. Проверить это из программы на VKACL нельзя, поэтому перед работой просто откройте исходный PDF обычной программой просмотра.Готовый PDF программы пытаются открыть сами (кнопка Wait). Если он не открылся — найдите файл в папке или кликните
runsys.bat.
№09. PDF PRESENT — PDF-презентация из картинок
Что делает. Собирает PDF-файл, в котором каждая страница — одна картинка из папки. Так готовят файл доклада из слайдов-картинок. Есть режим для постерных докладов: слайды поворачиваются на 90° и вписываются в лист A4, чтобы их можно было распечатать и приколоть на стенд.
Что нужно заранее. В папке — только картинки JPG или PNG. Порядок страниц — алфавитный порядок имён файлов.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | папка с картинками, с разделителем в конце | pro/1/ |
| 2 | имя PDF без расширения | present |
| 3 | режим: 0 — как есть, 1 — поворот на 90° и лист A4 |
0 |
Результат. Файл pro/<имя>.pdf — всегда в папке pro.
Пример. Скопируйте m91.jpg … m95.jpg из pro/0/ в pro/1/, затем:
pro/1/ present 0 E
Получится пятистраничный pro/present.pdf. Не удаляйте его — он понадобится
как источник в примерах программ №10–12.
Тонкости. В режиме 0 размер страницы берётся по первой картинке, и все
картинки ставятся в натуральную величину. Поэтому слайды должны быть одного
размера.
№10. PDF to PART — новый PDF из выбранных страниц
Что делает. Берёт из готового PDF нужные страницы и собирает из них новый файл. Каждую страницу можно сдвинуть, растянуть и повернуть. Можно ставить по две страницы источника на одну страницу результата.
Входные данные — первые строки файла:
| Строка | Что писать | Пример |
|---|---|---|
| 1 | W H N, затем путь к новому PDF и путь к PDF-источнику, оба без расширения |
640 480 2 pro/1/new pro/present |
| 2 … |N|+1 | по строке на страницу: n X Y Sx Sy A |
1 0 0 0.5 0.5 0 |
Смысл чисел:
| Параметр | Значение |
|---|---|
| W, H | размер страницы нового файла, pt |
| N | сколько страниц взять. N > 0 — по одной странице источника на страницу; N < 0 — по две (их нужно уменьшить и развести сдвигом, чтобы не перекрывались) |
| n | номер страницы источника |
| X, Y | сдвиг страницы источника на новой странице, pt |
| Sx, Sy | масштаб по осям; 1 1 — без изменений |
| A | угол поворота, градусы |
Результат. Файл по первому пути (pro/1/new.pdf).
Пример (источник — pro/present.pdf из примера №9):
640 480 2 pro/1/new pro/present E
1 0 0 0.5 0.5 0 E
2 0 0 0.5 0.5 0 E
Тонкости.
- Программа читает ровно |N| строк после первой; ниже можно хранить другие варианты и заметки.
- Номер несуществующей страницы просто пропускается, ошибки не будет. Сколько страниц в источнике, узнайте любой программой просмотра PDF.
- Пути — без пробелов.
№11. PDFs to PDF — объединение нескольких PDF
Что делает. Склеивает несколько PDF в один. Страницы можно сдвинуть, растянуть и повернуть. Удобно, например, чтобы собрать одностраничные PDF с картинками в один многостраничный.
Входные данные — первые строки файла:
| Строка | Что писать | Пример |
|---|---|---|
| 1 | W H N, затем путь к новому PDF без расширения |
640 480 2 pro/1/new2 |
| 2 … |N|+1 | по строке на файл: X Y Sx Sy A, затем путь к PDF без расширения |
0 0 1 1 0 pro/1/new |
W, H — размер страницы результата в pt; N — сколько файлов объединить (N < 0 — по две старые страницы на новую); X, Y, Sx, Sy, A — как у №10.
Результат. pro/1/new2.pdf.
Пример — дважды вставить файл из примера №10:
640 480 2 pro/1/new2 E
0 0 1 1 0 pro/1/new E
0 0 1 1 0 pro/1/new E
Тонкости.
- Каждый файл вставляется целиком, со всеми своими страницами.
- Если какого-то файла нет, программа сообщит об этом, и результат не будет записан.
- Лучше объединять файлы с одинаковым размером страниц; если размеры разные, подберите сдвиг и масштаб пробой.
№12. PDF PAGEs — размеры страниц
Что делает. Показывает размеры всех страниц выбранного PDF. Нужно, чтобы правильно задать сдвиги и масштабы в программах №10, 11, 13 и 14.
Входные данные — первая строка файла:
| Строка | Что писать | Пример |
|---|---|---|
| 1 | папка, с которой начать выбор файла | pro/ |
Как работать. Откроется окно выбора файла, показывающее только PDF. Выберите файл.
Результат. Файл pro/page-sizes.txt: по строке на страницу — номер,
ширина и высота в pt. Он сразу открывается в редакторе. Папку выбранного
файла программа записывает в первую строку входных данных — в следующий раз
выбор начнётся с неё.
Пример.
pro/
Тонкости. Используется только первая строка; лишних символов после пути не ставьте.
№13. PIC on PDF — картинки поверх страницы PDF
Что делает. Делает новый одностраничный PDF: копию первой страницы старого PDF, поверх которой положены картинки — в любом месте, с масштабом и поворотом. Удобно, чтобы добавить в документ подпись, печать или пометку.
Входные данные — первые строки файла:
| Строка | Что писать | Пример |
|---|---|---|
| 1 | N, путь к старому PDF, путь к новому PDF (оба без расширения) |
1 pro/0/QR-vgkohn pro/1/1 |
| 2 … N+1 | по строке на картинку: X Y P S A, затем путь к картинке с расширением |
0 0 0 220 0 pro/0/jad.jpg |
| Параметр | Значение |
|---|---|
| X, Y | левый нижний угол картинки, pt |
| P | всегда 0 (не используется) |
| S | ширина картинки на странице, pt; высота — пропорционально |
| A | угол поворота, градусы |
Результат. pro/1/1.pdf.
Пример.
1 pro/0/QR-vgkohn pro/1/1 E
0 0 0 220 0 pro/0/jad.jpg
Тонкости.
- Каждая строка должна кончаться пробелом.
- Следующая картинка закрывает предыдущие — это можно использовать.
- Форматы картинок: jpg, gif, png, bmp, tif, wmf, eps (автор проверял jpg и png).
- Автор заметил, что на PDF, сделанный из картинки, новые картинки не ложатся. Обходной путь: превратить PDF в картинку онлайн-сервисом, наложить картинки программой №08 и снова собрать PDF программой №09.
№14. TXT on PDF — текст поверх страницы PDF
Что делает. Как №13, но вместо картинок кладёт на страницу строки текста встроенными шрифтами PDF.
Входные данные — первые строки файла:
| Строка | Что писать | Пример |
|---|---|---|
| 1 | N, путь к старому PDF, путь к новому PDF (оба без расширения) |
1 pro/0/QR-vgkohn pro/1/1 |
| 2 … N+1 | по строке на надпись: S X Y A F P R G B, затем сам текст и пробел |
16 60 160 0 10 0 0 0 0 Privet_Mir_! |
| Параметр | Значение |
|---|---|
| S | размер шрифта, pt |
| X, Y | точка привязки текста, pt |
| A | угол поворота, градусы |
| F | номер шрифта, см. ниже |
| P | привязка к точке: 0 — левым краем, 1 — серединой, 2 — правым краем |
| R, G, B | цвет, каждая составляющая от 0 до 255 (0 0 0 — чёрный) |
Шрифты: 1 Courier, 2 Courier-Bold, 3 Courier-Oblique, 4 Courier-BoldOblique, 5 Helvetica, 6 Helvetica-Bold, 7 Helvetica-Oblique, 8 Helvetica-BoldOblique, 9 Times, 10 Times-Bold, 11 Times-Italic, 12 Times-BoldItalic, 13 Times-Roman, 14 Symbol, 15 ZapfDingbats.
Результат. pro/1/1.pdf.
Пример.
1 pro/0/QR-vgkohn pro/1/1 E
16 60 160 0 10 0 0 0 0 Privet_Mir_! E
Тонкости.
- Внутри текста пробелов быть не должно — пишите
_, программа заменит его на пробел. После текста обязателен пробел. - Русские буквы встроенные шрифты PDF не поддерживают — только латиница.
- В текст можно вставлять текстовые коды VKACL: например,
\u32 32 32*3;даёт пять пробелов (числа — номера символов Юникода).
№39. PDF to PRINT — лист с картинками для печати
Что делает. Делает одностраничный PDF, на который можно положить сколько угодно картинок. Главное применение — разложить картинки на лист A4 и напечатать.
Входные данные — первые строки файла. Все пути считаются от папки
pro:
| Строка | Что писать | Пример |
|---|---|---|
| 1 | W H N, затем | и имя PDF без расширения |
596 842 2|pri |
| 2 … N+1 | по строке на картинку: M X Y P S A, затем | и файл картинки с расширением |
11 100 150 0 220 0|0/jad.jpg |
| Параметр | Значение |
|---|---|
| M | двузначное число KL. K: 1 — по координатам (рекомендуется), 0 — «потоком» друг за другом. L: 0 — масштаб в процентах, 1 — ширина в pt, 2 — высота в pt |
| X, Y | при K = 1 — левый нижний угол картинки, pt; при K = 0 — отступ после предыдущего объекта |
| P | при K = 0 — положение в строке: 0 слева, 1 по центру, 2 справа |
| S | масштаб: проценты, ширина или высота — в зависимости от L |
| A | угол поворота, градусы |
Результат. pro/pri.pdf.
Пример — два портрета шириной 220 pt на листе A4:
596 842 2|pri
11 100 150 0 220 0|0/jad.jpg
11 150 500 0 220 0|0/jad.jpg
Тонкости.
- После имени файла в строке ничего быть не должно — никакой буквы
E. - Следующая картинка закрывает предыдущие; картинки «по координатам» лучше ставить после «потоковых». Режим «потоком» автор советует не использовать или проверять пробой.
- При L = 0 и масштабе 100 % один пиксель картинки равен 1 pt.
№61. SWP4rus — PDF из TeX-файла редактора SWP
Что делает. Помогает сделать PDF из TeX-файла, записанного редактором Scientific WorkPlace 4 и новее, если в нём есть русский текст. SWP кодирует русские буквы так, что ни сам SWP, ни MiKTeX не могут сделать PDF. Программа перекодирует их в windows-1251 и готовит запуск MiKTeX.
Что нужно заранее.
- Установленный MiKTeX, настроенный на русский язык.
- В первой строке файла
pro/pdf/swp4rus.dat— путь к папкеbinMiKTeX на вашем компьютере, с разделителем в конце (сейчас там путь автора). Программа проверяет, что в этой папке естьpdflatex.exe. - TeX-файл с нужными пакетами для русского языка. Проще всего начинать с
шаблонов
pro/pdf/sample1.tex…sample4.tex; для пробы —sample4.tex.
Входные данные. Нет. Поставьте курсор в начало первой строки и нажмите Esc.
Как работать.
- В окне выбора (оно открывается в
pro/pdf/) выберите TeX-файл. - Программа создаст
pro/pdf/runsys.batи попросит запустить его. Сначала кликните этот файл в менеджере файлов, дождитесь конца его работы и только потом нажмите OK. - PDF появится рядом с TeX-файлом, с тем же именем.
Тонкости. Только Windows. Файл runsys.bat создаёт сама программа — его
не правят; править нужно swp4rus.dat, один раз. Подробности у автора:
latex-info.
Числовые массивы и матрицы
Эти программы работают с массивами чисел: переводят их из текста в двоичный
вид и обратно, вырезают, сглаживают, интерполируют, вычисляют. Большинство
работает с файлами .dat — числами по 4 байта без заголовка (подробнее — в
разделе Числовые файлы .dat). Размеры матрицы в таком файле не
хранятся, поэтому их всегда указывают во входных данных.
Нарисовать массив помогут программы группы Графики.
| № | Название | Для чего |
|---|---|---|
| 16 | TXT to DAT | текст → .dat |
| 17 | MAT to FRAG | вырезать фрагмент матрицы |
| 18 | MAT to Smooth | сглаживание гауссианом |
| 19 | MAT RESIZE | новый размер интерполяцией |
| 32 | TIFF to TAGs | параметры TIFF-файла |
| 33 | TIFFs to DATs | матрицы из TIFF-файлов папки |
| 37 | ADGF | подгонка функцией Гаусса |
| 43 | DAT to TXT | .dat → текст |
| 46 | PIC to DAT | пиксели картинок → числа |
| 48 | PIC to XYProf | профили картинки по X и Y |
| 53 | MAT to LINE | значения вдоль отрезка |
| 55 | DAT MOD 2 | операции над всеми файлами папки |
| 65 | DAT MOD 1 | операции над одним массивом |
| 71 | DAT to TIFF 1 | матрица → 16-битный TIFF |
| 77 | DAT MOD 1 | транспонирование, обрезка, сглаживание, отражение |
| 79 | MAT PROP | анализ 16-битных матриц детектора |
| 80 | — | функции по формулам «как в Excel» |
№16. TXT to DAT — текстовая таблица в двоичный файл
Пошаговый пример — в разборе №21.
Что делает. Читает матрицу (или вектор) чисел из текстового файла и
записывает те же числа в двоичный файл .dat, с которым работают другие
программы.
Что нужно заранее. Текстовый файл с расширением .txt. В режиме матрицы
каждая строка матрицы записана на отдельной строке файла.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | сколько чисел в строке матрицы (для вектора — сколько всего чисел) | 441 |
| 2 | сколько строк в матрице; 1 — особый случай «вектор» |
1 |
| 3 | сколько строк в начале файла пропустить (например, текстовый заголовок) | 0 |
| 4 | путь к файлу без .txt |
pro/0/matrix |
Результат. Файл с тем же именем и расширением .dat в той же папке.
Пример. Файл pro/0/matrix.txt — 21 строка по 21 числу. Его можно
прочитать как вектор из 441 числа или как матрицу 21×21 — результат одинаков:
441 1 0 pro/0/matrix E
21 21 0 pro/0/matrix E
Тонкости.
- В режиме «вектор» (второе число
1) разбиение по строкам не важно: читается столько чисел, сколько указано первым. В режиме матрицы строка матрицы номер i берётся со строки файла номер i (после пропущенных). - Программа заменяет символы табуляции на пробелы прямо в исходном
.txt-файле. - Путь не должен содержать пробелов.
№17. MAT to FRAG — фрагмент матрицы
Что делает. Вырезает из матрицы прямоугольный фрагмент и записывает его в новый файл — как вырезают кусок картинки. Есть и обратный режим: вставить фрагмент из второго файла на место в первом.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1, 2 | ширина и высота исходной матрицы | 400 100 |
| 3, 4 | сдвиг начала фрагмента по горизонтали и вертикали | 0 0 |
| 5, 6 | ширина и высота фрагмента | 100 50 |
| 7 | исходный файл с расширением | pro/0/m001.dat |
| 8 | файл фрагмента с расширением | pro/1/m001f.dat |
Результат. Второй файл — ширина × высота фрагмента чисел.
Пример.
400 100 0 0 100 50 pro/0/m001.dat pro/1/m001f.dat
Тонкости.
- Никаких лишних символов в конце строки. Если после двух путей стоит ещё
хоть одно поле (например, привычная буква
E), включается обратный режим: программа читает фрагмент из второго файла и вписывает его в первый, перезаписывая исходный файл. Второй файл при этом должен существовать и быть меньше первого. - Фрагмент должен целиком помещаться в матрицу.
№18. MAT to Smooth — сглаживание гауссианом
Что делает. Сглаживает матрицу (свёртка с функцией Гаусса) сразу для серии ширин гауссиана и записывает все результаты в один файл. Умеет и обратную операцию — развёртку.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1, 2 | nx, ny — ширина и высота матрицы (ny может быть 1) | 64 1 |
| 3 | ep: 0 — свёртка, больше 0 — развёртка |
0 |
| 4 | mo: 1 — вдоль первого индекса, 2 — вдоль второго, 3 — по обоим (матрица квадратная) |
1 |
| 5 | d — шаг сетки | 1 |
| 6 | dr — начальная полная ширина гауссиана на полувысоте | 5 |
| 7 | dd — шаг изменения ширины | 5 |
| 8 | nd — сколько ширин перебрать | 3 |
| 9 | исходный файл | pro/0/in999.dat |
| 10 | файл результата | pro/1/in999.dat |
Результат. Файл из nd матриц подряд (nx × ny × nd чисел), по одной на каждую ширину dr, dr+dd, dr+2·dd, …
Пример.
64 1 0 1 1 5 5 3 pro/0/in999.dat pro/1/in999.dat E
Тонкости.
- Размер вдоль сглаживаемого индекса должен быть степенью двойки (256, 512, 1024, …): при mo = 1 — nx, при mo = 2 — ny, при mo = 3 — оба. Если это не так, сначала интерполируйте матрицу программой №19.
- d, dr и dd задаются в одних единицах.
№19. MAT RESIZE — новый размер матрицы
Что делает. Пересчитывает матрицу на другое число точек линейной интерполяцией. Область значений аргументов при этом сохраняется.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1, 2 | ширина и высота исходной матрицы | 400 100 |
| 3, 4 | ширина и высота результата | 512 512 |
| 5 | исходный файл | pro/0/m001.dat |
| 6 | файл результата | pro/1/m001n.dat |
Результат. Файл с матрицей нового размера.
Пример.
400 100 512 512 pro/0/m001.dat pro/1/m001n.dat E
№32. TIFF to TAGs — параметры TIFF-файла
Что делает. Читает служебные записи (теги) TIFF-файла и показывает главное: ширину и высоту картинки, число бит на пиксель, сжатие, порядок байтов, где лежат данные. Нужна, чтобы убедиться, что файл — 16-битная чёрно-белая картинка (значения 0–65535), пригодная для научных данных.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | папка, с которой начать выбор файла | pro/0 |
Как работать. В окне выбора укажите TIFF-файл.
Результат. Файл tif-inf.txt в папке TIFF-файла; он сразу открывается в
редакторе.
Пример (в pro/0/ есть s001.tif):
pro/0 E
Тонкости. Если выбранный файл — не TIFF, программа сообщит об этом и
прервёт работу проигрывателя (в её коде на этот случай стоит команда
#stop); просто запустите _runp.bat снова.
№33. TIFFs to DATs — матрицы из TIFF-файлов
Что делает. Просматривает все файлы папки, находит среди них подходящие
TIFF (8 или 16 бит на пиксель) и записывает их пиксели как числа в файлы
.dat в другую папку.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | папка с TIFF-файлами | pro/0/ |
| 2 | папка для .dat |
pro/2/ |
| 3 | 1 — сообщать о каждом неподошедшем файле, 0 — молча пропускать |
1 |
Результат. pro/2/<имя>.dat для каждого подходящего <имя>.tif.
Пример.
pro/0/ pro/2/ 1 E
Тонкости. Расширение исходных файлов — .tif из трёх букв: программа
отрезает три последних символа имени и дописывает dat. Разделители \
превращаются в / автоматически.
№37. ADGF — подгонка функцией Гаусса
Что делает. Ищет функцию Гаусса, которая лучше всего описывает кривую из файла: подбирает положение центра и ширину, минимизируя сумму квадратов отклонений. Поиск идёт с графическим сопровождением, в конце рисуется график кривой и найденного гауссиана.
Что нужно заранее. Кривая — двоичный файл .dat из N чисел, записанных с
постоянным шагом d = X/N. Координата точки j (от 0 до N−1) —
x(j) = d·(j + (1−N)/2), то есть кривая центрирована на нуле.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | Nm — сколько раз вычислять гауссиан при поиске | 200 |
| 2 | N — число точек кривой | 301 |
| 3 | X — длина области аргумента | 0.12 |
| 4 | x — начальное положение центра | 0.002 |
| 5 | w — начальная ширина на полувысоте | 0.032 |
| 6 | dx — шаг поиска по центру | 0.0002 |
| 7 | dw — шаг поиска по ширине | 0.0002 |
| 8 | m: 1 — записывать протокол поиска |
1 |
| 9 | файл с кривой | pro/0/ep01.dat |
Результат. В папке pro: график adgf.png (над ним — найденные x, w и
высота M) и, если m = 1, файл adgf.txt со строкой «x w M сумма квадратов»
на каждое вычисление.
Пример.
200 301 0.12 0.002 0.032 0.0002 0.0002 1 pro/0/ep01.dat
№43. DAT to TXT — двоичный файл в текст
Что делает. Переписывает числа из .dat в текстовый файл — для программ,
которые понимают только текст.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | файл .dat без расширения |
pro/0/in999 |
| 2 | новый файл без расширения (будет .txt) |
pro/1/in999 |
| 3 | n — сколько чисел в строке | 1 |
| 4 | M — формат: 1 — с плавающей точкой, 2 — целые |
1 |
| 5 | N: при M = 1 — ширина числа (10 → 3 знака после точки, 11 → 4 и т. д.); при M = 2 — множитель | 11 |
| 6 | C: при M = 2 — вычитаемая константа (при M = 1 не важна) | 0 |
Результат. pro/1/in999.txt.
Пример.
pro/0/in999 pro/1/in999 1 1 11 0
Тонкости. При M = 2 каждое число умножается на N, из него вычитается C, и результат пишется целым числом шириной 5 позиций — значит, не больше четырёх цифр. Вычитание убирает неизменный «фон», умножение делает числа целыми; подходящие N и C подберите по графику исходных данных.
№46. PIC to DAT — пиксели картинок в числа
Что делает. Для каждой картинки папки (JPG, PNG, GIF) записывает значения
её пикселей как вещественные числа в файл .dat — для дальнейшей
математической обработки.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | папка с картинками, с разделителем в конце | pro/1/ |
| 2 | папка для .dat, с разделителем в конце |
pro/2/ |
| 3–5 | необязательно: веса R G B для перевода в оттенки серого | 1 1 1 |
Результат. pro/2/<имя>.dat для каждой картинки. Без весов каждый
пиксель даёт три числа (красный, зелёный, синий) — всего 3·W·H чисел.
С весами — одно число g = (R·r + G·g + B·b)/255 на пиксель, файл втрое меньше.
Пример.
pro/1/ pro/2/
Тонкости.
- Не ставьте в конце букву
E: третье поле программа считает началом весов R G B. - Ширина картинки в файл не записывается — запомните её сами. Проверка по размеру файла: 12·W·H байт в цветном режиме, 4·W·H — в сером.
- В исходной папке — только картинки.
№48. PIC to XYProf — профили картинки
Что делает. Складывает цвета каждого пикселя картинки (JPG или PNG), усредняет полученную матрицу по столбцам и по строкам и получает две кривые — профиль по X и профиль по Y. Записывает их и рисует графики.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | путь к картинке с расширением | pro/0/m91.jpg |
| 2, 3 | начало и конец оси X на графике | 0 1 |
| 4, 5 | начало и конец оси Y на графике | 0 1 |
Результат. Рядом с картинкой: m91X.dat и m91Y.dat — столбцы чисел,
m91X.png и m91Y.png — графики.
Пример.
pro/0/m91.jpg 0 1 0 1
Тонкости. Несмотря на расширение, файлы X.dat и Y.dat —
текстовые (число в строке), а не двоичные.
№53. MAT to LINE — значения вдоль отрезка
Что делает. Берёт из матрицы значения вдоль прямого отрезка между двумя точками (с интерполяцией), записывает их и рисует график.
Входные данные — одна строка, ровно девять полей:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | файл матрицы без .dat |
pro/0/m001 |
| 2 | файл результата без расширения | pro/1/new |
| 3, 4 | nx, ny — размеры матрицы | 400 100 |
| 5, 6 | x1, y1 — начало отрезка | 0 0 |
| 7, 8 | x2, y2 — конец отрезка | 399 99 |
| 9 | n — сколько точек взять на отрезке | 100 |
Координаты — номера точек, считая с нуля: x от 0 до nx−1, y от 0 до ny−1. Они могут быть дробными.
Результат. pro/1/new.dat (n чисел) и график pro/1/new.png: кривая
нормирована на интервал 0–1, над графиком — координаты концов, минимум и
максимум.
Пример.
pro/0/m001 pro/1/new 400 100 0 0 399 99 100
Тонкости. Полей должно быть ровно девять. Лишняя буква E в конце
вызовет сообщение Input data are incomplete!.
№55. DAT MOD 2 — операции над всеми файлами папки
Что делает. Выполняет одну математическую операцию над каждым числовым файлом папки.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | номер операции, 1–10 | 3 |
| 2 | параметр C | 100 |
| 3 | папка с исходными файлами, с разделителем в конце | pro/1/ |
| 4 | вторая папка (нужна операциям 1 и 2, но пишется всегда), с разделителем в конце | pro/2/ |
| № | Операция (a — массив из первой папки, b — из второй) |
|---|---|
| 1 | a / b; значения b меньше C заменяются на C (C > 0) |
| 2 | a · b |
| 3 | a + C |
| 4 | a · C |
| 5 | a + линейная функция от C в начале до −C в конце (поправка фона) |
| 6 | exp(C·a) |
| 7 | ln(a); значения меньше C заменяются на C |
| 8 | sin(C·a) |
| 9 | cos(C·a) |
| 10 | a в степени C |
Результат. Файлы 0001.dat, 0002.dat, … — в первой папке.
Пример.
3 100 pro/1/ pro/2/
Тонкости.
- Обрабатываются все файлы первой папки. Результаты ложатся туда же, поэтому при повторном запуске программа обработает и их — уберите их заранее.
- Для операций 1 и 2 во второй папке должно быть столько же файлов того же размера, либо ровно один файл — тогда он используется для всех.
№65. DAT MOD 1 — операции над одним массивом
Что делает. Выполняет операцию над массивом из файла или вычисляет его характеристики.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | номер операции, 1–14 | 3 |
| 2 | параметр C | 100 |
| 3 | исходный файл | pro/0/in999.dat |
| 4 | второй файл (нужен операциям 1 и 2; иначе пишется любой путь) | pro/1/in999.dat |
| 5 | файл результата | pro/1/in998.dat |
Операции 1–10 — те же, что у №55. Дополнительно:
| № | Операция |
|---|---|
| 11 | для каждой строки матрицы (длина строки nx — степень двойки) — свёртка с гауссианом ширины w и ширина самого высокого пика; результат — кривая длиной ny. C = nx·1000 + w, например 1024020 (w в шагах сетки) |
| 12 | транспонирование матрицы; C = nx |
| 13 | среднее по строкам (результат — вектор); C = nx |
| 14 | среднее по столбцам; C = nx |
Результат. Третий файл.
Пример.
3 100 pro/0/in999.dat pro/1/in999.dat pro/1/in998.dat E
Тонкости. Для операций 1 и 2 массивы должны быть одного размера. Матрица в файле хранится по строкам: сначала первая строка, потом вторая.
№71. DAT to TIFF 1 — матрица в 16-битный TIFF
Что делает. Записывает матрицу из .dat в TIFF-файл: 16 бит на пиксель,
без сжатия.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1, 2 | ширина и высота матрицы | 100 165 |
| 3 | порядок байтов: 0 — Юникс, 1 — Windows (автор советует 1) |
1 |
| 4 | путь к .dat от папки pro, без расширения |
0/001 |
Результат. TIFF с тем же именем: pro/0/001.tif.
Пример. Буква E в конце не читается — она только показывает, что после
последнего поля есть пробел:
100 165 1 0/001 E
Тонкости.
- Путь отсчитывается от
pro; папку выше можно указать через../, но выходить за пределы папки программы нельзя. - Значения должны помещаться в диапазон целых 0–65535.
- В текущем коде третье число не используется: файл всегда пишется с порядком байтов Intel (Windows).
№77. DAT MOD 1 — преобразования матрицы в файле
Что делает. Пять операций над одним файлом: транспонирование, ограничение значений, удаление выбросов и сглаживание шума, отражение, график минимумов и максимумов строк.
Входные данные — одна строка; первые четыре поля общие:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | номер операции, 1–5 | 1 |
| 2 | папка с разделителем в конце — или *, если пути файлов пишутся полностью от главной папки |
pro/0/ |
| 3 | исходный файл | m001.dat |
| 4 | файл результата | m001t.dat |
| 5 … | числа операции, см. ниже | 400 100 |
| № | Числа | Что делает |
|---|---|---|
| 1 | W H | транспонирует матрицу W×H (строки становятся столбцами) |
| 2 | Mi Ma | всё, что меньше Mi, делает равным Mi; больше Ma — равным Ma |
| 3 | W H N S | заменяет точки, отличающиеся от соседей больше чем на S, средним по N соседям (N нечётное, не меньше 3); при S ≤ 0 сглаживает все точки |
| 4 | ±W ±H | отражает матрицу; знак минус перед размером указывает, какой индекс переворачивать (один или оба) |
| 5 | W H | рисует график минимума и максимума каждой строки; результат — картинка, её имя пишется без расширения |
Результат. Файл результата в той же папке (для операции 5 — .png).
Пример — транспонировать матрицу 400×100 из демонстрационных файлов:
1 pro/0/ m001.dat m001t.dat 400 100 E
Тонкости. Программа проверяет, что размер файла соответствует W×H, и при несоответствии сообщает об ошибке. В операции 5 длиной строки можно считать сумму нескольких строк: вместо 2304×1500 указать 11520×300.
№79. MAT PROP — анализ 16-битных матриц
Что делает. Специальная программа для квадратных матриц из целых чисел 0–65535 — таких, какие записывают 16-битные TIFF-файлы координатных детекторов синхротронного излучения (матрицы получают программой №33). Три операции; номер операции — первое число строки.
Операция 1 — сводка по серии файлов. Поля: 1, рабочая папка (от
главной папки), имя отчёта без расширения, общее начало имён файлов, число
файлов nA (1–10), число максимумов nB, размер матрицы nC. Файлы должны
называться «начало + цифра 0…9» с расширением .dat.
В отчёт .txt по строке на файл: минимум, максимум, среднее и координаты nB
наибольших значений (координаты считаются сверху вниз).
Операция 2 — увеличенный фрагмент. Поля: 2, папка, начало имени,
номер файла nA (0–9), размер матрицы nB, размер фрагмента nC, координаты x
и y центра фрагмента. Рисует логарифм фрагмента в оттенках серого с
обращённым контрастом (максимум — чёрный) и записывает картинку в файл.
Операция 3 — деление двух матриц и сглаживание. Поля: 3, папка, первый
файл, второй файл, имя результата (все без .dat), размер матрицы nB и
управляющее число Q. Цифры Q считаются справа налево: p1 — делить заново
(1) или взять готовое частное (0); p2 — рисовать картинки исходных файлов;
p3 — палитра 0–3; p4 и p5 — размер окна сглаживания N = p4 + 10·p5 (нечётный);
p6 — 1 убирает оси; p7 — вариант палитры 3; p8 — 1 рисует логарифм.
Результаты: <имя>a.dat / <имя>a.png (частное) и <имя>b.dat /
<имя>b.png (сглаженное частное).
Пример (автора; папки task/… есть только на его компьютере):
1 task/o46/5/d info d 1 10 2304 E
2 task/o46/7/o4g1nc d 4 2304 100 366 738 E
3 task/o46/4/d 56 bg19 56b19 2304 0009311 E
Тонкости. Демонстрационных данных у программы нет. Матрицы рисуются перевёрнутыми по вертикали, чтобы выглядеть так же, как в других программах просмотра TIFF.
№80. Векторные вычисления «как в Excel»
В архиве
vkacl.zipот 23.05.2026 этой программы ещё нет: строка 80 файлаpro00.txtпуста, и меню Index номер 80 не принимает. Описание ниже составлено по сайту автора.
Что делает. Вычисляет несколько функций по формулам на сетке значений аргумента (или по столбцам аргументов из файла), записывает таблицу результатов и рисует график.
Вариант 1 — аргумент на равномерной сетке. Строка начинается с 0:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | 0 |
0 |
| 2 | nf — двузначное число: единицы — сколько функций (до 9), десятки — 0 нормировать графики, 1 не нормировать |
2 |
| 3, 4 | A1, A2 — начальное и конечное значения аргумента A | 0 9 |
| 5 | nA — число значений аргумента | 10 |
| 6 | имя результата без расширения | pro/test |
| 7 … | формулы функций от A, по одной на поле | A A*A |
Результат: pro/test.png (график; над ним — минимум и максимум первых трёх
функций) и pro/test.txt (столбцы чисел).
Вариант 2 — аргументы из файла. Строка начинается с числа аргументов na
(1–4): na nf nA файл_аргументов файл_результата f1 f2 …. Файл аргументов
(.txt, без расширения во входных данных) содержит na столбцов по nA строк;
аргументы называются A, B, C, D. Результат — только функции в
<файл_результата>.txt и график .png.
Пример (с сайта автора):
0 2 0 9 10 pro/test A A*A E
Тонкости. Формулы пишутся без пробелов, по правилам выражений VKACL (см. Выражения и функции).
Графики
Программы этой группы рисуют числовые данные: кривые, карты матриц,
квазитрёхмерные и аксонометрические графики, анимацию сечений. Данные берутся
из текстовых файлов или из двоичных .dat (см.
Числовые файлы .dat); картинки сохраняются в PNG, а №49 и 50 —
в EPS и PDF.
Общие правила записи входных данных — в разделе
Как записывать входные данные. Подписи над графиками
пишутся без пробелов: вместо пробела ставьте _.
| № | Название | Для чего |
|---|---|---|
| 03 | DAT to PNG 2 | картинки из матриц всех файлов папки |
| 20 | 1D PIC 1 | график кривых |
| 21 | 2D MAP | карта матрицы |
| 22 | 2D as SET 1D | семейство сдвинутых кривых |
| 23 | 2D as AXON | аксонометрия поверхности |
| 24 | 2D as ANIM | анимация сечений |
| 49 | EPS 1D | кривые в EPS/PDF |
| 50 | EPS 2D | карта в EPS/PDF |
| 67 | 1D PIC 2 | графики для всех файлов папки |
| 70 | DAT to PNG 1 | картинка из фрагмента матрицы |
Текстовые файлы с числами. Программы №20, 21 и 22 перед чтением заменяют в копии файла табуляции на пробелы, а запятые — на точки. Значит, десятичная запятая допустима, но разделять числа запятыми нельзя — только пробелами, табуляциями или переводами строк.
№03. DAT to PNG 2 — картинки из матриц всех файлов папки
Что делает. Для каждого числового файла папки рисует картинку прямоугольного фрагмента матрицы (или всей матрицы) — без осей и подписей — и записывает её в PNG. Удобно для серий однотипных файлов.
Что нужно заранее. В исходной папке — только двоичные файлы .dat
одинакового размера. Папка для картинок существует.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | папка с матрицами | pro/1/ |
| 2 | папка для картинок | pro/2/ |
| 3, 4 | ширина и высота матрицы | 640 169 |
| 5, 6 | сдвиг начала фрагмента по горизонтали и по вертикали (от левого нижнего угла) | 0 0 |
| 7, 8 | ширина и высота фрагмента | 640 169 |
| 9 | отражение: 0 — нет, 1 — по высоте, 2 — по ширине, 3 — по обеим осям |
0 |
| 10 | палитра: 0 — оттенки серого, 1–4 — цветные (лучшие — 3 и 4) |
0 |
Результат. pro/2/<имя>.png для каждого <имя>.dat. Сама программа
картинки не показывает — в конце она сообщает папку, а смотреть их удобно
программой №54.
Пример. Скопируйте m003.dat из pro/0/ в pro/1/, затем:
pro/1/ pro/2/ 640 169 0 0 640 169 0 0 E
Тонкости. Имена файлов упорядочиваются по алфавиту; у картинки то же имя,
что у файла, с расширением .png. Для одного файла удобнее программа
№70.
№20. 1D PIC 1 — график кривых
Что делает. Рисует в рамке с осями график одной или нескольких функций из файла. Большинство оформления задано заранее, во входных данных — только главное.
Входные данные — одна строка: девять чисел, подпись, файл.
| Поле | Что писать | Пример |
|---|---|---|
| 1 | nf — число функций | 1 |
| 2 | np — число точек каждой функции | 77 |
| 3 | nb — номер первой точки, которая попадёт на график | 1 |
| 4 | ng — сколько точек рисовать | 77 |
| 5, 6 | x1, x2 — аргумент в первой и последней точке файла | 0 76 |
| 7 | s — масштаб графика (1 — обычный); отрицательный — не показывать, только записать файл |
1 |
| 8 | t — формат файла, см. ниже | 3 |
| 9 | ni — сколько строк (t = 1, 2) или чисел (t = 3) пропустить в начале | 0 |
| 10 | подпись над графиком, _ вместо пробелов |
рис._1 |
| 11 | файл с данными | pro/0/in999.dat |
Форматы: t = 1 — текст столбцами, первый столбец — аргумент, остальные —
функции; t = 2 — текст столбцами, только функции; t = 3 — двоичный
.dat, сначала все точки первой функции, потом второй и так далее.
Результат. PNG с тем же именем рядом с файлом данных:
pro/0/in999.png. График показывается на экране (если s > 0).
Пример.
1 77 1 77 0 76 1 3 0 рис._1 pro/0/in999.dat E
Тонкости. Отрицательный масштаб удобен в цепочках программ (№57), когда окна с графиками не нужны. Для серии файлов с одинаковой структурой есть №67.
№21. 2D MAP — карта матрицы
Подробный разбор с примером — Разбор: №21 2D MAP.
Что делает. Рисует матрицу как карту: каждая точка — прямоугольник, окрашенный по значению (оттенки серого или цвет). Оси размечаются по заданным пределам аргументов, сбоку — шкала цветов, над картой — подпись, минимум и максимум.
Входные данные — одна строка: nx ny x1 x2 y1 y2 p1 p2 tf sf td Подпись Файл.
| Поле | Что писать | Пример |
|---|---|---|
| 1, 2 | nx, ny — число точек по горизонтали и вертикали | 21 21 |
| 3, 4 | x1, x2 — пределы горизонтальной оси | -5 5 |
| 5, 6 | y1, y2 — пределы вертикальной оси | -4 4 |
| 7, 8 | p1, p2 — ширина и высота прямоугольника точки, px (1–9) | 9 9 |
| 9 | tf — вид графика (1–6) | 2 |
| 10 | sf — множитель размера (1 — обычный) |
1 |
| 11 | td — формат данных и режимы (до трёх цифр) | 1 |
| 12 | подпись, _ вместо пробелов; если не нужна — один _ |
Матрица_чисел |
| 13 | файл с матрицей | pro/0/matrix.txt |
tf: 1 — полный график, серый; 2 и 3 — полный, цветной (две разные
палитры); 4, 5, 6 — то же, но только сама картинка без осей и шкалы
(размер ровно nx·p1 × ny·p2).
td: последняя цифра — формат (1 — текст, 2 — двоичный .dat); вторая с
конца, если 1, — не показывать график на экране; третья с конца, если 1, —
обратить палитру (максимум и минимум меняются местами). Например, 1, 11,
111, 2, 12.
Результат. PNG рядом с файлом данных: pro/0/matrix.png.
Пример.
21 21 -5 5 -4 4 9 9 2 1 1 Матрица_чисел pro/0/matrix.txt
Тонкости. Числа идут так: сначала нижняя строка карты слева направо, потом строка над ней и так далее. В текстовом файле разбиение по строкам не важно.
№22. 2D as SET 1D — семейство сдвинутых кривых
Что делает. Рисует функцию двух переменных как серию кривых-сечений, сдвинутых друг относительно друга, с удалением невидимых линий — получается квазитрёхмерный график без искажений в сечениях.
Входные данные — одна строка: двенадцать чисел и файл.
| Поле | Что писать | Пример |
|---|---|---|
| 1, 2 | nx — точек в каждой кривой, ny — число кривых | 141 41 |
| 3, 4 | x1, x2 — пределы аргумента по горизонтали | -1 1 |
| 5, 6 | y1, y2 — значения параметра для первой и последней кривой (подписываются на наклонной оси) | 1 100 |
| 7 | sa — сдвиг левой вертикальной оси, px (к стандартным 90) | 1 |
| 8 | sc — горизонтальный сдвиг кривых: 0 — на один шаг сетки, 1 — на два и т. д. |
1 |
| 9 | sv — вертикальный сдвиг кривых в единицах 0,001 от максимума функции | 15 |
| 10 | dt — формат: 1 — текст, 2 — двоичный .dat |
2 |
| 11 | st — размер чисел на осях, px | 20 |
| 12 | wa — добавка к ширине рисунка, px (к стандартным 900) | 20 |
| 13 | файл с данными | pro/0/fxy2.dat |
Данные идут подряд: все nx значений первой кривой, потом второй и так далее.
Результат. Два графика рядом с файлом: fxy2a.png и fxy2b.png.
Пример.
141 41 -1 1 1 100 1 1 15 2 20 20 pro/0/fxy2.dat
Тонкости. Лучше всего выходит, когда кривых хотя бы вдвое меньше, чем точек в каждой (ny < nx/2): иначе график сильно вытягивается вправо. Это поправляют параметрами sa и wa.
№23. 2D as AXON — аксонометрия поверхности
Что делает. Рисует поверхность z(x, y), заданную матрицей, в аксонометрической проекции — с осями, подписями и сечениями.
Входные данные — одна строка: двадцать чисел, подпись, файл.
| Поле | Параметр | Что значит | Пример |
|---|---|---|---|
| 1, 2 | nx, ny | число точек матрицы по x и y | 400 100 |
| 3, 4 | x1, x2 | пределы аргумента x | -6 6 |
| 5, 6 | y1, y2 | пределы аргумента y | 197 256 |
| 7, 8 | z1, z2 | пределы оси z | 0 55.6 |
| 9 | sm | четыре цифры: первая 1 — показать график на экране, остальные три — масштаб в процентах |
1100 |
| 10 | sa | две цифры: первая — сечения (1 XZ, 2 YZ, 3 оба), вторая — вертикальные оси (0 обе, 1 правая, 2 левая) |
30 |
| 11–13 | vx, vy, vz | направление на точку зрения (важны отношения) | 12 18 10 |
| 14 | dv | удалённость точки зрения (автор: десятичный логарифм расстояния) | 200 |
| 15, 16 | sx, sy | множители осей x и y относительно оси z | 5. 1 |
| 17, 18 | tx, ty | положение подписи, px | 9 9 |
| 19, 20 | kx, ky | число точек на графике; если не равны nx, ny, матрица интерполируется | 100 100 |
| 21 | подпись | _ вместо пробелов |
Axon_pro |
| 22 | файл | двоичный .dat |
pro/0/m001.dat |
Результат. PNG рядом с файлом данных: pro/0/m001.png.
Пример.
400 100 -6 6 197 256 0 55.6 1100 30 12 18 10 200 5. 1 9 9 100 100 Axon_pro pro/0/m001.dat
Тонкости.
- Произведение kx·ky не должно превышать 65536, иначе программа откажется работать. Разумно kx = ky = 100, предельно — 180. При артефактах уменьшите число точек.
- На осях стоят настоящие значения аргументов, но для рисунка фигура должна быть примерно одинаковой по трём осям. Ось z берётся за основу, а размеры по x и y подгоняются множителями sx и sy.
- Значение dv в примере — 200; подбирайте его, отталкиваясь от примера.
- В текущем коде вместо vz передаётся vx, так что третья координата точки зрения на рисунок не влияет.
№24. 2D as ANIM — анимация сечений
Что делает. Показывает строки матрицы по очереди как плоский график — получается анимация, в которой кривая меняется со временем.
Входные данные — одна строка: пять чисел, подпись, файл.
| Поле | Что писать | Пример |
|---|---|---|
| 1 | nx — точек в каждой кривой | 400 |
| 2 | ny — число кривых (кадров) | 100 |
| 3, 4 | x1, x2 — аргумент в первой и последней точке | -20.48 20.48 |
| 5 | tp — пауза между кадрами, в десятых долях секунды | 4 |
| 6 | подпись, _ вместо пробелов |
Intensity |
| 7 | двоичный файл .dat |
pro/0/m001.dat |
Управление.
| Клавиша | Действие |
|---|---|
| Enter | запустить анимацию |
| Пробел | остановить |
| → / ← | остановить; следующий Enter запустит вдвое быстрее / медленнее |
| ↑ | остановить и спросить номер кривой (пока не нажмёте Cancel) |
| ↓ | пошаговый режим: 0, затем снова ↓ — следующая кривая |
| Esc | выход |
Пример.
400 100 -20.48 20.48 4 Intensity pro/0/m001.dat E
Тонкости. nx·ny не может быть больше, чем размер файла в байтах, делённый на 4.
№49. EPS 1D — график кривых в EPS и PDF
Что делает. Строит график кривых в векторном формате EPS и переводит его в PDF — для статей. Входные данные — смесь чисел и команд PostScript из книги автора (учебник по PostScript); если вы не знаете PostScript, меняйте в примере только числа.
Что нужно заранее.
- Установленный MiKTeX (для перевода EPS в PDF нужна его программа
epstopdf.exe). - Данные — двоичные файлы
pro/in<номер>.dat, по файлу на кривую (например,pro/in999.dat; для примера скопируйте его изpro/0/).
Входные данные — первые строки файла (рабочая папка — pro):
| Строка | Что писать |
|---|---|
| 1 | ширина и высота рисунка в pt, число кривых, номер результата (3 → файлы f003.eps и f003.pdf) |
| 2 | подписи: размер шрифта перед def, координаты подписей перед m, тексты в скобках с кодами шрифтов (I — курсив, L — прямой, ib — нижний индекс, dsN/isN — уменьшить/вернуть размер); последние два числа — сдвиг начала координат |
| 3 | оси: перед par — длины осей, размеры рисок, размер чисел, пределы горизонтальной и вертикальной осей; перед parx и parf — первая длинная риска, шаг между длинными, число коротких; axx, axf — нарисовать оси с числами (варианты axx0, axx1, axx2 — без чисел, верхняя без чисел, верхняя с числами) |
| 4 и далее | по строке на кривую: номер файла in…dat, множитель, делающий числа целыми (не больше 4 цифр), толщина линии, цвет r g b, начало и конец аргумента, число точек, множитель для приведения к вертикальной оси |
| последняя | путь к папке bin MiKTeX на вашем компьютере |
Результат. pro/f003.eps; после ответа Yes на вопрос программы —
ещё и pro/f003.pdf, который сразу открывается.
Пример (автора; путь к MiKTeX замените своим):
700 450 1 3
/FS 26 def 13 412 m (I)I( / )L(I)I()L(0)ib 500 20 m (\()L(D)G(E)I( / )L(E)I(\))L( x 10)L(4)it gs 77 92 tr
600 300 6 12 26 -2.4 2.4 0 90 par -2 1 0 parx axx 0 20 0 parf axf
999 1 1.5 slw 0 0 0 srgb -2.28 2.28 77 0.1 figl
C:\_vk\Miktex\miktex\bin
Тонкости. Число точек в строке кривой может быть меньше числа значений в
файле, но не больше. Перевод в PDF идёт через runsys.bat и работает только в
Windows.
№50. EPS 2D — карта матрицы в EPS и PDF
Что делает. Вторая часть «EPS-набора»: рисует матрицу картой контраста в EPS и переводит в PDF.
Что нужно заранее. MiKTeX (как у №49); матрица — двоичный файл
pro/m<np>.dat (для примера скопируйте m998.dat из pro/0/ в pro/).
Входные данные — две первые строки. Первая — это кусок кода VKACL, в котором достаточно менять числа:
| Параметр | Значение |
|---|---|
| np | номер файла: 998 → pro/m998.dat |
| nx | точек по первому аргументу (вторая размерность вычисляется по размеру файла) |
| Sc | масштаб в процентах (100 — пиксель равен pt) |
| Sx | сдвиг нижней подписи от середины, pt |
| x1, x2 | пределы первого аргумента |
| y1, y2 | пределы второго аргумента |
| f1, f2 | пределы значений функции |
| m | контраст: 1 — цветной, максимум белый; 2 — серый, максимум чёрный; 3 — цветной, максимум чёрный; 4 — серый, максимум белый |
| pp | две цифры — сколько пикселей на точку по x и по y |
После #pr в той же строке — подписи осей на PostScript (xti, yti).
Вторая строка — путь к папке bin MiKTeX.
Результат. В папке pro: p998.png (голая картинка), p998.eps,
p998EPS.txt (картинка в коде EPS, для продвинутых) и, после ответа Yes,
p998.pdf.
Пример (автора):
# np=998; nx=400; Sc=100; Sx=-35; x1=-3; x2=4; y1=105; y2=125; f1=0; f2=61.7; m=1; pp=11; #pr /xti{(x)I(, )H ds2 (MKM)H is2}bd /yti{(z)I(, )H ds2(CM)H is2 40 0 rm (I)I( / I)I()H(0)ib}bd\E
C:\_vk\Miktex\miktex\bin
Тонкости. На сайте автора сказано, что файл берётся из папки data, а
результаты пишутся в папку eps; в коде программы и то и другое — папка
pro. Русские буквы в подписях PostScript не используются.
№67. 1D PIC 2 — графики для всех файлов папки
Что делает. Для каждого двоичного файла папки рисует график (как №20 с форматом t = 3) и записывает его в PNG, не показывая. Удобно, когда файлов много и они одинаково устроены — например, одна зависимость при разных внешних параметрах.
Входные данные — одна строка из одиннадцати полей:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | nf — число функций | 1 |
| 2 | np — точек на функцию | 77 |
| 3 | nb — первая точка на графике | 1 |
| 4 | ng — сколько точек рисовать | 77 |
| 5, 6 | x1, x2 — начальное и конечное значение аргумента | -1 1 |
| 7 | s — масштаб (меньше 10; 1 — обычный) | 1 |
| 8 | ni — сколько чисел пропустить в начале файла (при ni = np·i пропускаются i первых функций) | 0 |
| 9 | подпись, _ вместо пробелов |
рис._1 |
| 10 | папка с файлами | pro/1/ |
| 11 | папка для графиков (можно ту же) | pro/1/ |
Результат. <папка графиков>/<имя>.png для каждого файла.
Пример. Скопируйте in999.dat из pro/0/ в pro/1/ (можно ещё одну
копию под другим именем), затем:
1 77 1 77 -1 1 1 0 рис._1 pro/1/ pro/1/
Тонкости. Лучше брать папки внутри папки программы и писать относительный
путь. Символ _ программа заменяет на пробел не только в подписи, но и в
путях к папкам — папки с _ в имени не подойдут.
№70. DAT to PNG 1 — картинка из фрагмента матрицы
Что делает. Как №03, но для одного файла: рисует прямоугольный фрагмент матрицы (или всю матрицу) без осей и записывает в PNG с заданным именем.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | файл матрицы без .dat |
pro/0/m003 |
| 2 | файл картинки без .png |
pro/2/m003 |
| 3, 4 | ширина и высота матрицы | 640 169 |
| 5, 6 | сдвиг фрагмента по горизонтали и вертикали (от левого нижнего угла) | 0 0 |
| 7, 8 | ширина и высота фрагмента | 640 169 |
| 9 | отражение: 0 — нет, 1 — по высоте, 2 — по ширине, 3 — по обеим |
0 |
| 10 | число из трёх цифр I S P: P — палитра (0 — серая, 1–4 — цветные), S = 1 — не показывать на экране, I = 1 — обратить палитру (минимум белый); ведущие нули можно не писать | 4 |
Результат. pro/2/m003.png; показывается на экране, если S = 0.
Пример.
pro/0/m003 pro/2/m003 640 169 0 0 640 169 0 4
Тонкости. Если полей меньше десяти, программа сообщит, что чего-то не хватает.
Тексты и файлы
Программы для работы с текстовыми файлами и с файлами вообще: поиск, подсчёт, замена, шифрование, склейка, редактирование, электронные книги.
Общие правила записи входных данных — в разделе Как записывать входные данные.
| № | Название | Для чего |
|---|---|---|
| 02 | SYMBOL | сколько раз символ встречается в файле |
| 05 | FIND WORD | найти слово во всех файлах папки |
| 15 | CIPHER | редактор зашифрованных текстов |
| 25 | EDITOR | большой редактор текстов |
| 26 | LINE EDIT | править одну строку файла |
| 36 | COPY FILEs | склеить файлы в один |
| 64 | TXT to FB2 | электронная книга FB2 |
| 72 | DAT MOD 2 | замены текста во всех файлах папки |
| 75 | Exe FILE | открыть файл по расширению |
№02. SYMBOL — сколько раз символ встречается в файле
Что делает. Считает, сколько раз заданный символ встречается в файле, и показывает число в окне. Например, по символу перевода строки можно узнать число строк.
Входные данные — одна строка, в одном из двух видов:
| Вид | Что писать | Пример |
|---|---|---|
| обычный | сам символ и сразу, без пробела, путь к файлу | @pro/note.txt |
| по коду | знак ^, сразу путь к файлу, пробел, номер символа в Юникоде, пробел |
^pro/0/figure.pro 10 E |
Результат. Окно с текстом File has this symbol N times.
Пример — сколько строк (символов с кодом 10) в файле:
^pro/0/figure.pro 10 E
Тонкости.
- Второй вид нужен для символов, которые не набрать на клавиатуре: перевод строки (10), табуляция (9), пробел (32) и т. п.
- В обычном виде путём считается всё, что стоит после символа, до конца
строки, поэтому не ставьте в конце ничего лишнего. Если сомневаетесь,
пользуйтесь видом с
^. - В файле входных данных можно держать строки для многих файлов и выбирать нужную курсором.
№05. FIND WORD — поиск слова во всех файлах папки
Что делает. Ищет слово во всех файлах с заданным расширением в одной папке, показывает список найденных мест и предлагает посмотреть или отредактировать эти файлы.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | слово (любое, хоть одна буква; без пробелов) | @ |
| 2 | расширение файлов, без точки | acl |
| 3 | папка без разделителя в конце | pro |
Результат. Файл pro/word_in_files.txt: по строке на файл — имя и номера
байтов, где найдено слово. Он показывается в редакторе, затем программа
предлагает выбор:
| Кнопка | Что будет |
|---|---|
| See | по очереди открываются найденные файлы; курсор стоит на первой букве найденного слова |
| Edit | то же, но файлы можно править; при выходе по Esc файл перезаписывается |
| Exit | конец работы |
При просмотре Esc переходит к следующему месту, а крестик окна прекращает работу.
Пример — найти символ @ во всех файлах .acl папки pro:
@ acl pro E
Тонкости.
- Вложенные папки не просматриваются.
- Расширение сравнивается по первым трём буквам:
htmнайдёт и.html. - Если ничего не найдено, программа так и скажет.
№15. CIPHER — редактор зашифрованных текстов
Что делает. Позволяет хранить текстовый файл на диске только в зашифрованном виде и при этом редактировать его как обычный текст. Ключ — число от 1 до 255.
Что нужно заранее. Текстовый файл с латиницей (коды 0–127) и русскими буквами в кодировке windows-1251.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | режим: 1 — отредактировать обычный текст и зашифровать; 2 — расшифровать, отредактировать и снова зашифровать; 3 — только расшифровать и записать |
2 |
| 2 | ключ, от 1 до 255 | 123 |
| 3 | путь к файлу | pro/0/Эти-глаза-напротив.txt |
Результат. Тот же файл, перезаписанный (зашифрованным или расшифрованным — по режиму).
Пример.
2 123 pro/0/Эти-глаза-напротив.txt E
Тонкости.
- Обычный порядок: первый раз режим
1, дальше —2, а чтобы вернуть файлу обычный вид —3. - Все операции с одним файлом делайте с одним и тем же ключом. Забытый ключ не восстановить.
№25. EDITOR — большой редактор текстов
Что делает. Открывает указанный файл в большом редакторе — с множеством функций обработки текста и использования его для других операций. Описание редактора — на сайте автора: vkNotepad.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | путь к файлу | pro/note.txt |
Пример.
pro/note.txt
Тонкости.
- Чтобы редактор мог открывать сайты, укажите в 17-й строке файла
vkNP/par.txtполный путь к своему браузеру (сейчас там путь автора). - Для проверки опечаток нужен словарь из архива
vktot.zip. - Файл
pro/note.txt— «дежурная записная книжка» автора, в неё можно писать что угодно.
№26. LINE EDIT — правка одной строки файла
Что делает. Показывает в редакторе одну строку файла с заданным номером,
предварительно заменив в ней символы ~ на переводы строк; после правки
делает обратную замену и записывает строку на место. Удобно для файлов-«баз»,
где каждая строка — отдельная запись: код программы, подпись к фотографии и
т. п. Так, например, устроены pro00.txt и idc00.txt.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | номер строки | 63 |
| 2 | путь к файлу | pro00.txt |
Результат. Исправленная строка в том же файле. Если нужно только посмотреть, закройте редактор крестиком — ничего не изменится.
Пример (автора — строка 63 файла с кодом программ):
63 pro00.txt
Тонкости. pro00.txt — это код готовых программ, а idc00.txt — ваши
входные данные. Правьте их, только понимая, что делаете; для пробы возьмите
копию файла.
№36. COPY FILEs — склеить файлы в один
Что делает. Складывает несколько файлов побайтно, один за другим, и записывает результат в новый файл. Годится и для текстов, и для музыки.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | папка — только относительно папки программы, без разделителя в конце | pro/0 |
| 2 | имена файлов этой папки через +, без пробелов |
matrix.txt+matrix.txt+matrix.txt |
| 3 | имя нового файла | new.txt |
Результат. pro/0/new.txt.
Пример.
pro/0 matrix.txt+matrix.txt+matrix.txt new.txt E
№64. TXT to FB2 — электронная книга
Что делает. Делает электронную книгу формата FB2 из текстового файла с простой специальной разметкой.
Что нужно заранее.
- Текст книги в файле
.txt(кодировка windows-1251), размеченный по правилам автора. В начале файла — строки с параметрами книги, например`название == Моя книга,`фамилия == Иванов; главы и абзацы отмечаются особыми символами. Правила — в файлеpro/0/book.htm(изvkacld.zip) или на сайте: book.htm. Образец —pro/0/mylife.txt. - Картинка обложки: файл JPG с тем же именем рядом с текстом
(
mylife.jpgдляmylife.txt).
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | путь к текстовому файлу с расширением | pro/0/mylife.txt |
Результат. pro/0/mylife.fb2. Программа предлагает сразу открыть его.
Пример.
pro/0/mylife.txt
№72. DAT MOD 2 — замены текста во всех файлах папки
В списке автора эта программа носит то же имя, что и №55, но работает с текстом.
Что делает. Меняет текст во всех файлах папки сразу — любого типа. Файлы переписываются на месте, исходного вида не останется.
Входные данные — одна строка: номер операции, папка, тексты.
| Поле | Что писать | Пример |
|---|---|---|
| 1 | номер операции, 1–6 | 2 |
| 2 | папка, с разделителем в конце | pro/1/ |
| 3 … | тексты, нужные операции, через пробел | старое новое |
| № | Что делает | Тексты |
|---|---|---|
| 1 | переводит русские буквы из windows-1251 в UTF-8 и заменяет в тексте указание windows-1251 на utf-8 |
— |
| 2 | заменяет текст 1 на текст 2 | 2 |
| 3 | попеременно: текст 1 → текст 2, затем текст 3 → текст 4, снова текст 1 … — так меняют пары скобок, (…) на […] |
4 |
| 4 | заменяет всё от текста 1 до текста 2 включительно на текст 3: например, все (123) на точку |
3 |
| 5 | сортирует строки по алфавиту | — |
| 6 | перенумеровывает строки: после каждого перевода строки, пропустив один символ, три следующих заменяет номером 001, 002, … (для списков ссылок) | — |
Результат. Изменённые файлы в той же папке. Программа ничего не показывает — смотрите результат сами.
Пример.
1 pro/1/ E
2 pro/1/ старое новое E
3 pro/1/ ( [ ) ] E
4 pro/1/ ( ) . E
Тонкости.
- Преобразование необратимо — сделайте копию папки. В папке не должно быть посторонних файлов.
- Тексты — только из печатных символов, без пробелов. Чтобы что-то удалить или заменить на пробел, замените это на редкий символ, а его потом уберите в редакторе.
- Лишняя буква
Eв конце не мешает — автор даже советует её ставить.
№75. Exe FILE — открыть файл по расширению
Что делает. Менеджер файлов особого вида: вы выбираете файл, а программа «исполняет» его в зависимости от расширения.
| Расширение | Что будет |
|---|---|
| pdf, htm, jpg, png, gif, mp3, wma, mp4, wmv, avi, flv, mkv, mov | открывается программой, которую для этого назначила система (в Линуксе — браузером) |
| dat | рисуется график чисел (формат float, 4 байта); картинка графика записывается рядом, <имя>.png |
| acl | выполняется как программа на VKACL |
| mid | проигрывается музыка |
| остальные | открываются в большом редакторе |
После этого программа спрашивает, повторить ли.
Входные данные — одна строка: путь к любому файлу в той папке, с которой начать выбор.
| Поле | Что писать | Пример |
|---|---|---|
| 1 | путь к файлу | pro/note.txt |
Пример.
pro/note.txt
Тонкости. Вся строка считается именем файла: пишите его с первой позиции,
без пробелов (замените их на - или _) и без лишних символов в конце.
Сайты
Эти программы готовят веб-страницы: сайт с фотографиями, слайд-шоу, статью
из текста, сложный сайт по разметке, копию чужой статьи, страницу для
перевода. Результат — файл .htm, который можно открыть в браузере на своём
компьютере или выложить в интернет.
Готовую страницу программа обычно предлагает открыть (кнопки Wait /
Go). Если браузер не открылся, найдите файл в папке или кликните
runsys.bat в главной папке программы. Общие правила записи входных данных —
в разделе Как записывать входные данные.
| № | Название | Для чего |
|---|---|---|
| 01 | FOTO SITE | сайт фотографий с комментариями |
| 04 | SLIDE SHOW | слайд-шоу по картинкам папки |
| 38 | SIMP SITE | простой сайт из текста |
| 44 | COMP SITE | сложный сайт по разметке |
| 52 | FOTO SHOW | фото-шоу под музыку |
| 66 | WEB SITE | копия статьи из интернета |
| 74 | CH LANG | страница с кнопкой перевода |
№01. FOTO SITE — сайт фотографий с комментариями
Что делает. Делает заготовку сайта: таблицу иконок фотографий по пять в ряд. Клик по иконке показывает большую фотографию, клик по фотографии возвращает к таблице. Иконки шириной 240 px программа делает сама. Комментарии к фотографиям вы потом дописываете в готовый файл вручную (можно и не дописывать — сайт готов сразу).
Что нужно заранее. Папка с большими фотографиями (разметка страницы рассчитана на ширину около 1280 px), их число кратно пяти. Папка для сайта существует.
Входные данные — семь первых строк файла:
| Строка | Что писать | Пример |
|---|---|---|
| 1 | название сайта для вкладки браузера и соцсетей (на странице не видно) | Круиз 25. 12-я часть… |
| 2 | заголовок на странице | Фотографии с круиза… |
| 3 | автор, дата, адреса — что угодно | Кон В. Г. . . . 26-06-2025 |
| 4 | адрес папки с фотографиями на сервере (для будущей публикации) | http://kohnvict.narod.ru/s/2506/C/ |
| 5 | папка с фотографиями на компьютере, с / в конце |
pro/1/ |
| 6 | папка для иконок и сайта, с / в конце |
pro/2/ |
| 7 | любой HTML-код в самом конце страницы (реклама, ссылки); если не нужен — точка или пробел | <iframe … src="icons.htm"></iframe> |
Результат. В папке из строки 6: иконки s<имя>.jpg (к имени фотографии
спереди добавлена буква s) и страница m9s.htm. Иконки и страница должны
лежать в одной папке; m9s.htm можно переименовать.
Пример (автора). Скопируйте m91.jpg … m95.jpg из pro/0/ в pro/1/
и icons.htm из pro/0/ в pro/2/:
Круиз 25. 12-я часть. Фотографии с круиза на теплоходе Александр Пушкин. Виктор Кон. Victor Kohn.
Фотографии с круиза на теплоходе Александр Пушкин в 2025-м году. 12-я часть.
Кон В. Г. . . . 26-06-2025 . . . http://kohnvict.narod.ru
http://kohnvict.narod.ru/s/2506/C/
pro/1/
pro/2/
<iframe frameborder=0 width=860 height=80 src="icons.htm"></iframe>
Тонкости.
- Строки 4 и 5 программа вставляет в код страницы как есть; адрес из строки 4 стоит в коде закомментированным, работает адрес из строки 5. Чтобы выложить сайт в интернет, в готовом файле переставьте комментарий с одного адреса на другой; так же можно поправить букву диска для флешки.
- Надёжнее всего держать обе папки внутри папки программы и писать относительные пути, как в примере: программа сама посчитает путь от страницы к фотографиям.
- Если число фотографий не кратно пяти, лишние не попадут в таблицу иконок.
- Места для комментариев в
m9s.htmотмечены пустыми строками; удобно писать текст после каждого ряда из пяти иконок. - Страница подгружает фон, скрипт и кнопку перевода с сайтов автора — без интернета они не появятся.
№04. SLIDE SHOW — слайд-шоу по картинкам папки
Что делает. Делает страницу слайд-шоу по всем картинкам папки: каталог иконок, удобная навигация, смена кадров. Интернет не нужен — картинки показываются прямо с компьютера.
Что нужно заранее. Папка с картинками в формате, который понимает браузер (PNG, JPG, GIF). Лучше одного размера — иначе они будут приведены к одному.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | папка с картинками — относительно папки программы или полный путь | pro/1/ |
| 2, 3 | числитель и знаменатель отношения высоты картинок к ширине | 3 4 |
Результат. Страница pro/show.htm; программа предлагает её открыть.
Пример — картинки 1280×960 (отношение 3 : 4) в pro/1/:
pro/1/ 3 4 E
Тонкости.
- Подсказок на странице нет: кликните в любом месте, чтобы пойти дальше, а кнопка H покажет, что можно делать. Кнопки дублируются клавишами.
- Картинки упорядочены по алфавиту имён.
- Если задать отношение, не совпадающее с картинками, они растянутся. При слишком большом отношении кнопки могут уйти за правый край окна — чуть уменьшите его.
- Остальные параметры показа — во второй строке файла
pro/b/showA.txt(кроме первых двух, которые берутся из входных данных); их смысл описан на сайте программы слайд-шоу. - Музыка заиграет, только если в
show.htmвручную указать реальный файл. - Чтобы выложить сайт в интернет, в
show.htmзамените адрес папки на адрес на сервере и переименуйте файл. На смартфоне страница не работает.
№38. SIMP SITE — простой сайт из текста
Что делает. Превращает обычный текстовый файл в веб-страницу по шаблону автора. Разметка почти не нужна.
Что нужно заранее. Текстовый файл .txt: в первой строке — заголовок
статьи, во второй — автор и что-нибудь о нём (всё в одну строку), с третьей —
сам текст; абзацы разделяются пустой строкой.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | путь к текстовому файлу без .txt |
pro/0/exam0 |
Как работает. Сначала текст открывается в редакторе — его можно подправить. После выхода по Esc рядом создаётся страница.
Результат. pro/0/exam0.htm.
Пример.
pro/0/exam0 E
Тонкости. Файл exam0.txt — одновременно образец и инструкция по
подготовке текста. Не правьте его, а скопируйте под другим именем. Если
нужна страница посложнее — №44, если для перевода — №74.
№44. COMP SITE — сложный сайт по разметке
Что делает. Делает сайт на HTML, CSS и JavaScript, но писать на этих языках не нужно: текст размечается простыми трёхсимвольными командами. Описание разметки — на сайтах автора txthtmh и txt-htm-ex.
Как устроены проекты. Рабочая папка — pro/sites/. Каждый сайт — проект
с номером от 01 до 99: текст проекта 2 лежит в pro/sites/pro02.txt, готовый
сайт — pro/sites/pro02.htm, дополнительные файлы (объекты txthtmo.txt,
внешние тексты txthtmt.txt, картинки, музыка) — в папке pro/sites/02/.
Проект 01 уже есть: он показывает все возможности разметки. Новый проект
создаётся сам — копированием проекта 01, когда вы впервые укажете его номер.
Входные данные — одна строка из двух чисел: номер проекта и номер операции.
| Операция | Что делает |
|---|---|
| 1 | открыть текст проекта в большом редакторе |
| 2 | собрать сайт |
| 3 | править объекты — по одному; номер объекта выбирается в таблице из 99 кнопок (работают 9), кнопка 99 — выход |
| 4 | править внешние тексты — повторяющиеся фрагменты, по одному на строку |
| 5 | открыть в браузере описание разметки (pro/sites/txthtmh.htm) |
Результат. pro/sites/proNN.htm.
Пример — удобно сразу записать пять строк и выбирать операцию курсором:
2 1
2 2
2 3
2 4
2 5
Тонкости.
- После каждой операции программа спрашивает, продолжать ли; сайт удобно делать по частям, объект за объектом.
- Картинки и другие файлы нового проекта скопируйте в его папку вручную (или ссылайтесь на другие папки и адреса в интернете).
- Во внешних текстах вместо перевода строки пишут символ
`. Редактор не показывает номера строк, но Ctrl+W переключает режим длинных строк, а Alt+I сообщает номер строки под курсором. - Для пробы автор советует проект 01: выполните операцию 2 и согласитесь
открыть готовый файл. Если сайт не открылся, кликните
runsys.bat.
№52. FOTO SHOW — фото-шоу под музыку
Что делает. Делает страницу фото-шоу: фотографии сменяются автоматически под музыку, есть панель управления и правила (скрыты, открываются кнопкой).
Что нужно заранее. Файл данных .txt (путь считается от папки pro):
| Строка файла данных | Что писать |
|---|---|
| 1 | название сайта (для вкладки и соцсетей) |
| 2 | комментарий к показу — любой длины, он прокручивается |
| 3 | адрес mp3: в интернете (http://…) или на компьютере (file:///…) |
| 4 и далее | адреса фотографий, по одному на строку, тоже http:// или file:/// |
Последняя строка тоже должна кончаться переводом строки.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | файл данных — от папки pro, без .txt |
0/in |
| 2 | имя страницы — от папки pro, без .htm |
out |
Как работает. Файл данных сначала открывается в редакторе; после выхода по Esc программа собирает страницу.
Результат. pro/out.htm.
Пример (файл данных pro/0/in.txt есть в vkacld.zip):
0/in out
Тонкости. Полный путь с буквой диска для файла данных задавать нельзя. Оформление и скрипт страница загружает с сайта автора, поэтому смотреть её нужно при подключённом интернете. Автор оптимизировал показ под Google Chrome.
№66. WEB SITE — копия статьи из интернета
Что делает. Помогает переложить интересную статью из интернета в свой аккуратный формат: текст отдельно, картинки отдельно — таблицей иконок, которые открываются по клику. Работа полуавтоматическая: часть шагов вы делаете вручную, строго по порядку.
Входные данные — восемь первых строк файла:
| Строка | Что писать |
|---|---|
| 1 | путь к будущему файлу страницы (полный или от папки программы) |
| 2 | название сайта для вкладки браузера и соцсетей |
| 3 | ссылка на источник |
| 4 | файл со списком таких статей (относительно будущей страницы) |
| 5 | заголовок, который увидит читатель |
| 6 | фоновая картинка (относительно будущей страницы) |
| 7 | любой HTML-код в самом верху страницы; если не нужен — один пробел |
| 8 | параметры картинок: менять только значения после = |
Параметры восьмой строки: n — число картинок (0 — без картинок, остальное
тогда не важно); w, h — их ширина и высота; af — общее начало адресов
картинок; ef — окончание (расширение). Картинки нумеруются двумя цифрами:
af + 01 + ef, af + 02 + ef, …
Как работать.
- Выйдите из редактора по Esc. Программа запишет страницу и откроет её в большом редакторе.
- Выделите текст статьи на сайте-источнике, скопируйте (Ctrl+C) и вставьте в место с подсказкой (Ctrl+V).
- Проверьте, что абзацы разделены ровно одной пустой строкой. Строку-заголовок
можно выделить знаком
$в начале и в конце. - В меню редактора выберите кодировку UB (Unicode Big Endian) и концы строк как в Windows. Выйдите по Esc.
- Программа сделает замены и снова откроет текст. Ничего не меняйте, только выберите кодировку UTF-8 General marker и выйдите по Esc.
Результат. Файл из строки 1. Сам он не открывается — найдите и откройте его в браузере.
Пример (адреса условные):
pro/1/article.htm
Название для вкладки браузера
https://example.ru/source-article
readme.htm
Заголовок статьи
../0/bgim2.gif
n=0; w=900; h=675; af="http://example.ru/pics/"; ef=".jpg";
Тонкости. Пример автора во входных данных ссылается на его папки и работает только на его компьютере — подготовьте свои данные. Ссылку на источник и автора статьи оставляйте обязательно.
№74. CH LANG — страница с кнопкой перевода
Что делает. Превращает текстовый файл в веб-страницу с кнопкой выбора языка: Google переводит её с русского на любой из 54 языков. Переведённый текст можно скопировать.
Что нужно заранее. Текстовый файл .txt:
- первые символы файла —
&1, последние (без пробелов и перевода строки перед ними) —&2; без них страница не покажется; - абзацы начинаются после пустой строки, заголовки разделов — после двух пустых строк;
- можно использовать простые HTML-теги (
<b>…</b>,<i>…</i>, картинки). Общий заголовок — так:&1<h1>Заголовок</h1>.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | путь к текстовому файлу без .txt |
pro/0/MFL1s |
Результат. Текст копируется в pro/b/textforsite.js, а в браузере
открывается страница pro/b/ini-fr01.htm.
Пример.
pro/0/MFL1s E
Как перевести. Нужен интернет. Выберите язык кнопкой на странице и пролистайте весь текст — Google переводит то, что появилось на экране. Затем Ctrl+A, Ctrl+C и вставьте текст в любой редактор.
Тонкости.
- Страница состоит из нескольких файлов, и при следующем запуске
textforsite.jsперезаписывается. Чтобы сохранить результат, скопируйтеini-fr01.htmпод другим именем и вставьте в него содержимоеtextforsite.jsвместо ссылки на этот файл. - Сохранить из браузера переведённый текст можно только в mhtml или PDF; при сохранении в HTML сохранится русский оригинал.
- Если нужна страница одним файлом, берите №38 или №44.
Звук, анимация, игры
Презентации, слайд-шоу под музыку, проигрыватель mp3, игры и демонстрационные анимации. Общие правила записи входных данных — в разделе Как записывать входные данные.
| № | Название | Для чего |
|---|---|---|
| 27 | LECTURE | показ презентации или картинок папки |
| 41 | GAME PIC | игра-мозаика |
| 42 | GAME MOV | движение упругих шаров |
| 63 | FM-PLAYER | проигрыватель mp3 в браузере |
| 69 | vkSS | слайд-шоу под музыку с переходами |
| 99 | DEMO | рекламная анимация VKACL |
№27. LECTURE — показ презентации и картинок
Что делает. Три связанных применения:
- Показ доклада из zip-архива со слайдами-картинками — во весь экран, с быстрым переходом к любому слайду через таблицу иконок.
- Просмотр всех JPG и PNG в любой папке — и заодно подготовка архива для первого режима.
- Запуск программ на VKACL прямо из презентации: анимаций, расчётов, дополнительных материалов к слайдам.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | zip-архив презентации (режим 1) или папка с картинками, с разделителем в конце (режим 2); лучше относительно папки программы | zip/240725.zip |
| 2 | необязательно: сколько пикселей снизу оставить свободными (чтобы видеть панель задач); по умолчанию 25 | 0 |
Управление.
| Действие | Клавиша | Или клик мышью |
|---|---|---|
| следующий слайд | → | в правой верхней четверти |
| предыдущий слайд | ← | в левой верхней четверти |
| таблица иконок всех слайдов (клик по иконке — к слайду) | ↑ | в правой нижней четверти |
| выход | ↓ (автор называет и Esc) | в левой нижней четверти |
| запустить программу VKACL для текущего слайда | Enter | — |
записать архив lect.zip (только в режиме 2, когда показан слайд) |
Z | — |
Как устроен архив презентации.
- Папка
lect: слайдыs001.jpg,s002.png, … — букваsи трёхзначный номер слайда; картинка-таблица иконокs999.jpg; других картинок быть не должно (числовые файлы можно). - Папка
anim: картинки для программ-анимаций; в ней должен лежать хотя бы один файл, даже неиспользуемый, иначе при выходе будет ошибка. - Программы для слайдов: либо общая
lect/s999.pro, в которой варианты для разных слайдов выбираются по переменнойku(номер слайда), либо отдельныеlect/s005.proдля слайда 5 и т. д.
Как подготовить архив. Откройте в режиме 2 папку со слайдами (имена
любые), нажмите Z — в главной папке программы появится lect.zip
с папкой lect. Папку anim и программы добавьте в архив вручную, затем
переименуйте архив как угодно (расширение .zip).
Результат. Показ на экране. В режиме 2, если таблицы иконок s999 ещё нет,
программа строит её (это небыстро) и сохраняет в папку, чтобы в следующий раз
не строить заново.
Пример — демонстрационная презентация из vkacld.zip:
zip/240725.zip 0
Тонкости.
- Лишнюю букву
Eв конце не ставьте: второе поле программа читает как число. - Слайды меньшей ширины ставятся по центру, остальное поле чёрное.
- Папки
lectиanimна время показа извлекаются из архива и удаляются после выхода. - Программы на VKACL для слайдов должны быть полностью отлажены: при первой же ошибке показ прекратится. Набор готовых анимаций автора описан на его странице animations.
№41. GAME PIC — игра-мозаика
Что делает. Тренажёр зрительной памяти. Вы рассматриваете картинку, затем она режется на 48 квадратов 100×100, которые перемешиваются. Нужно собрать картинку обратно, меняя квадраты местами попарно.
Входные данные. Нет — программа сразу открывает окно выбора картинки в
папке pro/0/.
Как играть.
- Выберите картинку размером 800×600 — например,
game.jpgизvkacld.zip. - Рассмотрите и запомните её, затем нажмите Enter.
- Наведите мышь на квадрат и нажмите Пробел (или кликните) — он отметится крестиком. Наведите на квадрат, с которым надо поменяться, и снова Пробел или клик.
- Повторяйте, пока картинка не соберётся. Надоело — закройте окно крестиком.
- Программа спросит, сыграть ли ещё.
Тонкости. Если выбранная картинка не 800×600, программа уменьшит или
увеличит её, запишет как pro/0/tmp.jpg и попросит запустить игру снова и
выбрать этот файл.
№42. GAME MOV — движение упругих шаров
Что делает. Демонстрация законов механики: пронумерованные твёрдые шары летают в замкнутой области, отскакивая от стенок, препятствий и друг от друга без потери энергии. Четыре сюжета; параметры можно менять и наблюдать.
Входные данные — одна строка: номер сюжета и его параметры.
| Сюжет | Что писать после номера |
|---|---|
1 — прямоугольная область |
W H Nh Nv E Ns R — ширина и высота области (px), шаров по горизонтали и по вертикали, полная энергия, сколько шаров сначала движется, радиус шара |
2 — круглая область со столбиками |
Dr Dp Dw Np Nw RDp RDw SS Nb — диаметры области, шара и столбика (px), число шаров и столбиков, диаметры кругов расстановки шаров и столбиков (% от области), начальная скорость (px), число неподвижных шаров между подвижными |
3 — две области, соединённые щелью |
как в сюжете 1, плюс ширина щели Ws |
4 — сложная область, всё задано |
скорость шаров V (подберите под свой компьютер) |
Управление. Enter — движение, Пробел — остановка, Esc — выход.
Пример — значения автора, оптимальные для каждого сюжета:
1 500 500 13 13 900 1 10
2 400 40 20 6 12 90 60 20 10
3 600 400 6 8 200 12 10 22
4 6
Тонкости.
- Ошибки во входных данных не проверяются: при неудачных значениях программа может просто перестать работать — запустите её заново.
- Не давайте одному шару слишком большую скорость: за один шаг он может «проскочить» стенку. Большую энергию лучше раздать нескольким шарам.
№63. FM-PLAYER — проигрыватель mp3 в браузере
Что делает. Делает страницу-проигрыватель для всех mp3-файлов папки с удобной навигацией и открывает её в браузере. Интернет не нужен.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | папка с mp3 — полный путь или от папки программы | pro/1/1/ |
| 2 | вид проигрывателя, 1 или 2 |
2 |
Результат. Страница pro/b/mp.htm; программа предлагает открыть её.
Пример.
pro/1/1/ 2 E
Тонкости.
- Без папки с mp3-файлами программу запускать бессмысленно — сначала положите несколько файлов в какую-нибудь папку.
- Файлы других типов в папке не мешают; mp3 упорядочиваются по алфавиту.
- На странице есть кнопка Info с подсказками. Вид 1 подстраивается под ширину окна браузера; если не помещается по высоте — сузьте окно.
- Страница перезаписывается при каждом запуске. Чтобы выложить её в интернет,
замените в
mp.htmадреса файлов на адреса на сервере и переименуйте её.
№69. vkSS — слайд-шоу под музыку
Что делает. Показывает слайд-шоу по заранее написанному протоколу: картинки сменяются под фоновую музыку с эффектными переходами, могут увеличиваться и плыть по экрану, на них появляются надписи.
Входные данные — одна строка:
| Поле | Что писать | Пример |
|---|---|---|
| 1 | путь к файлу протокола | pro/0/sky0.vks |
Протокол — текстовый файл:
- Первая строка: адрес музыки,
|, пять чисел: номер картинки, к которой вернуться после последней; ширина и высота окна показа, px; смещение левого верхнего угла окна от угла экрана (отрицательное — окно по центру). - Строки картинок:
#, адрес картинки,|, время показа в сотых долях секунды; дальше необязательно — номер перехода (0–12), смещение центра картинки по x и y, и тройка чисел для «движения»: интервал между кадрами (сотые секунды; 0 — без движения), шаг в пикселях (может быть отрицательным) и вид —0изменение размера,1движение по горизонтали,2по вертикали. - Строки надписей (после строки картинки, сколько угодно):
text=Текст| T S X Y R G B K— время показа (сотые секунды), размер шрифта, левый нижний угол текста, цвет, начертание (0–3). Шрифт — Sans Serif; русский текст допустим.
Адреса — в виде URL: http://… или для своего компьютера File:C:/папка/файл.
Музыка — только MIDI (.mid).
Переходы: 0 — мгновенно; 1 — старая картинка схлопывается к центру; 2, 3, 4 — новая вырастает из центра, из левого верхнего, из левого нижнего угла; 5 — падает сверху; 6 — наползает слева; 7 — плавное смешивание; 8 — затухание и проявление; 9–12 — новая выталкивает старую слева, справа, сверху, снизу.
Управление.
| Клавиша | Действие |
|---|---|
| Esc | выход |
| Enter | пауза; повторно — музыка сначала и следующий кадр |
| ↑ / ← / Backspace / PgUp | назад на 1 / 2 / 3 / 4 кадра |
| PgDn | вперёд на 5 кадров |
| Home / End | в начало / в конец |
| C / O | выключить / включить музыку |
| любая другая | вперёд на 1 кадр |
Пример — протокол pro/0/sky0.vks; первые его строки:
File:C:/0/sky/Julio-Iglesias-Je-Nai-Pas-Change.mid|1 840 640 -1 -1
#File:C:/0/sky/sky.png|400 0 0 0
#File:C:/0/sky/s000.jpg|400 1 0 0
#File:C:/0/sky/s001.jpg|400 2 0 0
Картинки и музыки к нему в архивах нет: их нужно скачать с Яндекс-диска
автора (ссылка — во входных данных программы) и положить в C:\0\sky\.
Тонкости.
- Не закрывайте окно крестиком — выходите по Esc.
- Картинки показываются без масштабирования: большие обрезаются окном, а меньшие ложатся поверх предыдущих, и те видны по краям.
- Надпись появляется только после того, как закончится движение картинки; на движущиеся картинки надписи не ставьте. Координаты надписи отсчитываются по картинке, а не по окну.
- Правила протокола описаны и на сайте автора: vkss.
№99. DEMO — рекламная анимация VKACL
Что делает. Показывает анимации, рекламирующие язык VKACL: картинку, которая растёт, и текст, который появляется строка за строкой, под музыку.
Входные данные. Нет. Поставьте курсор в начало файла и нажмите Esc.
Как работать. В меню выберите Picture size, Text size или All together; Exit — выход. Остановить анимацию — крестиком в правом верхнем углу окна.
Автоматизация и система
Программы, которые запускают другие программы, файлы и команды: панель кнопок, «проигрыватель в проигрывателе» для своего кода, цепочки готовых программ, команды операционной системы. Общие правила записи входных данных — в разделе Как записывать входные данные.
| № | Название | Для чего |
|---|---|---|
| 28 | RUNNER | панель из 176 кнопок |
| 29 | PLAYER | свой код на VKACL: написать и выполнить |
| 56 | CHAIN 1 | несколько программ подряд |
| 57 | CHAIN 2 | цепочка с данными прямо в протоколе |
| 76 | SYSTEM | команды операционной системы |
| 78 | CHAIN 3 | цепочка для каждого файла папки |
№28. RUNNER — панель кнопок
Что делает. Показывает таблицу из 176 кнопок (11 × 16). Каждую кнопку вы настраиваете сами: открыть файл в редакторе, запустить его средствами системы, выполнить как программу VKACL, открыть папку. Так под рукой оказываются самые нужные файлы, документы и программы.
Входные данные. При запуске файл входных данных не показывается — сразу появляется таблица. Первая строка файла — пояснение (не читается), со второй строки идут кнопки: строка 2 — кнопка 1, строка 3 — кнопка 2 и так далее. Формат строки:
Название кнопки| действие путь
| Действие | Что делает с файлом |
|---|---|
1 |
открывает в большом редакторе |
2 |
открывает программой, назначенной в системе для этого типа файлов (только Windows) |
3 |
выполняет как программу на VKACL |
4 |
открывает в малом редакторе — он умеет показывать сайты с адресом https |
5 |
открывает папку в проводнике Windows |
Путь — полный или от папки программы.
Как работать. Кликните кнопку — действие выполнится, и таблица появится
снова (после действия 5 программа, судя по коду, заканчивает работу). Выход —
крестик окна таблицы. В заготовке автора первая кнопка
Edit ID открывает сам файл кнопок (pro/0.par) — так их и настраивают;
изменения сохранятся.
Пример — начало файла кнопок:
Пояснения: первая строка программой не читается
Edit ID| 1 pro/0.par
Справка| 4 help.txt
Заметки| 1 pro/note.txt
О программе| 2 pro/hdata/about.htm
Папка pro| 5 pro
Тонкости.
- Если файла или папки нет, программа сообщит об этом и закончит работу — так же удобно сделать кнопку «Выход» на несуществующий файл (в заготовке это последняя, 176-я кнопка Exit).
- Действия
2и5в Линуксе не работают. - Для действия
3годятся только программы, которые не портят переменные проигрывателя.
№29. PLAYER — свой код на VKACL
Что делает. Проигрыватель программ на VKACL, написанный на самом VKACL.
Позволяет быстро написать и выполнить небольшую программу — расчёт, график,
обработку файла — не выходя из режима проигрывателя. Для серьёзной работы
автор советует среду разработки (_rund.bat).
Что нужно заранее. Файл с расширением .pro с кодом. Проигрыватель сам
файлы не создаёт — сделайте файл средствами системы, лучше в папке pro/0/.
Образец — pro/0/figure.pro из vkacld.zip (рисует функции Бесселя).
Входные данные. Нет — роль инструкции играет сам файл входных данных.
Как работать.
- Появится окно с кнопками Help, Start, Exit. Help открывает инструкцию — прочитайте её.
- Start открывает выбор файла
.proв папкеpro/0/. - Код появляется в редакторе. Поправьте его и выйдите по Esc: файл сохранится и выполнится. Если закрыть редактор крестиком, ничего не сохранится и не выполнится.
- При ошибке в коде появится сообщение, и код откроется снова для правки.
- После выполнения выберите: Current — снова этот файл, New — другой, Nothing — выход.
Пример — файл pro/0/test.pro из двух строк:
# a=2^10; b=sqr(2); c=4*art(1);
#m [op=win;] 2^10 = \G a;\n корень из 2 = \G b;\n пи = \G c;\E
Тонкости. В коде нельзя использовать команды #stop и #exit,
переменные на букву U и последние элементы текстового массива t() (с
индексами больше KY−10000): их занимает сам проигрыватель. Как писать на
VKACL — начиная с главы Начало работы.
№56. CHAIN 1 — несколько программ подряд
Что делает. Сама ничего не делает — запускает другие готовые программы одну за другой, каждую со своими заранее подготовленными входными данными.
Что нужно заранее. Входные данные запускаемых программ должны быть уже
записаны без ошибок — исправить их по ходу не получится. Проще всего один раз
запустить каждую программу из меню Index и довести её данные до ума (или
отредактировать нужную строку idc00.txt программой №26).
Входные данные — одна строка из пар чисел:
| Поле | Что писать | Пример |
|---|---|---|
| 1, 2 | номер программы и номер строки в её входных данных | 31 1 |
| 3, 4 | следующая пара | 54 1 |
| … | и так далее |
Пример — запустить №31 и №54, каждую с первой строкой её данных:
31 1 54 1
Тонкости.
- Курсор должен стоять в начале строки, строка — не длиннее 500 символов.
- Лишних символов в конце нет: число полей должно быть чётным.
- В цепочке работают не все программы. Лучше всего — те, что берут данные из одной строки и не требуют ответов пользователя.
№57. CHAIN 2 — цепочка с данными в протоколе
Что делает. Тоже запускает программы по цепочке, но входные данные каждой пишутся прямо здесь, в протоколе, — заранее ничего готовить не надо.
Входные данные — первые строки файла (позиция курсора не важна, выполняется верхний протокол):
- Каждая строка: в первых двух позициях — номер программы (
20,03или3), затем пробел, а с четвёртой позиции — ровно та строка входных данных, которую эта программа взяла бы из своего файла. - Строка короче шести символов заканчивает протокол; обычно пишут
@. - Номер
00— особый: остаток строки выполняется как код VKACL. Так можно, например, включить таймер перед программой и узнать время её работы после.
Пример (автора) — нарисовать график №20 и карту №21:
20 1 77 1 77 0 76 1 3 0 рис._1 pro/0/in999.dat E
21 21 21 -5 5 -4 4 9 9 2 1 1 Матрица_чисел pro/0/matrix.txt E
@
Тонкости.
- Подходят только программы, которые берут данные из одной строки, выбранной курсором. Программы с многострочными данными (№8, 10, 11 и т. п.) в цепочке работать не будут.
- Диалоги программ по ходу цепочки появляются как обычно. Чтобы графики не всплывали, у №20 задайте отрицательный масштаб, у №21 — вторую цифру td равной 1.
- Программе без входных данных нужна строка не короче шести символов: номер и любые символы после пробела.
№76. SYSTEM — команды операционной системы
Что делает. Заменяет командные файлы: выполняет команды операционной
системы, записанные по одной на строку в jsc1.txt (Windows) или jsc2.txt
(Линукс) в главной папке. Систему программа определяет сама.
Что нужно заранее. Свои команды в jsc1.txt. Сейчас там команды
автора (пути к его программам) — замените их. Команда — имя программы с
аргументами; папки в путях Windows разделяйте знаком /; лишних пробелов не
ставьте. Например:
notepad.exe C:/vkacl/pro/note.txt
explorer.exe C:/vkacl/pro
Входные данные — одна строка: номера строк файла команд через пробел.
| Поле | Что писать | Пример |
|---|---|---|
| 1 … | номера команд, которые выполнить | 1 2 |
Пример.
1 2
Тонкости.
- Не ставьте в конце лишнюю букву
E: все поля программа читает как номера. - Не все программы запускаются так же, как из системы, — проверяйте на своём
компьютере; иногда запуск блокирует защита системы. Лучше всего так
открываются браузер с нужным файлом и обычные программы. Команда
java -jar …срабатывает, только пока фокус не ушёл в другие окна.
№78. CHAIN 3 — цепочка для каждого файла папки
Что делает. Как №57, но в пакетном режиме: выполняет протокол по очереди для каждого файла указанной папки. Годится для программ, которые обрабатывают один файл.
Входные данные — первые строки файла:
| Строка | Что писать |
|---|---|
| 1 | папка с файлами, относительно папки программы |
| 2 и далее | протокол, как у №57: номер программы в двух позициях, пробел, её входные данные; конец — строка @ |
В данных вместо имени файла пишут \T$1 $2\u32; — это полный путь к
очередному файлу и пробел после него. Номер файла (1, 2, …) доступен как
\I1 $0; и годится для составления новых имён: например, 2\I1 $0;f
превратится в 21f, 22f, …
Пример (автора) — дважды убрать выбросы и транспонировать каждую матрицу
2304×2304 из pro/5/ программой №77:
pro/5/ E
77 3 * \T$1 $2\u32; \T$1 $2\u32; 2304 2304 25 0 E
77 1 * \T$1 $2\u32; \T$1 $2\u32; 2304 2304 E
77 3 * \T$1 $2\u32; \T$1 $2\u32; 2304 2304 25 0 E
77 1 * \T$1 $2\u32; \T$1 $2\u32; 2304 2304 E
@
Тонкости. В этом примере результат каждой операции записывается поверх исходного файла — работайте с копиями. Демонстрационных данных у программы нет.
Разное
Справочники и калькулятор. Общие правила записи входных данных — в разделе Как записывать входные данные.
| № | Название | Для чего |
|---|---|---|
| 30 | UNICODES | какие символы есть в шрифте |
| 31 | PTOE | таблица Менделеева — справочник и записная книжка |
| 62 | CALCUL | калькулятор на 8 переменных |
№30. UNICODES — символы шрифтов
Что делает. Показывает таблицами все символы выбранного шрифта с их номерами в Юникоде. Нужна, чтобы узнать, какие символы (буквы, греческие, математические знаки) можно использовать в надписях программ, например №08.
Входные данные. Нет — программа сразу показывает список шрифтов.
Как работать.
- Выберите шрифт из списка (Arial, Times New Roman, Verdana и др.) или нажмите New и введите имя своего шрифта. Exit — выход.
- На странице — 340 символов: 17 строк по 20. Слева — номер первого символа строки, сверху — номера столбцов 0–19; номер символа = номер строки + номер столбца.
- Любая клавиша или клик — следующая страница; PgUp или ↑ — предыдущая; Esc — назад к списку шрифтов.
Тонкости. Если шрифта на компьютере нет, Java подставит свой шрифт по умолчанию — таблица будет, но не того шрифта.
№31. PTOE — таблица Менделеева
Что делает. Интерактивная таблица Менделеева и одновременно записная книжка: клик по элементу открывает текст о нём, который можно дополнять и исправлять — программа всё запомнит. В текстах есть ссылки на ресурсы интернета, в том числе на статьи из книги автора.
Входные данные. Нет. Поставьте курсор в начало первой строки и нажмите Esc.
Как работать.
- Кликните по клетке элемента — его текст откроется в большом редакторе.
- Правьте и выходите по Esc: изменения сохранятся в
pro/b/ptoe.dbn. - Чтобы открыть ссылку из текста, поставьте на неё курсор и нажмите F4.
- Чтобы закончить, кликните по картинке вне клеток элементов — например, по портрету Менделеева.
Тонкости. Первая ссылка ведёт на статью автора и точно работает; другие со временем могут исчезнуть — заменяйте их новыми.
№62. CALCUL — калькулятор
Подробный разбор с примерами — Разбор: №62 CALCUL.
Что делает. Вычисляет выражения и показывает в окне значения восьми
переменных a b c d e f g h. В одной строке можно записать целую цепочку
вычислений — использовать уже посчитанные переменные в следующих формулах.
Входные данные — одна строка присваиваний вида переменная=выражение;:
| Что | Правило |
|---|---|
| присваивание | имя=выражение; — точка с запятой в конце обязательна |
| операции | + - * / ^ (степень); < — меньшее из двух, > — большее из двух |
| функции | abs sqr log exp sin cos tan ars arc art int sgn sfi cfi bj0 bj1, аргумент в скобках |
| числа | 2.5, 2,5, 4.4e1 |
| результат | то, что присвоено переменным a–h |
Результат. Окно со значениями a…h в формате вида 1.9635+01
(то есть 1,9635·10¹).
Пример (автора):
x=-4.4e1; h=abs(x); a=sqr(h); b=log(h); c=exp(x); d=sin(x); e=ars(d); f=cos(x); g=arc(d);
Тонкости. Строк можно держать сколько угодно, выполняется та, в начале
которой курсор. Лишнюю букву E в конце не ставьте — она будет понята как
часть выражения. Подробности и ловушки — в разборе.
Разбор: №08 SLIDE MAKER
Программа №08 собирает картинку-слайд: на основу заданного размера кладёт другие картинки и пишет поверх них текст. Так делают титульный слайд доклада, объявление, заставку к видео, кнопку для сайта. Краткое описание — в каталоге: №08 SLIDE MAKER.
В этом разборе мы сначала запустим пример автора, а потом соберём свой титульный слайд 1280×720 из трёх картинок и двух надписей.
Что понадобится
- Установленная программа и архив
vkacld.zip, разложенный по папкам (см. Установка). - Три файла из
pro/0/, которые нужно скопировать вpro/1/— рабочую папку программы №08:
| Файл | Что это | Размер |
|---|---|---|
000000.png |
чёрный прямоугольник | 256×192 |
m91.jpg |
фотография | 1280×960 |
jad.jpg |
портрет | 220×250 |
Шаг 1. Открываем программу
- Запустите
_runp.bat. - Нажмите Index, затем кнопку 8.
- Откроется редактор. Наверху — пример входных данных, ниже — варианты автора и его инструкция.
Программа №08 читает первые строки файла и выполняет только верхний вариант. Позиция курсора ей не важна.
Шаг 2. Пример автора
Наверху файла стоит (или впишите сами) такой вариант:
512 512 1 3|slide
256 256 0 0 0 9 9|000000.png
256 100 5 1 30 0 255 0 |Arial|на полотно любого размера
256 200 5 1 30 255 0 0 |Arial|можно ставить картинки
256 300 5 1 30 255 255 255 |Arial|и тексты любых фасонов
Разберём его построчно.
Строка 1 — 512 512 1 3|slide:
| Число | Смысл |
|---|---|
512 512 |
основа шириной 512 и высотой 512 пикселей |
1 |
N1 — на основу кладётся одна картинка |
3 |
N2 — будет три надписи |
slide |
имя результата: получатся slide.png и slide.jpg |
Строка 2 — картинка: 256 256 0 0 0 9 9|000000.png:
| Число | Смысл |
|---|---|
256 256 |
центр картинки — в центре основы |
0 |
поворота нет |
0 0 |
скашивания нет |
9 9 |
увеличить в 9 раз по ширине и по высоте |
000000.png |
файл в pro/1/ |
Чёрный прямоугольник 256×192, увеличенный в 9 раз, становится 2304×1728 и закрывает всю основу — получается чёрный фон.
Строки 3–5 — надписи, например 256 100 5 1 30 0 255 0 |Arial|на полотно любого размера:
| Число | Смысл |
|---|---|
256 100 |
точка привязки: x = 256 (середина), y = 100 пикселей от верхнего края |
5 |
способ привязки: текст центрируется в точке и по ширине, и по высоте |
1 |
жирный шрифт |
30 |
размер шрифта 30 пикселей |
0 255 0 |
цвет — зелёный |
Arial |
шрифт |
на полотно… |
сам текст, до конца строки |
Нажмите Esc. Слайд появится в окне в левом верхнем углу экрана:
на чёрном фоне три строки — зелёная, красная и белая, одна под другой.
В папке pro/1/ появятся slide.png и slide.jpg.
Затем программа спросит Do you like to change parameters? Ответ Yes снова откроет входные данные — так удобно подгонять слайд понемногу. No закончит работу.
Шаг 3. Как устроены координаты
- Начало отсчёта — левый верхний угол основы; x растёт вправо, y — вниз.
- Для картинки X, Y — положение её центра. Картинка поворачивается и масштабируется вокруг центра.
- Картинки кладутся в том порядке, в каком записаны: следующая закрывает предыдущую. Надписи всегда поверх картинок.
Для надписи X, Y — точка привязки, а число M (от 1 до 9) говорит, какой частью текст к ней прикладывается:
| M | слева | по центру | справа |
|---|---|---|---|
| низом | 1 | 2 | 3 |
| серединой высоты | 4 | 5 | 6 |
| верхом | 7 | 8 | 9 |
Например, M = 1 — левый нижний угол текста в точке X, Y; M = 5 — центр
текста в точке; M = 9 — правый верхний угол в точке.
Шаг 4. Свой слайд
Сделаем титульный слайд 1280×720: фотография во весь слайд, тёмные полосы сверху и снизу для текста, повёрнутый портрет слева, заголовок и подпись. Вставьте в самое начало файла, над примером автора, семь строк:
1280 720 4 2|title
640 360 0 0 0 1 1|m91.jpg
640 70 0 0 0 5 0.7|000000.png
640 650 0 0 0 5 0.7|000000.png
200 360 5 0 0 1.2 1.2|jad.jpg
640 70 5 1 64 255 255 255 |Arial|Готовые программы VKACL
640 650 5 2 40 255 220 0 |Arial|слайд собран программой №08
Что здесь происходит:
| Строка | Что делает |
|---|---|
1280 720 4 2|title |
основа 1280×720, четыре картинки, две надписи, результат title |
640 360 … 1 1|m91.jpg |
фотография 1280×960 в центре, без изменений: по ширине она точно по слайду, лишнее сверху и снизу обрежется |
640 70 … 5 0.7|000000.png |
чёрный прямоугольник, растянутый в 5 раз по ширине (1280) и сжатый до 0,7 по высоте (≈134): полоса вдоль верхнего края |
640 650 … 5 0.7|000000.png |
такая же полоса внизу — один файл можно класть сколько угодно раз |
200 360 5 0 0 1.2 1.2|jad.jpg |
портрет слева, увеличенный в 1,2 раза и наклонённый на 5° |
640 70 5 1 64 … |
заголовок: по центру верхней полосы, жирный, 64 px, белый |
640 650 5 2 40 255 220 0 … |
подпись: по центру нижней полосы, курсив, 40 px, жёлтый |
Нажмите Esc и посмотрите на результат. Если наклон портрета
получился не в ту сторону, поменяйте знак угла (-5). Ответьте Yes,
поправьте числа, снова Esc — и так, пока слайд не понравится.
Шаг 5. Результат
В папке pro/1/ лежат title.png и title.jpg размером 1280×720. Входные
данные сохранились — в следующий раз программа откроет их в том же виде.
Что дальше:
- соберите несколько слайдов в PDF — программа №09;
- покажите их как презентацию — программа №27;
- узнайте, какие символы есть в шрифте, — программа №30.
Если что-то не так
| Что видно | Почему | Что делать |
|---|---|---|
| File: … is absent!, на месте картинки светлый квадратик | файла нет в pro/1/ или опечатка в имени |
скопируйте файл в pro/1/, проверьте имя и расширение |
| Font or Text is absent! | в строке надписи нет второй черты | или текст пустой |
формат: числа |шрифт|текст |
| надпись не там, где ждали | y отсчитывается сверху; не тот способ привязки M | начните с M = 5 — текст центрируется в точке |
| картинка пропала | её закрыла картинка, записанная ниже | поменяйте строки местами |
| надпись взялась из текста инструкции | N2 больше, чем строк надписей | N1 и N2 должны точно совпадать с числом строк |
| последняя надпись не появилась | N2 меньше, чем строк надписей | увеличьте N2 |
| файл результата назван странно | после имени в первой строке стоят пробелы или буква E |
после | — только имя, до конца строки |
| шрифт выглядит «не тем» | такого шрифта нет на компьютере, Java подставила свой | выберите шрифт из списка программы №30 |
Разбор: №21 2D MAP
Программа №21 рисует матрицу чисел как карту: каждая точка — цветной или серый прямоугольник, по краям — оси с подписями, сбоку — шкала цветов. Так смотрят результаты расчётов, распределения интенсивности, рельеф — любую функцию двух переменных, заданную таблицей. Краткое описание — в каталоге: №21 2D MAP.
В разборе мы нарисуем карту по текстовой таблице, попробуем разные виды графика, затем переведём таблицу в двоичный файл программой №16 TXT to DAT и нарисуем карту уже по нему.
Что понадобится
Установленная программа и архив vkacld.zip, разложенный по папкам
(см. Установка). Нужен файл pro/0/matrix.txt из этого
архива.
Шаг 1. Смотрим на данные
pro/0/matrix.txt — 21 строка по 21 целому числу от 0 до 99, всего 441
число. Это «холм»: по краям нули, к центру значения растут до 99. Первые
строки файла:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 17 31 38 42 43 42 38 31 17 0 0 0 0 0 0
0 0 0 0 0 32 44 51 56 58 59 58 56 51 44 32 0 0 0 0 0
Как программа №21 читает такие данные:
- числа идут подряд, по строкам матрицы; первая строка файла — нижняя строка карты, следующая — над ней, и так до верхней;
- как числа разбиты на строки файла, не важно — хоть все в одну строку; важно только их общее количество, nx × ny;
- разделители — пробелы, табуляции, переводы строк. Запятую программа считает десятичной точкой, поэтому разделять числа запятыми нельзя.
Шаг 2. Первая карта
Запустите
_runp.bat, нажмите Index, затем 21.В редакторе первая строка — как раз наш случай:
21 21 -5 5 -4 4 9 9 2 1 1 Матрица_чисел pro/0/matrix.txtКурсор уже стоит в начале первой строки (подойдёт и вторая позиция). Нажмите Esc.
Разберём строку поле за полем:
| Поле | Значение | Смысл |
|---|---|---|
| nx | 21 |
в каждой строке матрицы 21 точка |
| ny | 21 |
строк 21 |
| x1, x2 | -5 5 |
горизонтальная ось размечается от −5 до 5 |
| y1, y2 | -4 4 |
вертикальная ось — от −4 до 4 |
| p1, p2 | 9 9 |
каждая точка — квадрат 9×9 пикселей, карта будет 189×189 |
| tf | 2 |
полный график: карта, оси, шкала, подпись; цветная палитра 1 |
| sf | 1 |
обычный размер |
| td | 1 |
данные — текст; показать график на экране; палитра обычная |
| подпись | Матрица_чисел |
над картой будет «Матрица чисел» — _ стал пробелом |
| файл | pro/0/matrix.txt |
где лежат числа |
Результат. На экране — цветная карта холма с осями и шкалой цветов. Над
ней подпись и пара чисел — настоящие минимум и максимум матрицы (0 и 99);
шкала цветов показывает значения, нормированные на интервал 0–1. Картинка
записана в pro/0/matrix.png — рядом с файлом данных, с тем же именем.
Программа спросит Job is done! Continue? Ответьте Yes, чтобы вернуться к входным данным и попробовать варианты.
Шаг 3. Варианты
Не правьте удачную строку — скопируйте её ниже и меняйте копию; нужный вариант выбирается курсором. Попробуйте по одной правке:
| Что поменять | Строка | Что получится |
|---|---|---|
| tf = 1 | 21 21 -5 5 -4 4 9 9 1 1 1 Матрица_чисел pro/0/matrix.txt |
оттенки серого |
| tf = 3 | 21 21 -5 5 -4 4 9 9 3 1 1 Матрица_чисел pro/0/matrix.txt |
вторая цветная палитра |
| tf = 5 | 21 21 -5 5 -4 4 9 9 5 1 1 _ pro/0/matrix.txt |
только картинка 189×189, без осей и шкалы (подпись не нужна, но _ писать обязательно) |
| td = 101 | 21 21 -5 5 -4 4 9 9 2 1 101 Матрица_чисел pro/0/matrix.txt |
палитра обращена: максимум и минимум поменялись цветами |
| td = 11 | 21 21 -5 5 -4 4 9 9 2 1 11 Матрица_чисел pro/0/matrix.txt |
график не показывается, только записывается в файл |
| p1 p2 = 4 4 | 21 21 -5 5 -4 4 4 4 2 1 1 Матрица_чисел pro/0/matrix.txt |
карта меньше: 84×84 |
| sf = 2 | 21 21 -5 5 -4 4 9 9 2 2 1 Матрица_чисел pro/0/matrix.txt |
весь график вдвое крупнее |
Все варианты пишут в один и тот же файл pro/0/matrix.png — каждый
следующий заменяет предыдущий.
Как читать td: это число до трёх цифр. Последняя цифра — формат данных
(1 текст, 2 двоичный файл). Средняя — 1, если график не показывать.
Первая — 1, если обратить палитру. Нули впереди не пишут: 1, 11,
101, 111, 2, 12…
Шаг 4. Переводим таблицу в двоичный файл (№16)
Текст удобен человеку, но большие матрицы программы VKACL хранят в двоичных
файлах .dat: по 4 байта на число, без заголовка (см.
Числовые файлы .dat). Перевести таблицу умеет программа №16.
В проигрывателе: Index → 16.
Выберите или впишите строку:
441 1 0 pro/0/matrix EЭто значит: прочитать 441 число, как вектор (
1во втором поле), ничего не пропуская в начале файла (0), изpro/0/matrix.txt— расширение.txtне пишется. БукваEв конце не читается, она лишь показывает, что после пути есть пробел.То же самое можно записать как матрицу — 21 число в строке, 21 строка:
21 21 0 pro/0/matrix E. В режиме матрицы каждая строка матрицы должна стоять на отдельной строке файла.Нажмите Esc. Появится файл
pro/0/matrix.dat.
Проверка: размер файла должен быть 441 × 4 = 1764 байта.
Заметьте: программа №16 заменяет табуляции на пробелы прямо в исходном текстовом файле.
Шаг 5. Карта по двоичному файлу
Вернитесь к программе №21 и добавьте строку, где последняя цифра td — 2, а
файл — .dat:
21 21 -5 5 -4 4 9 9 2 1 2 Из_двоичного_файла pro/0/matrix.dat
Получится та же карта с новой подписью. Картинка снова запишется в
pro/0/matrix.png: имя берётся из имени файла данных без расширения. Если
хотите сохранить обе картинки, скопируйте matrix.dat под другим именем
(например, matrix2.dat) и рисуйте по копии.
Шаг 6. Свои данные
- Подготовьте текстовый файл: nx чисел в строке, ny строк; первой записывайте нижнюю строку карты. Таблица из Excel, сохранённая как «текст с разделителями табуляции», подойдёт, но в Excel верхняя строка идёт первой — карта выйдет перевёрнутой по вертикали. Тогда просто переставьте строки в обратном порядке.
- Положите файл в папку внутри папки программы, например
pro/1/data.txt. - Впишите в №21 строку со своими nx, ny, пределами осей и путём.
- Если данных много, сначала переведите их в
.datпрограммой №16 — чтение двоичного файла быстрее.
Если что-то не так
| Что видно | Почему | Что делать |
|---|---|---|
| сообщение об ошибке, курсор не в начале строки | строка выбирается по курсору | поставьте курсор в первую позицию нужной строки |
| карта «полосатая», картинка сдвинута | nx или ny не совпадают с данными | проверьте: nx × ny = числу чисел в файле (для .dat — размеру файла, делённому на 4) |
| числа прочитаны неверно | в файле запятые между числами | разделяйте числа пробелами |
| подпись обрезана по первому слову | в подписи пробел | вместо пробелов _ |
| программа не видит файл | опечатка в пути или пробел в нём | путь без пробелов, лучше относительный |
| карта вверх ногами | в файле первой идёт верхняя строка | переставьте строки |
| окна нет, а файл есть | вторая цифра td равна 1 | уберите её: td = 1 или 2 |
Разбор: №62 CALCUL
Программа №62 — калькулятор выражений. В строке пишут цепочку присваиваний
вроде r=2.5; a=r*r;, а программа показывает в окне значения восьми
переменных a, b, c, d, e, f, g, h. Строк можно накопить
сколько угодно — получается записная книжка формул, которая сохраняется между
запусками. Краткое описание — в каталоге: №62 CALCUL.
На самом деле строка калькулятора — это команда присваивания языка VKACL. Поэтому всё, что здесь сказано о выражениях, верно и для программ на VKACL.
Шаг 1. Открываем калькулятор
Запустите
_runp.bat, нажмите Index, затем 62.В редакторе — три строки-примера автора и под ними инструкция:
X=121; M=0.15/(366-X); a=0.85+(323-X)*M; b=0.85+(97-X)*M; x=-4.4e1; h=abs(x); a=sqr(h); b=log(h); c=exp(x); d=sin(x); e=ars(d); f=cos(x); g=arc(d); x=4.4e1; a=int(x); b=sgn(x); c=sfi(x); d=cfi(x); e=bj0(x); f=bj1(x); g=x^2; h=2*(x+4)/5;
Шаг 2. Первый расчёт
Поставьте курсор в самое начало второй строки и нажмите Esc. Программа выполнит строку:
| Присваивание | Что вычисляется | Значение |
|---|---|---|
x=-4.4e1; |
x = −4,4·10¹ | −44 |
h=abs(x); |
модуль | 44 |
a=sqr(h); |
квадратный корень | 6,6332 |
b=log(h); |
натуральный логарифм | 3,7842 |
c=exp(x); |
экспонента | 7,7811·10⁻²⁰ |
d=sin(x); |
синус (аргумент в радианах) | −0,017702 |
e=ars(d); |
арксинус | −0,017703 |
f=cos(x); |
косинус | 0,99984 |
g=arc(d); |
арккосинус | 1,5885 |
В окне значения показаны так (точное число пробелов может отличаться):
a= 6.6332+00, b= 3.7842+00, c= 7.7811-20, d= -1.7702-02
e= -1.7703-02, f= 9.9984-01, g= 1.5885+00, h= 4.4000+01
Это экспоненциальная запись без буквы E: четыре знака после точки, затем
знак и двузначный порядок. 6.6332+00 — это 6,6332·10⁰ = 6,6332;
-1.7702-02 — это −1,7702·10⁻² = −0,017702; 4.4000+01 — это 44.
Закройте окно. Программа спросит Job is done! Continue? — ответ Yes вернёт в редактор, No закончит работу.
Шаг 3. Свой расчёт
Допишите в начало файла новую строку — площадь и длину окружности радиуса 2,5, гипотенузу треугольника 3–4–5 и ещё несколько величин:
r=2.5; p=4*art(1); a=p*r^2; b=2*p*r; c=sqr(3^2+4^2); d=art(1)*180/p; e=exp(1); f=log(10); g=10<3; h=10>3;
| Переменная | Формула | Результат | В окне |
|---|---|---|---|
p |
4·arctg 1 = π (своей константы π в языке нет) | 3,14159 | не показывается |
a |
π·r² — площадь круга | 19,635 | 1.9635+01 |
b |
2·π·r — длина окружности | 15,708 | 1.5708+01 |
c |
√(3² + 4²) — гипотенуза | 5 | 5.0000+00 |
d |
arctg 1 в градусах | 45 | 4.5000+01 |
e |
число e | 2,7183 | 2.7183+00 |
f |
ln 10 | 2,3026 | 2.3026+00 |
g |
меньшее из 10 и 3 | 3 | 3.0000+00 |
h |
большее из 10 и 3 | 10 | 1.0000+01 |
Поставьте курсор в начало этой строки и нажмите Esc. Вспомогательные
переменные r и p в окне не видны — показываются только a–h. Поэтому
всё, что хотите увидеть, присваивайте им.
Правила записи
Присваивание: имя=выражение;. Точка с запятой нужна после каждого
присваивания, включая последнее. Пробелы вокруг = и между элементами
допустимы.
Числа: 42, 3.14, 3,14 (запятая тоже годится), 1.5e3, 2.5E-4.
Операции — от более сильной к более слабой:
| Уровень | Операции | Смысл |
|---|---|---|
| 1 | < > |
меньшее из двух, большее из двух |
| 2 | ^ |
степень |
| 3 | * / |
умножение, деление |
| 4 | + - |
сложение, вычитание |
Скобки ( ) — как обычно.
Функции — имя из трёх букв и аргумент в скобках:
| Функция | Что считает |
|---|---|
abs(x) |
модуль |
sqr(x) |
квадратный корень, x ≥ 0 |
log(x) |
натуральный логарифм, x > 0 |
exp(x) |
экспонента, x < 500 |
sin(x), cos(x), tan(x) |
синус, косинус, тангенс; x в радианах |
ars(x), arc(x) |
арксинус, арккосинус; |x| ≤ 1 |
art(x) |
арктангенс |
int(x) |
целая часть: дробь просто отбрасывается, int(-2.7) = −2 |
sgn(x) |
знак: −1, 0 или 1 |
sfi(x), cfi(x) |
интегралы Френеля S(x) и C(x) |
bj0(x), bj1(x) |
функции Бесселя J₀(x) и J₁(x) |
rnd(0) |
случайное число от 0 до 1 (в списке автора для калькулятора её нет, но язык её знает) |
Имена переменных: одна буква (x, R; большие и маленькие буквы —
разные переменные), буква с цифрой (a1), две буквы (dx). Надёжнее всего
брать маленькие буквы. Не используйте имена, которые занимает сам
проигрыватель: начинающиеся с U, двухбуквенные с последней буквой X, Y
или Z (в том числе AY … KY).
Комментарий. После восклицательного знака ! строку можно продолжить
любым текстом — он не выполняется. Только знака # в таком тексте быть не
должно.
r=2.5; a=4*art(1)*r^2; ! площадь круга радиуса 2,5
Ловушки
| Ловушка | Пример | Как правильно |
|---|---|---|
| минимум и максимум связывают сильнее всего | 1<5+10 даёт 11, а не 1 |
ставьте скобки: 1<(5+10) |
| степень считается слева направо | 2^3^2 = (2³)² = 64 |
2^(3^2) = 512 |
| минус сразу после знака операции — ошибка | 2*-3 |
2*(0-3) или -3*2 |
| логарифм натуральный | log(100) = 4,605 |
десятичный: log(100)/log(10) = 2 |
| углы — в радианах | sin(30) ≠ 0,5 |
sin(30*4*art(1)/180) = 0,5 |
забыли ; в конце |
a=1; b=2 |
a=1; b=2; |
буква E в конце для «видимого пробела» |
a=1; E |
здесь она будет понята как выражение — не ставьте её |
| переменная из a–h не задана | в строке нет h= |
в окне будет старое значение, оставшееся от предыдущих вычислений |
Ошибка в выражении (деление на ноль, корень из отрицательного числа, неизвестная функция) вызывает сообщение интерпретатора, и расчёт прерывается. Если после этого проигрыватель закрылся, запустите его заново — строки входных данных сохранятся, кроме последней правки.
Каждую строку лучше делать самодостаточной — задавать в ней все нужные величины, а не полагаться на значения, посчитанные в прошлый раз.
Что дальше
- Полное описание выражений языка — в справочнике: Выражения и функции.
- Если нужны циклы, графики, таблицы — это уже маленькая программа на VKACL: её можно написать и выполнить программой №29 или в среде разработки (см. Начало работы).
Что такое VKACL
VKACL не похож на языки, к которым вы привыкли. Прежде чем писать первую программу, стоит принять четыре его исходные идеи — иначе всё остальное будет казаться странным.
Идея первая: программа — это поток команд в тексте
В большинстве языков файл состоит из инструкций, а комментарии помечаются
особым знаком. В VKACL наоборот: файл состоит из текста, а команды помечаются
знаком #.
Это обычный текст. Его можно писать свободно:
пояснения, заметки, черновики формул.
#pr Привет!\E
И снова текст, который никто не исполняет.
Интерпретатор ищет ближайший #, выполняет то, что за ним, снова ищет # — и
так до конца файла. Всё между командами он просто пропускает.
Отсюда сразу следует ограничение, о котором стоит помнить с самого начала:
в поясняющем тексте не должно быть символа #. Строка
Здесь мы используем команду #d для заполнения массива.
не комментарий: интерпретатор найдёт #d и попытается его выполнить.
Идея вторая: вся память общая
В VKACL нет объявлений переменных, нет областей видимости, нет локальных переменных у процедур. Есть фиксированный набор ячеек, существующий всегда:
- 55 однобуквенных переменных:
a…z,A…Z,$,%,&; - двухсимвольные:
a0…z9иaa…ZZ; - три больших массива — целый
i(), вещественныйr(), текстовыйt(); - служебный массив
s(), через который команды получают параметры и отдают результаты.
Процедура — это просто именованный кусок кода; данные она получает и возвращает через те же общие ячейки.
У такого устройства есть причина. Автор начинал на Фортране, где массив объявлялся в каждой процедуре с фиксированным размером, «на всякий случай» по максимуму. Он с самого начала сделал иначе, как в ассемблере: одна большая область памяти, а «массив» — это просто номер первого элемента и длина. Тогда массивы укладываются плотно, а вектор можно на ходу считать матрицей, матрицу одной формы — матрицей другой формы, и наоборот, ничего не копируя. Индексы считать несложно, и этому быстро учишься.
Идея третья: команда — это имя, параметры и аргументы
Любая команда выглядит одинаково:
#имя [параметр=значение; параметр=значение;] аргументы
Поле в квадратных скобках необязательно. Важная особенность: параметры
запоминаются. Если вы один раз написали [mo=1;], этот mo останется равным
единице для всех последующих команд, пока его не переопределят. Это удобно и это
же — источник самых неприятных ошибок.
Чего в языке нет
Стоит сказать прямо, чтобы не искать:
- нет операторов сравнения —
<и>заняты под минимум и максимум; условия строят через арифметику и функциюsgn; - нет типов — все скалярные переменные вещественные, преобразование происходит при записи в целый массив;
- нет функций с аргументами — только процедуры без параметров;
- нет рекурсии — вызов процедуры из себя же считается ошибкой;
- нет строк как значений — текст живёт в массиве
t(), и работа с ним ведётся по индексам и длинам.
Взамен язык даёт очень короткую запись для того, что автор делает постоянно: рисовать графики, показывать окна, обрабатывать файлы и картинки, запускать готовые программы.
Идея четвёртая: язык — диспетчер, а не вычислитель
VKACL задуман в первую очередь как язык управления: графика, окна ввода и выбора, работа с файлами и PDF, запуск готовых программ и подпрограмм на Java. Для этого он очень удобен.
Для больших расчётов — тройных циклов по тысяче повторов — интерпретируемый
язык не годится, и VKACL здесь не исключение. Способ, которым такие задачи
решаются в Matlab и в numpy, есть и здесь: операции над массивом целиком.
Их выполняет команда #ma — сложить, умножить, транспонировать,
отсортировать, взять преобразование Фурье, построить сплайн — одной командой,
без цикла. А то, что и так не получается, автор пишет на Java и вызывает из
VKACL как процедуру.
Две реализации
| Интерпретатор автора | Этот проект | |
|---|---|---|
| Что | aclp.jar, Java |
acl-core, Rust |
| Команд | 40 и 54 суперкоманды | ядро языка, #ma, файлы (см. Реализация) |
| Графика, окна, звук, PDF | да | нет; окна выбора и ввода заменены вопросами в консоли |
| Готовые программы | 80 | нет |
| Где взять | страница vkacl | песочница |
Для реальной работы нужен интерпретатор автора. Реализация из этого проекта существует, чтобы примеры туториала запускались прямо на странице и чтобы поведение языка было проверено тестами.
Дальше — первая программа.
Первая программа
Начнём с программы, которая что-то печатает. В VKACL это делается в два приёма, и это первое, что нужно понять про язык.
Вывод в две ступени
#pr Привет, мир!\n\E
#m [op=txt;] \Tp\E
Разберём построчно.
#pr Привет, мир!\n\E — команда формирует текст и кладёт его в текстовый
массив t(). Она ничего не показывает на экране. \n — перевод строки,
\E — обязательный признак конца текста.
#m [op=txt;] \Tp\E — команда показывает текст в окне терминала. \Tp
означает «взять последний фрагмент, записанный #pr».
Конца программы специально отмечать не нужно: интерпретатор просто доходит до конца текста.
Имя команды можно писать длиннее: значимы только первые три буквы, так что
#pr, #pri и #print — одна и та же команда. В программах автора чаще
всего встречается короткая форма #pr. А вот #p — это другая команда:
она только задаёт параметры.
Такое разделение выглядит громоздким, но у него есть смысл: текст в t() можно
накопить, потом отредактировать, записать в файл, показать на экране или
отправить в PDF — источник один.
Почему \E и почему \n
Аргумент #pr — это форматированный текст (в документации автора — FT).
Он не заканчивается на конце строки: интерпретатор читает его, пока не встретит
\E. Поэтому текст можно свободно разносить по строкам.
Внутри работают escape-коды: \n — перевод строки, \t — табуляция,
\# — сам знак #, \\ — обратная косая черта.
Ловушка с пробелами
Перед каждым фрагментом текста интерпретатор пропускает пробелы и переводы строк. Это значит, что так пробел не получить:
#pr A B\E
даст A B (внутренние пробелы сохраняются), а вот так:
#pr A \E
даст A — хвостовой пробел исчезнет, потому что после A идёт \, и пробел
перед ним съеден. Явный пробел записывают кодом символа:
#pr A\u32;\E
\u32; — символ с кодом 32, то есть пробел. Точка с запятой обязательна.
Считаем и печатаем
# a=2; b=3;
# c=a*b+1;
#pr a*b+1 = \G c;\n\E
#m [op=txt;] \Tp\E
Здесь два новых элемента.
# a=2; b=3; — команда вычислений. Она начинается с #, за которым сразу идёт
пробел — это краткая форма команды #c. Каждое присваивание заканчивается
точкой с запятой.
\G c; — вставить значение переменной c в формате «мантисса и порядок».
Результат будет выглядеть так:
a*b+1 = 7.0000+00
Формат \G — фиксированной ширины 11 символов, четыре знака после точки,
двузначный порядок без буквы E. Для целых чисел удобнее \I:
#pr a*b+1 = \I4 c;\n\E
даст a*b+1 = 7 — число выровнено по ширине 4.
Где кончается команда
Программа выполняется сверху вниз. У большинства команд аргументы имеют
понятный конец: у #pr это \E, у #rep — одно число. Но у некоторых команд
аргументов может быть сколько угодно: у вычислений #c — любое число
присваиваний, у #d и #v — любое число значений, у #e — имя процедуры.
Такая команда читает аргументы, пока не встретит один из трёх знаков:
| Знак | Смысл |
|---|---|
# |
началась следующая команда |
@ |
кончилась процедура |
! |
аргументы кончились — дальше обычный текст |
Поэтому после таких команд перед поясняющим текстом ставят !:
# a=2; b=3; !
Здесь пояснение: без восклицательного знака слово «Здесь»
было бы принято за начало ещё одного присваивания.
#pr \G a b;\E
То же нужно, если такая команда стоит последней в программе: без !
интерпретатор продолжит читать аргументы за концом текста и остановится с
ошибкой. Для #e в файле, который вызывается из другой программы, это
проявляется сообщением, что такой процедуры нет.
Отсюда привычка, которую легко перенять у автора: заканчивать вычисления
знаком !, если дальше не идёт сразу другая команда:
# a=2; b=3; c=a*b; !
Что попробовать
Откройте песочницу и запустите:
# n=5; f=1; i=1;
#rep 5
# f=f*i; i=i+1;
#end
#pr 5! = \I6 f;\n\E
#m [op=txt;] \Tp\E
Это факториал пятёрки. #rep 5 … #end — цикл на пять повторений; про него
подробно в главе Ветвления и циклы.
Дальше — вычисления и переменные.
Вычисления и переменные
Команда вычислений — самая частая в любой программе на VKACL. У неё две записи, полностью равнозначные:
#c a=1; b=2;
# a=1; b=2; !
Вторая — просто # и пробел. В реальном коде почти всегда пишут её.
Переменные
Отдельно объявлять ничего не нужно, все ячейки существуют с самого начала и равны нулю.
# a=1; z=2; A=3; Z=4; $=5; %=6; &=7;
# a1=10; b2=20; zz=30; AB=40; !
Доступны:
- однобуквенные —
a…z,A…Z,$,%,&(регистр важен:aиAразные); - буква+цифра —
a0…z9,A0…Z9; - буква+буква —
aa,ab, …,ZZ.
Все они хранят вещественные числа.
Три имени имеют особый смысл по традиции: & — условие для #case (см.
Ветвления), $ и % часто используют как временные.
Операции
# a=2+3; b=7-2; c=2*3; d=7/2; e=2^10; !
| Операция | Что делает |
|---|---|
+ - |
сложение, вычитание |
* / |
умножение, деление |
^ |
возведение в степень |
< |
минимум двух значений |
> |
максимум двух значений |
Да, < и > — не сравнения. a<b — это меньшее из двух чисел.
Приоритеты: главная неожиданность
Порядок связывания в VKACL такой (сверху — сильнее):
<>— минимум и максимум^— степень*/+-
Минимум и максимум связывают сильнее всего. Поэтому:
# m=1<5+10; !
это min(1,5) + 10 = 11, а вовсе не min(1, 15). И
# n=2*3<4; !
это 2 * min(3,4) = 6.
Степень вычисляется слева направо: 2^3^2 равно (2^3)^2 = 64, а не 2^9.
Когда сомневаетесь — ставьте скобки. Они работают обычным образом.
Функции
Имя функции — ровно три буквы, сразу за ним открывающая скобка:
# a=sqr(16); b=log(10); c=exp(1);
# d=sin(1); e=cos(1); f=tan(1);
# g=ars(0.5); h=arc(0.5); k=art(1);
# m=abs(0-7); n=int(3.7); p=sgn(0-2); q=rnd(0); !
| Функция | Смысл | Примечание |
|---|---|---|
sqr |
квадратный корень | ошибка при отрицательном аргументе |
log |
натуральный логарифм | ошибка при аргументе ≤ 0 |
exp |
экспонента | при аргументе < −500 даёт 0 |
sin cos tan |
тригонометрия | аргумент в радианах |
ars arc art |
арксинус, арккосинус, арктангенс | |
abs |
модуль | |
int |
целая часть | отбрасывание к нулю: int(-3.7) = -3 |
sgn |
знак: −1, 0 или 1 | |
rnd |
случайное число из [0,1) | аргумент игнорируется |
sfi cfi |
интегралы Френеля | |
bj0 bj1 |
функции Бесселя первого рода |
Наличие Френеля и Бесселя прямо в языке многое говорит о задачах, ради которых он создавался: Виктор Кон занимается рентгеновской оптикой.
Унарный минус
Минус в начале выражения работает:
# a=-5; b=-sgn(x); !
А вот сразу после другой операции — нет. Запись 2*-3 даёт ошибку. Пишите так:
# a=2*(0-3); !
Идиома 0-x вместо -x в середине выражения встречается в авторском коде
повсеместно.
Числа
# a=42; b=3.14; c=3,14; d=1.5e3; e=2.5e-4; !
Разделителем дробной части может быть и точка, и запятая. Экспонента пишется
через e или E.
Как построить условие
Раз сравнений нет, условия строят арифметикой. Самый частый приём — sgn:
Единица, если q меньше трёх, иначе ноль или минус единица
# &=-sgn(q-3); !
sgn(q-3) равен −1 при q<3, нулю при q=3 и +1 при q>3; минус переводит
это в 1 / 0 / −1. Полученное значение затем разбирает #case.
Другой приём — «зажать» значение через минимум и максимум:
Ограничить x диапазоном от 0 до 100
# x=0>x<100; !
Читается справа налево по приоритетам: сначала x<100 (не больше 100), потом
0>… (не меньше 0).
Дальше — массивы и память.
Массивы и память
Кроме скалярных переменных в VKACL есть четыре массива. Они существуют всегда, общие для всей программы, и индексируются с единицы.
| Запись | Что хранит | Размер |
|---|---|---|
i(n) |
целые числа | 249 999 |
r(n) |
вещественные числа | 25 999 999 |
t(n) |
символы текста | 1 999 999 |
s(n) |
служебные ячейки | 112 |
Обращение к элементу — обычное:
# i(1)=10; i(2)=20;
# r(100)=3.14;
# a=i(1)+i(2); !
Индексы считаются упрощённо
Внутри скобок работает урезанный вычислитель. Допустимы только числа,
скалярные переменные и операции + - * / ^:
# k=5;
# a=i(k); ! это работает
# b=i(k+1); ! и это
# c=i(k*2-1); ! и это
А вот так — нельзя:
# d=i(int(k/2)); ! ошибка: функции в индексах не работают
# e=i(j(1)); ! ошибка: вложенные массивы тоже
Обходной путь один — посчитать индекс заранее в переменную:
# k=7; m=int(k/2); d=i(m); !
Заполнение массива: #d
Перечислять элементы по одному утомительно, поэтому есть команда #d:
#d 6 i(1) 7 0 0 0 9 11 !
Читается так: «шесть значений, начиная с i(1), вот они». Повторы
записываются короче — через звёздочку:
#d 6 i(1) 7 0*3 9 11 !
0*3 означает «ноль три раза». Результат тот же.
За один раз можно задать не больше 500 значений. Команда продолжает читать
группы количество приёмник значения…, пока не встретит следующую команду:
#d 3 i(1) 1 2 3 3 r(1) 1.5 2.5 3.5 !
Копирование: #pas
#pas 4 r(1) i(10)
«Переслать четыре элемента из r(1)…r(4) в i(10)…i(13)». Типы приводятся
автоматически: вещественные округляются при записи в целый массив.
Команда корректно работает при наложении областей — если приёмник правее источника, копирование идёт с конца.
Текстовый массив t()
t() хранит символы. Записать в него можно двумя способами: числовым кодом
# t(200)=65; t(201)=66; t(202)=67; !
или, что гораздо чаще, командой #pr, которая пишет туда форматированный текст.
Прочитать фрагмент обратно в текст — escape-код \T:
#pr \T200 3\E
«Взять три символа начиная с t(200)» — получится ABC.
У \T два аргумента: начало и длина. Оба — простые числа или переменные,
выражения там не работают:
# n=3;
#pr \T200 n\E так можно
#pr \T200 n-1\E так нельзя: напечатается ABC-1
Служебный массив s()
s() — это одновременно и параметры команд, и их результаты. Когда вы пишете
#f [op=size; file=data.txt;]
значение параметра n попадает в s(7), mo — в s(11) и так далее, а размер
файла команда вернёт в s(1).
Ячейки, которые нужны чаще всего:
| Ячейка | Смысл |
|---|---|
s(1) |
результат: размер файла и т. п. |
s(3) |
текущая позиция записи в t() |
s(4), s(5) |
начало и длина последнего фрагмента от #pr |
s(6) |
максимальная занятая позиция в t() |
s(3) — самая важная. Именно её сбрасывают в единицу, чтобы начать
формировать текст заново:
# s(3)=1;
#pr первая строка\n\E
#pr вторая строка\n\E
Без сброса каждый новый #pr дописывает текст к предыдущему — иногда это
именно то, что нужно.
Как вывести весь накопленный текст
Типичная концовка программы:
# n9=s(3)-1;
#m [op=txt;] \T1 n9\E
Длину пришлось положить в переменную, потому что \T не понимает выражений.
И точки с запятой после аргументов нет: \T читает ровно два значения и на
этом останавливается — всё, что написано дальше, попадёт в вывод как текст.
Это настолько частая идиома, что её стоит запомнить целиком.
Дальше — текст и вывод.
Текст и вывод
Форматированный текст (в документации автора — FT) — это язык внутри языка.
Его понимают #pr, #m и текстовые параметры команд.
Правило одно: текст читается до \E. Всё остальное — детали.
Скелет
# s(3)=1;
#pr Результат: \G x;\n\E
#m [op=txt;] \Tp\E
#prпишет в массивt()начиная сs(3);\Tpв#mозначает «последний фрагмент, записанный#pr»;#m [op=txt;]показывает текст в терминале.
Пробелы съедаются
Перед каждым куском текста интерпретатор пропускает пробелы, табуляции и переводы строк. Это позволяет свободно форматировать исходник:
#pr Первая строка\n
Вторая строка\n
Третья строка\n\E
Отступы в исходнике на результат не влияют. Но и нужный пробел так не поставить —
для него есть \u32;:
#pr Итого:\u32;\G x;\n\E
Другой способ — перенести строку исходника кодом \-, который не даёт ничего:
#pr Очень длинная строка, которую хочется \-
разбить в исходнике\n\E
Escape-коды: символы
| Код | Даёт |
|---|---|
\n \r \t \b |
перевод строки, возврат каретки, табуляция, забой |
\\ \" \' |
сами символы |
\# \@ \[ \] |
сами символы |
\- |
ничего (перенос строки в исходнике) |
\u коды; |
символы по кодам: \u32;, \u65 66 67;, \u65*4; |
\D |
текущие дата и время |
\E |
конец текста |
Коды \# и \@ нужны потому, что # и @ иначе оборвали бы команду.
Escape-коды: числа
Здесь начинается специфика. Каждый код читает список значений до ;:
#pr \G a b c;\n\E
выведет подряд три числа.
| Код | Формат | Пример для 3.14159 |
|---|---|---|
\G |
ширина 11, 4 знака, порядок без E |
3.1416+00 |
\B ш зн |
то же с буквой E |
\B 12 4 → 3.1416E+00 |
\I ш |
целое, выравнивание пробелами | \I5 → 3 |
\I-ш |
целое, выравнивание нулями | \I-5 → 00003 |
\N ш зн |
с фиксированной точкой | \N 10 3 → 3.142 |
\S |
короткая запись числа | 3.14159 |
\O |
полная запись плюс два пробела | 3.14159 |
\G — рабочая лошадка для вещественных чисел, \I — для целых.
Обратите внимание на порядок: у \B и \N сначала идёт ширина поля и число
знаков, потом сам список значений.
#pr \B 14 6 x;\n\E
Вставка из массива
| Код | Что делает |
|---|---|
\T нач длина |
фрагмент массива t() |
\Tp |
последний фрагмент от #pr (по s(4), s(5)) |
\P n; |
значение текстового параметра n |
Аргументы \T — только числа или переменные, не выражения.
Комментарий внутри текста
Прямо в форматированном тексте можно оставить заметку — она не попадёт в результат:
#pr Итого:\u32;![ тут будет сумма ]!\G s;\n\E
Открывается ![, закрывается ]!. Распознаётся такой комментарий только в самом
начале текста или сразу после escape-кода — там, где интерпретатор пропускает
пробелы. В середине обычного текста ![ … ]! будет напечатан как есть; поэтому
в примере перед ним стоит \u32;.
Накопление текста
Поскольку #pr дописывает в t(), отчёт удобно собирать по частям:
# s(3)=1;
#pr Отчёт\n\E
#pr ------\n\E
# i=1;
#rep 5
#pr строка \I2 i;\n\E
# i=i+1;
#end
# n9=s(3)-1;
#m [op=txt;] \T1 n9\E
Каждый #pr внутри цикла дописывает строку, а в конце всё показывается разом.
Куда ещё уходит текст
Собранный в t() текст — универсальный источник:
#m [op=txt;]— на экран;#io [op=wt;]— в файл (см. Файлы);- в оригинальном интерпретаторе — в PDF, в картинку, в заголовок графика.
Именно поэтому вывод сделан двухступенчатым.
Дальше — ветвления и циклы.
Ветвления и циклы
В VKACL всего две управляющие конструкции — #rep и #case — и обе закрываются
одним и тем же #end. Из них собирается всё остальное.
Цикл с известным числом повторений
# s=0; i=1;
#rep 10
# s=s+i; i=i+1;
#end
#rep N повторяет тело N раз. N — число или переменная, но не выражение:
считать его нужно заранее:
# n=5; m=n*2; !
#rep m
...
#end
Циклы вкладываются, глубина — до 45 уровней:
# c=0;
#rep 3
#rep 4
# c=c+1;
#end
#end
После этого c равно 12.
Если N окажется нулём или отрицательным — это ошибка, а не пустой цикл.
Проверяйте счётчик заранее.
Ветвление
Условие в VKACL — это значение переменной &, а #case сравнивает его со
своей меткой:
# &=2;
#case 1 # z=10; #end |
#case 2 # z=20; #end |
#case 3 # z=40; #end |
Выполнится только вторая ветка: & равно 2. Остальные пропускаются целиком,
вместе со всем, что внутри.
Вертикальная черта после #end — не украшение. Она означает «сбросить условие»:
после #end | переменная & получает служебное значение 12345, которое не
совпадает ни с одной меткой. Без неё произойдёт кое-что интересное.
#case как цикл «пока»
Если после #end не написать |, то по достижении #end интерпретатор
снова сравнит & с меткой ветки, и при совпадении вернётся к её началу.
Это и есть цикл с условием:
# &=1; q=0;
#case 1
# q=q+1;
# &=-sgn(q-4);
#end
#pr q = \I3 q;\n\E
Пока q меньше 4, выражение -sgn(q-4) даёт 1, & остаётся равным метке, и
блок повторяется. Когда q достигнет 4, sgn(0) даст 0, & станет нулём, и
цикл закончится.
То же можно записать через #end (x) — эта форма задаёт новое значение условия
прямо в закрывающей команде. В скобках допускается только число или
переменная, не выражение, поэтому условие считают заранее:
# &=1; q=0; !
#case 1
# q=q+1; w=-sgn(q-4); !
#end (w)
Как строят условия
Раз сравнений нет, всё сводится к тому, чтобы получить в & нужное целое.
Проверка на равенство — вычесть и взять модуль знака:
Единица, если a равно b
# &=1-abs(sgn(a-b)); !
Проверка «больше» — знак разности:
Единица, если a больше b, иначе 0 или -1
# &=sgn(a-b);
#case 1 ... a больше ... #end |
#case 0 ... равны ... #end |
#case -1 ... a меньше ... #end |
Метка может быть отрицательной — это удобно и используется постоянно.
Флаг — просто 0 или 1:
# &=0;
#case 1 ... не выполнится ... #end |
Ранний выход из цикла
Прямого break нет, и у #rep число повторов задано заранее — изменить его
изнутри нельзя. Когда цикл должен закончиться по условию, его пишут через
#case, где условие продолжения вы вычисляете сами:
# k=0; &=1; !
#case 1
# k=k+1; &=sgn(50-k*k)>0; !
#end
#pr первое k, у которого k*k больше 50: \I3 k;\n\E
#m [op=txt;] \Tp\E
Пока k*k меньше 50, sgn(50-k*k) равен 1, и ветка повторяется. Как только
квадрат превысит 50, sgn даст −1, а >0 (максимум с нулём) превратит его в
0 — ветка больше не совпадает с &, и цикл заканчивается на k = 8.
Что важно помнить
#end |закрывает ветку,#endбез черты — превращает её в цикл;- пропущенная ветка пропускается целиком, включая вложенные блоки;
- уровней вложенности не больше 45;
- цикл нельзя оставить незакрытым к концу процедуры — это ошибка 34.
Дальше — процедуры.
Процедуры
Процедура в VKACL — именованный кусок кода. Без параметров, без возвращаемого значения, без локальных переменных. Всё общение — через общую память.
Определение и вызов
#pro summ
# s=a+b;
@
# a=2; b=3;
#e _summ
#pr сумма = \G s;\n\E
#pro имя открывает процедуру, @ закрывает. Вызов — #e _имя с
подчёркиванием перед именем.
Определения обычно собирают в начале файла, а основной код идёт после них.
Интерпретатор регистрирует процедуру, когда доходит до #pro, поэтому
определение должно встретиться раньше вызова.
Значимы первые четыре буквы имени
Это не опечатка: имя процедуры усекается до четырёх символов.
#pro calculate ... @
#pro calcform ... @
Обе процедуры получат имя calc — и вторая затрёт первую. Имена длиннее
четырёх букв читаются нормально, но различаться должны в первых четырёх:
#pro calc-total ... @
#pro calc-part ... @
Здесь тоже конфликт: calc и calc. Безопаснее давать имена ровно из четырёх
символов.
Подчёркивание в вызове
#e _summ !
Подчёркивание означает «вызвать безусловно». Без него вызов становится
условным: процедура выполнится, только если параметр c совпадает с &.
#e [c=3;] summ !
выполнит summ, только когда & равно 3. Приём экзотический; в авторском коде
почти везде стоит подчёркивание.
Данные передают через переменные
Раз параметров нет, договариваться приходится на уровне соглашения:
Возводит x в квадрат, результат кладёт в y
#pro sqre
# y=x*x;
@
# x=5;
#e _sqre
#pr \G y;\n\E
Это работает, но требует дисциплины: любая процедура может испортить любую переменную. Распространённая практика — закрепить за процедурами свои буквы или диапазоны массивов.
Рекурсии нет
Вызов процедуры из неё самой — ошибка 14. Вложенные вызовы разных процедур разрешены, глубина — до 45:
#pro inne
# c=c+1;
@
#pro oute
#e _inne
#e _inne
@
# c=0;
#e _oute !
После этого c равно 2.
Выполнение текста как программы
Есть особая форма вызова — #e _text. Она выполняет как программу тот текст,
который лежит в массиве t():
# s(3)=1;
#pr \#\u32;q=6*7;!\E
# b=s(4); l=s(5);
#e [b=b; le=l;] _text !
#pr q = \G q;\n\E
#m [op=txt;] \Tp\E
Здесь программа сначала формирует строку # q=6*7;!, а потом исполняет её.
Обратите внимание на три детали:
\#нужен, чтобы знак#не оборвал#pr;- пробел после него записан кодом
\u32;— обычный пробел в этом месте был бы съеден, и получилось бы#q=6*7;, то есть уже не команда вычислений; - в конце выполняемого текста стоит
!. Интерпретатор автора не останавливает вычисления на границе этого текста и без!читает дальше, в посторонние символы, с ошибкой 18. В программах автора для той же цели дописывается пустая команда#p [].
Приём выглядит экзотикой, но именно на нём построены калькуляторы автора:
формулу, введённую в окне ввода, программа превращает в команду #c и
исполняет. В песочнице есть пример «Мини-калькулятор».
Процедуры из файлов
Код можно держать в отдельном файле и выполнять его из программы:
#e [file=lib.acl;] _file !
Файл читается и выполняется так, как если бы его текст стоял на месте вызова.
Если #e — последняя команда в таком файле, после неё обязателен !.
Две тонкости, обе проверены на интерпретаторе автора:
- путь считается от папки интерпретатора: рабочая папка, выбранная
#f [op=fold;], на него не влияет; - процедуры, объявленные внутри файла, после его окончания забываются. Если файл переопределил процедуру с тем же именем, снова действует прежнее определение. Поэтому библиотеку процедур удобнее держать в самой программе.
Краткая старая форма — ##имя: она выполняет файл proc/имя.acl. Автор ею
больше не пользуется, потому что файл читается с диска при каждом вызове.
Суперкоманды
Вместо россыпи файлов в новой версии есть номерные суперкоманды: ##1,
##2, … Это готовые программы на VKACL из библиотеки автора — графики,
карты, окна, интерполяция, преобразование Фурье. Каждая хранится в одной строке
общего файла-библиотеки; при первом вызове читается и остаётся в памяти, в
конце массива t(), так что повторные вызовы в цикле ничего не стоят.
Входные данные суперкоманде передают через переменные и массивы, а тексты —
через #pr, разделяя части вертикальной чертой:
#pr Да|Нет|Продолжить вычисления?\E ##33
показывает сообщение с кнопками «Да» и «Нет»; номер нажатой кнопки попадает в
&. Все 54 суперкоманды описаны в разделе Суперкоманды.
У этого устройства есть два следствия для любой программы:
- библиотека живёт в конце массива
t(), поэтому своим данным можно отводить толькоt(1)…t(KY), гдеKY— переменная, которую интерпретатор задаёт при запуске; - двухбуквенные переменные, оканчивающиеся на
Y(AY…KYи другие), занял диспетчер суперкоманд — их трогать нельзя. Автор советует обходить стороной и двухбуквенные имена наXиZ.
Дальше — файлы.
Файлы
За работу с файлами отвечают две команды: #io читает и пишет файл целиком,
#f выполняет операции над файлами и папками.
Запись текста в файл
# s(3)=1;
#pr Привет из VKACL\n\E
#pr Вторая строка\n\E
# n9=s(3)-1;
#io [op=wt; fir=t(1); n=n9; file=out.txt;]
Разберём параметры:
| Параметр | Смысл |
|---|---|
op=wt |
операция: write text |
fir=t(1) |
откуда брать: начало области |
n=n9 |
сколько элементов |
file=out.txt |
имя файла |
fir — это не число, а ссылка на ячейку: t(1), i(5), r(100).
Для текстовых операций она обязана указывать на t().
Чтение текста из файла
#io [op=rt; fir=t(1); n=100000; file=in.txt;]
# m=s(5); !
#pr прочитано\I7 m;\u32;символов\n\E
n здесь — верхняя граница, сколько максимум прочитать. Где оказался
прочитанный текст, команда сообщает так же, как #pr: начало — в s(4),
длина — в s(5). Поэтому его сразу можно вывести через \Tp. Позицию записи
s(3) чтение не сдвигает.
Восемь операций #io
op |
Что делает |
|---|---|
rt / wt |
читать / писать текст (только с t()) |
rb / wb |
читать / писать байты |
rd / wd |
читать / писать вещественные числа |
rf / wf |
читать / писать файл как массив |
Двоичные формы работают с i() и r() и позволяют сохранять численные данные
без потери точности.
Операции с файлами: #f
#f [op=size; file=data.txt;]
# sz=s(1); !
op |
Что делает |
|---|---|
fold |
сменить рабочую папку |
size |
размер файла в s(1) |
copy |
скопировать |
dele |
удалить |
line |
прочитать или записать строку с номером n |
find repl |
поиск и замена в файле |
list |
список файлов папки |
Полный список — в справочнике команды #f.
Смена папки — почти обязательный первый шаг в авторских программах:
#f [op=fold; file=pro;]
После этого все относительные имена отсчитываются от папки pro.
Имя файла из переменных
Имя файла — текстовый параметр, а значит, его можно собрать escape-кодами:
# n=7;
#f [op=size; file=\-данные-\I-3 n;.txt\E]
Если значение параметра начинается с \, оно читается как форматированный
текст. Код \- в начале ничего не выводит и нужен только для того, чтобы
значение начиналось с обратной косой черты. Получится данные-007.txt.
Похожий приём — специальное имя arg, при котором имя файла берётся из
следующего форматированного текста:
#io [op=rt; fir=t(1); n=10000; file=arg;] отчёт-\I-2 k;.txt\E
Что поддерживает реализация из этого проекта
Порт на Rust умеет все восемь операций #io, почти все операции #f и #te,
кроме связанных с картинками, окнами и сетью, — о таких он сообщает, называя
операцию. В песочнице без подключённой папки файлы живут в памяти: записанное
показывается под выводом. С подключённой папкой (кнопка «Подключить папку»)
программа работает с настоящими файлами.
Дальше — ловушки языка.
Ловушки языка
Собранные в одном месте вещи, на которых спотыкаются все. Каждая проверена на оригинальном интерпретаторе.
Символ # в поясняющем тексте
Заполняем массив командой #d — так делать нельзя.
#d 3 i(1) 1 2 3 !
Интерпретатор найдёт #d в «комментарии» и попытается его выполнить: прочитает
слово — как число элементов, получит ноль и остановится с ошибкой 33.
Правило: в тексте между командами не должно быть #. Если очень нужно —
пишите «команда d» словами.
Текст сразу после #c, #d, #v, #e
# a=1;
Дальше идёт пояснение.
#pr ...\E
Команда вычислений читает присваивания, пока не встретит #, @ или !.
Слово Дальше она примет за имя переменной и остановится с ошибкой. То же с
#d, #v и #e: у всех них число аргументов не фиксировано.
Правило: после таких команд, если дальше идёт текст, ставьте !:
# a=1; !
Дальше идёт пояснение.
Пробел после \#
Когда программа собирает команду в текстовом массиве, чтобы потом выполнить её
(#e _text), легко написать так:
#pr \# a=1;\E
Получится #a=1;: пробел перед a съеден по общему правилу форматированного
текста, и это уже не команда вычислений. Нужен явный пробел: \#\u32;a=1;\E.
Чужие переменные
Двухбуквенные переменные с Y на конце (AY…KY и другие) заняты диспетчером
суперкоманд, а за t(KY) лежит его код. Программа, которая их трогает,
работает до первой суперкоманды, а потом ломается непредсказуемо.
Правило: двухбуквенные имена на X, Y, Z не использовать; в t() не
заходить дальше KY.
< и > — это не сравнения
# &=a<b; !
Это не «a меньше b», а минимум из двух. И связывает он сильнее умножения:
# n=2*3<4; ! это 2*min(3,4) = 6
# m=1<5+10; ! это min(1,5)+10 = 11
Правило: для условий используйте sgn, а если нужен минимум в середине
формулы — ставьте скобки.
Степень слева направо
# e=2^3^2; !
Даёт 64, то есть (2^3)^2. В математике принято наоборот.
Унарный минус только в начале
# a=2*-3; ! ошибка 11
# a=2*(0-3); ! правильно
# b=-5; ! правильно, минус в начале
Аргумент #rep — не выражение
#rep 2+1 … #end выполнится 20 раз, а не 3
#rep n+1 … #end выполнится n раз, «+1» молча пропадёт
Счётчик #rep, метка #case, значения #d, числа в \G и \I читаются
особым образом: это одно число или одна переменная, а не выражение. Причём
в числе буква порядка E необязательна — 2+1 читается как 2·10¹. Так сделано,
чтобы можно было прочитать собственный формат вывода 2.0000+01.
Правило: всё, что нужно посчитать, считайте заранее в переменную:
# m=n+1; !
#rep m … #end
Параметры не сбрасываются
#f [op=size; file=a.txt; n=5;]
#f [op=size; file=b.txt;]
Во второй команде n всё ещё равно 5. Параметры глобальны и живут до
переопределения. Это чаще всего проявляется в параметрах mo, n и b,
которые используют почти все команды.
Правило: задавайте в команде все параметры, от которых зависит результат, даже если кажется, что они уже нужные.
Значимы первые буквы имён — и ищутся подстрокой
Команды сопоставляются по первым трём буквам, процедуры — по первым четырём. Причём имя команды ищется в общей таблице как подстрока, и находится первое совпадение:
| Пишут | Думают | Получают |
|---|---|---|
#p |
#pr |
#p — только установка параметров |
#in |
#inp |
#w — «IN» есть внутри «WIN» |
#ro |
#rob |
#pro |
#ex |
#exit |
#e |
С параметрами то же: xs — это xsh (сдвиг), а не позиция xpo; wi — это
twi, he — the (см. Поле параметров).
#pro calculate ... @
#pro calcform ... @ имя то же самое: calc
Правило: пишите имена команд и параметров полностью или хотя бы первыми тремя буквами.
Хвостовые пробелы исчезают
#pr Итого: \G x;\E
Пробел перед \G съеден: перед каждым фрагментом текста пропускаются пробелы.
Нужен пробел — пишите \u32;.
Индексы массивов считаются упрощённо
# a=i(k+1); ! работает
# b=i(int(k/2)); ! ошибка
В индексах доступны только числа, скалярные переменные и + - * / ^.
То же ограничение — у аргументов \T.
Кодировка исходников
Интерпретатор автора читает файлы как windows-1251. Файл, сохранённый в UTF-8, даст кракозябры в русском тексте. Реализация из этого проекта определяет кодировку сама и понимает оба варианта, но программы для интерпретатора автора стоит сохранять в windows-1251.
Ошибка молча прекращает программу
По умолчанию (err=0) любая ошибка показывает окно и завершает выполнение.
Чтобы обработать ошибку самому, нужны две вещи: параметр err не равен нулю и
точка возврата, отмеченная командой #%. После ошибки исполнение продолжается
с этой точки, а & получает значение 10101.
# ok=1; !
#p [err=1;]
#%
#case 10101 # ok=0; #end |
# &=ok; !
#case 1 #io [op=rt; fir=t(1); n=10000; file=может-не-быть.txt;] #end |
# &=ok; !
#case 0 #pr файл прочитать не удалось\n\E #end |
#p [err=0;]
Разберём, как это работает. #% запоминает место, куда вернуться после
ошибки. При первом проходе & не равно 10101, и ветка #case 10101
пропускается. Если чтение файла сорвалось, исполнение возвращается сразу за
#%, а & становится 10101 — теперь ветка выполняется и сбрасывает флаг ok.
Флаг нужен, чтобы опасная команда не выполнилась повторно: иначе программа
снова наткнётся на ту же ошибку и снова вернётся к #%.
Это единственный в языке механизм обработки ошибок.
Массивы целиком: #ma
Интерпретируемый язык медленен в циклах. Тройной цикл по тысяче повторов для
VKACL — непосильная задача, как и для любого интерпретатора. Matlab и numpy
решают это одинаково: операция применяется к массиву целиком, одной
командой, а цикл выполняется внутри, на скорости Java или C. В VKACL это
команда #ma, и она была в языке с самого начала, ещё во времена Фортрана.
Автор формулирует жёстко: без #ma язык не годится ни для научных расчётов,
ни для обработки картинок. Поэтому эта глава обязательна для всех, кто будет
считать.
Массив — это начало и длина
Вспомним, как устроена память: r() — одна большая область. «Массив» в
программе — это просто номер первого элемента и число элементов. Поэтому у
команд #ma почти всегда есть параметры:
| Параметр | Смысл |
|---|---|
b |
номер первого элемента в r() |
le |
число элементов (для векторов) |
nx, ny |
размеры матрицы: nx элементов в строке, ny строк |
trx |
сдвиг до второго массива: он начинается с r(b+trx) |
Матрица хранится по строкам: элемент строки y, столбца x лежит в
r(b + y·nx + x) (счёт с нуля). Ничто не мешает считать те же 12 чисел то
матрицей 3×4, то 4×3, то вектором длины 12 — это просто разные значения
nx, ny и le.
Константы, нужные операциям, берутся из переменных — чаще всего C и D.
А результат, если он одно число, иногда тоже кладётся в переменную.
Сумма квадратов без цикла
# s(3)=1; C=1; D=1; !
#ma [op=via; b=1; le=100;]
#ma [op=vvm; b=1; le=100; trx=0;]
#ma [op=mss; b=1; nx=100; ny=1; em=0;]
#pr sum=\B 16 8 r(101);\n\E
sum= 3.38350000E+05
Три строки — три операции над массивом из ста чисел:
viaзаполняетr(b+i) = C + D·i— получаем 1, 2, …, 100;vvmумножает каждый элемент на элемент, отстоящий наtrx; приtrx=0это возведение в квадрат;mssсуммирует; для вектора (ny=1) сумма кладётся сразу за ним, вr(b+nx).
Матрицы
# s(3)=1; !
#d 6 r(1) 1 2 3 4 5 6 !
#ma [op=mtr; b=1; nx=3; ny=2;]
#pr \G r(1) r(2) r(3) r(4) r(5) r(6);\n\E
1.0000+00 4.0000+00 2.0000+00 5.0000+00 3.0000+00 6.0000+00
Матрица 2×3 (две строки: 1 2 3 и 4 5 6) после mtr стала матрицей 3×2 —
теперь её строки 1 4, 2 5, 3 6. Транспонирование делается на месте.
mss для матрицы кладёт после неё сначала суммы по столбцам, потом по
строкам, потом общую сумму. Для той же исходной матрицы получится
5 7 9 | 6 15 | 21.
Скалярное произведение и ограничение диапазона
# s(3)=1; !
#d 4 r(1) 1 2 3 4 !
#d 4 r(5) 2 2 2 2 !
#ma [op=vvs; b=1; le=4; trx=4;]
#pr dot=\G C;\n\E
#d 5 r(1) 0.5 2.7 -1.3 4.2 3.1 !
# V0=0; V1=3; !
#ma [op=var; b=1; le=5;]
#pr \G r(1) r(2) r(3) r(4) r(5);\n\E
dot= 2.0000+01
5.0000-01 2.7000+00 0. 3.0000+00 3.0000+00
vvs записывает результат в переменную C — будьте внимательны, если C
использовалась для другого. var зажимает значения в диапазон от V0 до
V1.
Сортировка
# s(3)=1; !
#d 5 r(1) 3.5 1.25 4.75 2.5 0.5 !
#ma [op=vor; b=1; le=5; mo=1;]
#pr \G r(1) r(2) r(3) r(4) r(5);\n\E
#pr \I3 i(1) i(2) i(3) i(4) i(5);\n\E
5.0000-01 1.2500+00 2.5000+00 3.5000+00 4.7500+00
5 2 4 1 3
mo=1 — по возрастанию, mo=2 — по убыванию. Заодно в i(1)…i(le)
записываются прежние номера элементов: видно, что наименьший был пятым.
Какие операции есть
Полное описание — в справочнике #ma. По группам:
| Группа | Операции |
|---|---|
| заполнить | vic константой, via прогрессией, vig гауссианой |
| поэлементно с константой | vac прибавить C, vmc умножить на C, vpo степень C |
| функция от каждого элемента | vex exp, vlo ln, vsi sin, vco cos, vin целая часть, vba поправка байтов |
| два массива | vva сложить, vvm перемножить, vvs скалярное произведение |
| ограничить, отсортировать | var, vor |
| матрицы | mtr транспонировать, mii отразить, mss суммы, fno нормировать строки, mip, mds, mmr поворот |
| комплексные массивы | mcc, dcc, ccm, ccd умножение и деление, cne, cen модуль и фаза |
| спектр и свёртка | fft, mcg свёртка с гауссианой |
| интерполяция | mmi, ffi, fis кубический сплайн |
| производные и интегралы | fdf, sdf, fsd, ffd |
| прочее | gis гистограмма, cwm пик и его ширина, bsm bsi bsr система шаров |
Как думать в стиле #ma
Вместо «для каждого i сделать…» — «какой операцией над целым массивом это
выражается». Цикл остаётся там, где он действительно нужен: по строкам
файла, по кадрам анимации, по вариантам расчёта. А внутри каждого шага — одна
или несколько команд #ma.
Тем, кто пришёл из Matlab или numpy, это знакомо; тем, кто пришёл из C или Паскаля, придётся привыкнуть. Автор научился такому стилю ещё на Фортране и считает его самым естественным для научных расчётов.
Графика
Ради графики язык и появился в 1991 году: автору нужно было быстро строить научные графики, не переписывая каждый раз программу на Фортране. Графика есть только в интерпретаторе автора — в песочнице этой книги её нет. Оба рисунка ниже получены запуском приведённых программ в настоящем интерпретаторе.
Команд рисования три, и у каждой своя роль:
| Команда | Для чего |
|---|---|
#w |
научные графики «в одну команду»: кривые с осями, карты матриц, квази-трёхмерные графики; показ и преобразование картинок |
#g |
рисование по элементам: текст, линии, области, прямоугольники, овалы, оси, картинки |
#eg |
то же с вещественными координатами и преобразованиями — для сложных рисунков |
А для самых частых случаев есть готовые суперкоманды: ##1 — график
функций, ##2 — цветная карта матрицы, ##3 — аксонометрия. Им достаточно
передать данные, оси и подписи они размечают сами (см.
Суперкоманды).
График функций одной командой
Две кривые, синус и косинус на отрезке от 0 до 2 пи.
# s(3)=1; n=201; C=0; D=2*3.14159265/(n-1); !
#ma [op=via; b=1; le=n;]
#ma [op=vsi; b=1; le=n;]
#ma [op=via; b=202; le=n;]
#ma [op=vco; b=202; le=n;]
#w [op=pf; file=here; b=1; le=0; mo=0; nx=n; ny=2; n=0; uni=0; col=247; msi=0;
twi=640; the=400; wid=520; hei=300; xsh=80; ysh=50; bot=5; top=10;
tsi=14; tfo=1; tki=1; sty=0; c=0; sav=1;] 0 6.2832
#f [op=topng; n=1; form=sinus;]
Что здесь происходит:
#ma [op=via;]заполняет массив арифметической прогрессиейC + D·i, а#ma [op=vsi;]берёт синус от каждого элемента — две команды вместо цикла. Так же готовится косинус, начиная сr(202).#w [op=pf;](plain figure) рисует график.file=hereговорит, что числа лежат в массивеr()начиная сb=1, а не в файле.nx— точек в кривой,ny— число кривых, приmo=0все столбцы — значения функций, а аргумент меняется равномерно от первого до второго числа после скобок (0 6.2832).uni=0— разметку осей выбрать автоматически.- Размеры:
twi×the— вся картинка,wid×hei— прямоугольник осей,xsh,ysh— его сдвиг от левого нижнего угла,botиtop— длины рисок,tsi— размер шрифта чисел на осях (его обязательно задать: при нуле числа не видны). col=247— цвет первой кривой; следующая берёт следующий цвет палитры.sav=1— не показывать картинку, а сохранить её в память под номером 1.#f [op=topng; n=1; form=sinus;]записывает её в файлsinus.png.
Куда девается картинка
Параметр sav у всех рисующих команд работает одинаково:
sav |
Результат |
|---|---|
| больше 0 | картинка сохраняется в памяти под этим номером (до 100) и не показывается |
| 0 | показывается в отдельном окне; при c=1 программа ждёт, пока окно закроют |
| −1 | показывается и одновременно записывается в файл form.jpg |
| −2 | только записывается в файл form.jpg, без окна |
Из памяти картинку можно записать в PNG (#f [op=topng;]), дорисовать
командой #g [op=cont;], показать, собрать из нескольких одну.
Рисунок по элементам
Белый холст, синяя рамка, красный круг и подпись.
Координаты отсчитываются от левого нижнего угла, прямоугольники
и овалы ставятся по центру. Номера цветов считаются с единицы.
# s(3)=1;
#g [op=open; twi=400; the=300; col=246;]
#g [op=rect; nx=200; ny=150; wid=360; hei=260; col=249; mo=1;]
#g [op=oval; nx=200; ny=130; wid=140; hei=140; col=248; mo=0;]
#g [op=text; nx=200; ny=240; col=247; tfo=1; tki=1; tsi=24; sty=2;] VKACL\E
#g [op=close; c=0; sav=2;] \E
#f [op=topng; n=2; form=drawing;]
Порядок всегда один: op=open задаёт размер холста и цвет фона, дальше
рисуются элементы, op=close закрывает рисунок и распоряжается им по sav.
Несколько деталей, которые проще увидеть на картинке, чем вычитать:
- ось y направлена вверх:
ny=240— ближе к верхнему краю; - у
rectиovalкоординатыnx,ny— это центр фигуры; mo=0— фигура закрашена,mo=1— только контур;sty=2у текста — выравнивание по центру (1 — по левому краю, 3 — по правому);- в палитре по умолчанию 246 — белый, 247 — чёрный, 248 — красный, 249 —
синий. Свою палитру задаёт команда
#col.
Сдвиг и масштаб всего рисунка
Параметры trx, try сдвигают, а sca масштабирует всё, что рисуется после
них, — не трогая координат в самих командах. Так один и тот же код рисует
фрагмент в разных местах и разного размера. При sca, заданном со знаком
минус, меняются только размеры фигур, а их расположение остаётся прежним.
Что дальше
- Полный список операций — в справочнике:
#w,#g,#eg. - Готовые графики и карты — суперкоманды
##1,##2,##3и готовые программы №20–24, 49, 50 (см. Готовые программы).
Модель исполнения
Буфер и указатель
Интерпретатор держит весь текст программы в одном символьном буфере (на программу отводится до миллиона символов) и один указатель — текущую позицию разбора. Управляющие конструкции работают именно с ним: цикл — это возврат указателя назад, переход — присваивание указателю нового значения.
За концом программы в том же буфере расположена рабочая область, куда собирается форматированный текст.
Главный цикл
- Найти вперёд ближайший
#; всё до него — комментарий. - Поставить указатель сразу за
#. - Разобрать и выполнить команду.
- Повторять.
Цикл заканчивается, когда указатель выходит за границу текущей области
исполнения и стек вызовов пуст, либо когда встретилась команда #stop / #exit.
Что может стоять после #
| Запись | Смысл |
|---|---|
# (пробел) |
команда вычислений, синоним #c |
##N (число) |
номерная суперкоманда из библиотеки автора, см. Суперкоманды |
##имя |
старая форма: выполнить файл proc/имя.acl (каждый раз читается с диска) |
#имя |
обычная команда |
Сопоставление имени команды
Имя читается до пробела или перевода строки, приводится к верхнему регистру, берутся первые не более трёх символов, и результат ищется как подстрока в таблице из 4-символьных слотов:
PAR DAT CAL EXE IOP PRI PAS REP END CAS % STO PRO MES FIL WIN
COL INP EXI REA SEL MAT TEX SYS ZIP GRA GOT ROB EGR PAT AGR INI
SOU PSG BIM PDO FRA PFO CHO VRA
Номер команды — позиция / 4 + 1.
Следствия:
#pr,#print,#printer— одна и та же команда;- поиск идёт подстрокой, поэтому короткое имя может «попасть» в более ранний
слот:
#pнаходитPAR, а неPRI;#in—WIN(это#w!), а неINP;#ro—PRO, а неROB;#ex—EXE(#e), а неEXI; - неизвестное имя — ошибка 1.
Завершение аргументов
У команд с аргументами переменной длины — #c (и # ), #d, #v, #e и
некоторых других — аргументы кончаются на одном из трёх знаков:
| Знак | Смысл |
|---|---|
# |
начало следующей команды |
@ |
конец процедуры |
! |
конец аргументов; дальше обычный текст |
! обязателен, если за такой командой идёт поясняющий текст, и если #e —
последняя команда в файле, который выполняется из другой программы. У команд
с аргументами фиксированной формы (#pr … \E, #rep N) он не нужен.
Сам конец программы ничем не отмечается: исполнение заканчивается, когда
текст кончился, или по командам #stop и #exit.
Области исполнения
Текущая граница исполнения хранится в s(110). Вызов процедуры сохраняет
позицию возврата и старую границу, устанавливает новые и продолжает разбор.
Когда указатель доходит до границы, происходит возврат.
Глубина вложенности вызовов — до 45, так же и для циклов и ветвей (в версиях до 2025 года было 25). Рекурсия запрещена: повторный вход в процедуру с тем же именем даёт ошибку 14, и сообщение показывает всю цепочку вызовов.
Кодировка
Исходники читаются побайтово как windows-1251:
| Диапазон байта | Преобразование |
|---|---|
0x00…0x7F |
без изменений (ASCII) |
0x80…0xBF |
символ с тем же кодом (Latin-1); Ё и ё так не читаются |
0xC0…0xFF |
кириллица А…я (U+0410…U+044F) |
Одиночный CR без LF превращается в LF.
Обработка ошибок
Поведение задаёт параметр err (ячейка s(26)):
err |
Что происходит при ошибке |
|---|---|
0 (по умолчанию) |
окно с сообщением, выполнение прекращается |
не 0 |
без окна; если командой #% отмечена точка возврата, исполнение продолжается с неё, а & получает значение 10101 |
Ветка #case 10101 сразу за #% — стандартный способ поймать ошибку; полный
образец — в разделе Коды ошибок.
Память и переменные
Вся память статическая и глобальная. Ничего не объявляется, всё существует с начала программы и обнулено.
Классы хранилищ
| Запись | Что хранит | Максимальный индекс |
|---|---|---|
a…z, A…Z, $, %, & |
вещественное | 55 ячеек |
буква+цифра: a0…Z9 |
вещественное | 550 |
буква+буква: aa…ZZ |
вещественное | 3 025 |
i(n) |
целое | 249 999 |
r(n) |
вещественное | 25 999 999 |
t(n) |
символ | 1 999 999 |
s(n) |
целое, служебное | 112 |
Индексация везде с единицы. Обращение к нулевому или слишком большому индексу — ошибка 7.
Алфавит имён
Порядок символов, задающий нумерацию скалярных ячеек:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$%&
Регистр значим: a и A — разные переменные.
Двухсимвольные имена индексируются по формулам: буква+цифра даёт
позиция + 55 × цифра, буква+буква — позиция₁ + 55 × (позиция₂ − 1).
Практического значения это не имеет, но объясняет, почему пространств имён
именно столько.
Преобразование типов
Скалярные переменные и r() хранят вещественные числа. При записи в i() и
s() значение округляется. При записи в t() число трактуется как код символа;
отрицательные значения интерпретируются как кириллица cp1251.
Чтение из t() даёт код символа.
Индексы
Внутри скобок работает урезанный вычислитель: только числа, скалярные
переменные и операции + - * / ^. Ни функций, ни вложенных обращений к
массивам, ни скобок.
# a=i(k); ! да
# b=i(k*2+1); ! да
# c=i(int(k)); ! нет — ошибка
Перед именем допустим унарный минус: -r(5) читается как значение со знаком.
Служебный массив s()
s() совмещает две роли: через него передаются числовые параметры команд
(см. Поле параметров) и через него же команды возвращают
результаты.
Ячейки, имеющие постоянное значение:
| Ячейка | Смысл |
|---|---|
s(1) |
результат: размер файла, число прочитанных элементов |
s(3) |
текущая позиция записи в t() |
s(4) |
начало последнего фрагмента, записанного #pr |
s(5) |
длина последнего фрагмента |
s(6) |
максимальная занятая позиция в t() |
s(26) |
режим обработки ошибок (err) |
s(45) |
операционная система: 1 — Windows, 2 — Linux (задаёт start.acl) |
s(106), s(107) |
ширина и высота экрана |
s(108) |
аргумент командной строки (режим запуска) |
s(109) |
верхняя граница массива r() |
s(110) |
граница текущей области исполнения |
Начальные значения после запуска: s(3)=1, s(6)=1, s(29)=1, s(36)=100.
Переменная &
Формально это обычная скалярная ячейка, но по ней работает #case: команда
сравнивает свою метку именно с &. Значение 12345 считается «условие сброшено»
и не совпадает ни с одной меткой; значение 10101 означает «произошла ошибка».
Занятые переменные и граница t()
При запуске интерпретатор выполняет свой начальный код (start.acl), который
кладёт в конец массива t() диспетчер номерных суперкоманд и кэш уже
прочитанных суперкоманд. Отсюда правила для любой программы:
| Правило | Почему |
|---|---|
пользоваться только t(1)…t(KY) |
выше KY лежат диспетчер и кэш суперкоманд |
не трогать двухбуквенные переменные на Y: AY…KY и другие |
их использует диспетчер |
по возможности не брать двухбуквенные имена на X и Z |
часть из них тоже задана заранее (ZZ — размер r(), AZ, BZ… — входы суперкоманд) |
Готовые программы автора дополнительно не пользуются последними 10 000
элементами до KY и переменными с буквой U: там хранится код самой
выполняемой программы.
Копирование между ячейками: #v
#v — обратная команда к #d: переписывает подряд идущие элементы массива в
перечисленные переменные.
#d 3 r(11) 1.5 2.5 3.5 !
#v 3 r(11) a b c !
После этого a = 1.5, b = 2.5, c = 3.5. Как и у #d, групп
«количество, начало, приёмники» может быть несколько; конец — #, @ или !.
#init
Команда #init (значимы первые буквы #ini) останавливает звук, запущенный
командой #so. Память она не сбрасывает.
Выражения и функции
В языке два вычислителя. Полный работает в #c и в числовых параметрах;
урезанный — только в индексах массивов.
Полный вычислитель
Выражение обязано заканчиваться точкой с запятой. Скобки работают обычным образом, вложенность не ограничена.
Операции и приоритеты
Сверху — то, что связывает сильнее:
| Уровень | Операции | Смысл |
|---|---|---|
| 1 | < > |
минимум, максимум |
| 2 | ^ |
возведение в степень |
| 3 | * / |
умножение, деление |
| 4 | + - |
сложение, вычитание |
Всё левоассоциативно, включая ^: выражение 2^3^2 равно (2^3)^2 = 64.
То, что минимум и максимум связывают сильнее арифметики, — самая контринтуитивная черта языка:
| Запись | Значение |
|---|---|
1<5+10 |
min(1,5)+10 = 11 |
2*3<4 |
2*min(3,4) = 6 |
0>x<100 |
зажать x в диапазон 0…100 |
Унарный минус
Допустим в начале выражения и сразу после открывающей скобки или имени функции. После бинарной операции — синтаксическая ошибка:
# a=-5; ! да
# b=sqr(-x+9); ! да
# c=2*-3; ! ошибка 11
# d=2*(0-3); ! обходной путь
Деление на ноль
Ошибка 24, а не бесконечность.
Урезанный вычислитель
Работает внутри i( ), r( ), s( ), t( ). Отличия:
- операнды — только целые литералы и скалярные переменные;
- операции
^ / * - +, причём^вычисляется сразу, затем*и/, затем+и-; - скобок и функций нет;
- разбор заканчивается на первом символе, не входящем в набор операций.
Функции
Имя ровно из трёх букв, сразу за ним (. Регистр не важен.
| Имя | Смысл | Ограничения |
|---|---|---|
sqr |
квадратный корень | аргумент ≥ 0, иначе ошибка 10 |
log |
натуральный логарифм | аргумент > 0 |
exp |
экспонента | аргумент < 500; при < −500 результат 0 |
sin |
синус | радианы |
cos |
косинус | радианы |
tan |
тангенс | радианы |
ars |
арксинус | |аргумент| ≤ 1 |
arc |
арккосинус | |аргумент| ≤ 1 |
art |
арктангенс | |
abs |
модуль | |
int |
целая часть | отбрасывание к нулю |
sgn |
знак: −1, 0, 1 | |
rnd |
случайное из [0,1) | аргумент игнорируется |
sfi |
интеграл Френеля S | |
cfi |
интеграл Френеля C | |
bj0 |
функция Бесселя J₀ | |
bj1 |
функция Бесселя J₁ |
Числовые литералы
42 целое
3.14 точка как разделитель
3,14 запятая тоже
1.5e3 экспонента
2.5E-4 знак у экспоненты
Команда #c
#c имя=выражение; имя=выражение; ...
# имя=выражение; ...
Команда читает пары «приёмник = выражение», пока не встретит #, ! или @.
Приёмником может быть скалярная переменная или элемент любого массива:
# a=1; i(5)=a*2; r(100)=sqr(2); t(1)=65; s(3)=1; !
Обратите внимание: если за командой вычислений идёт поясняющий текст или конец
программы, её нужно закрыть знаком ! — иначе текст будет разобран как
продолжение списка присваиваний.
Поле параметров
Сразу за именем команды может стоять поле в квадратных скобках:
#f [op=fold; file=pro;]
#sel [nx=6; ny=9; mo=0; wid=60; hei=30;]
Внутри — пары имя=значение;. Имя сопоставляется по первым трём буквам, как и
имена команд.
Параметры глобальны
Значения сохраняются до явного переопределения и видны всем последующим командам. Это главный источник трудноуловимых ошибок: команда может сработать не так из-за параметра, заданного двадцатью строками выше.
#f [op=size; file=a.txt; n=5;]
#f [op=size; file=b.txt;] здесь n всё ещё 5
Короткие имена и ловушки
Имя параметра, как и имя команды, ищется подстрокой по первым трём буквам в общей таблице имён — и находится первое совпадение. Поэтому короткое имя может означать совсем не то, что кажется:
| Пишут | Кажется | На самом деле |
|---|---|---|
xs, ys |
xpo, ypo (позиция) |
xsh, ysh — s(16), s(17) (сдвиг) |
wi |
wid |
twi — s(12) |
he |
hei |
the — s(13) |
si |
siz |
tsi — s(24) |
co |
col |
c (cod) — s(8) |
or |
ord |
form |
mi |
msi / mki |
такого нет — ошибка 2 |
Для позиции окна пишут xp и yp. Надёжнее всего писать имена полностью или
первыми тремя буквами.
Текстовые параметры
Четыре штуки, у каждого своя предельная длина:
| Имя | Длина | Назначение |
|---|---|---|
fir |
8 | ссылка на ячейку: t(1), i(5), r(100) |
op |
4 | код операции |
file |
42 | имя файла или папки |
form |
42 | формат, вспомогательная строка |
Значение читается до пробела или ;. Если раньше встретится ] — ошибка 27.
Значение, начинающееся с \, разбирается как форматированный
текст — так собирают имена файлов из переменных:
#f [op=size; file=\-отчёт-\I-3 n;.txt\E]
Числовые параметры
Все остальные вычисляются полным вычислителем и округляются в ячейку s() с
соответствующим номером.
| Имя | s() |
Обычное назначение |
|---|---|---|
n |
7 | количество |
c |
8 | код, условие вызова |
b |
9 | начало |
le |
10 | длина |
mo |
11 | режим |
twi |
12 | ширина изображения |
the |
13 | высота изображения |
wid |
14 | ширина |
hei |
15 | высота |
xsh (или xs) |
16 | сдвиг по X |
ysh (или ys) |
17 | сдвиг по Y |
sty |
18 | стиль |
bot |
19 | нижняя граница |
top |
20 | верхняя граница |
nx |
21 | число элементов по X |
ny |
22 | число элементов по Y |
sav |
23 | сохранение |
tsi |
24 | размер шрифта текста на рисунке |
uni |
25 | код символа |
err |
26 | режим обработки ошибок |
fk |
27 | вид шрифта текстовых окон (1…5) |
fs |
28 | размер шрифта текстовых окон |
col |
29 | цвет |
tfo |
30 | шрифт текста |
tki |
31 | вид текста |
msi |
32 | размер маркера |
mki |
33 | вид маркера |
trx |
34 | сдвиг по X (в #g — смещение рисунка, в #ma — расстояние до второго массива) |
try |
35 | сдвиг по Y |
sca |
36 | масштаб |
rat |
37 | отношение |
siz |
38 | размер |
ord |
39 | порядок |
dir |
40 | направление |
em |
41 | пустое поле |
xp |
42 | позиция по X (полное имя xpo) |
yp |
43 | позиция по Y (полное имя ypo) |
pal |
44 | палитра |
Поскольку параметр — это просто ячейка s(), его можно задать и напрямую:
#p [n=5;]
# s(7)=5; !
Обе записи эквивалентны. Первая читается лучше.
Команда #p
Команда #p не делает ничего, кроме установки параметров. Её используют, чтобы
задать значения заранее:
#p [err=1; mo=0;]
Форматированный текст
Форматированный текст (FT) — аргумент команд #pr, #m, #read и
текстовых параметров. Читается до \E.
Правило пробелов
Перед каждым фрагментом пропускаются пробелы, табуляции и переводы строк.
Поэтому отступы в исходнике безопасны, но и нужный пробел приходится
записывать явно: \u32;.
Символы
| Код | Результат |
|---|---|
\E |
конец текста (обязателен) |
\- |
ничего — перенос строки в исходнике |
\n |
перевод строки |
\r |
возврат каретки |
\t |
табуляция |
\b |
забой |
\\ |
обратная косая черта |
\" \' |
кавычки |
\# \@ \[ \] |
сами символы |
\D |
текущие дата и время |
Числа
Каждый код читает список выражений и заканчивается точкой с запятой.
| Код | Синтаксис | Формат | Пример для 3.14159 |
|---|---|---|---|
\G |
\G знач; |
ширина 11, 4 знака, порядок без E |
3.1416+00 |
\B |
\B ш зн знач; |
то же с буквой E |
3.1416E+00 |
\I |
\Iш знач; |
целое, дополнение пробелами | 3 |
\I |
\I-ш знач; |
целое, дополнение нулями | 00003 |
\N |
\N ш зн знач; |
фиксированная точка | 3.142 |
\S |
\S знач; |
короткая запись | 3.14159 |
\O |
\O знач; |
полная запись плюс два пробела | 3.14159 |
Ширина у \I пишется слитно с кодом, у \B и \N — через пробел.
Если числу не хватает заданной ширины, \G и \B печатают одиночную звёздочку.
Ноль печатается как 0. с выравниванием по правому краю.
Данные
| Код | Синтаксис | Что делает |
|---|---|---|
\T |
\T нач длина |
фрагмент массива t() |
\Tp |
\Tp |
последний фрагмент от #pr (по s(4), s(5)) |
\P |
\P n; |
текстовый параметр n (1 — fir, 4 — op, 5 — file, 6 — form) |
\u |
\u коды; |
символы по числовым кодам |
\U |
\U выражения; |
то же, но коды вычисляются |
Аргументы \T — только числа или скалярные переменные, выражения не работают.
Точка с запятой в конце не нужна: \T читает ровно два значения. Если её
поставить, она попадёт в вывод как обычный символ — этим пользуются, когда
собирают в t() текст команды для последующего #e _text.
В \u и \U действует повтор через звёздочку:
#pr \u45*40;\n\E сорок минусов
#pr \u32 65 32;\E пробел, A, пробел
Комментарий внутри текста
#pr Итого:\u32;![ здесь будет сумма ]!\G s;\n\E
Открывается ![, закрывается ]!, в результат не попадает. Распознаётся только
в начале текста или сразу после escape-кода; внутри обычного текста печатается
как есть.
Пути и служебные значения
| Код | Даёт |
|---|---|
\F |
имя файла интерпретатора |
\H |
рабочая папка |
\M |
текущая папка процесса |
\L |
имя последней запущенной внешней программы |
В реализации из этого проекта эти коды разворачиваются в пустую строку.
Команда #pr
#pr дописывает построенный текст в массив t() начиная с позиции s(3),
после чего:
s(4)— начало записанного фрагмента,s(5)— его длина,s(3)— сдвинута за конец,s(6)— максимальная занятая позиция.
Сама по себе команда ничего не показывает: для вывода нужен #m [op=txt;].
Коды ошибок
Номера совпадают с оригинальным интерпретатором, поэтому сообщения обеих реализаций сопоставимы напрямую.
| № | Причина | Частая настоящая причина |
|---|---|---|
| 1 | неизвестное имя команды | символ # в поясняющем тексте |
| 2 | неизвестное имя параметра | опечатка в поле [...] |
| 3 | указатель вышел за границу буфера | незакрытый текст или потерянный \E |
| 4 | процедура не закрыта символом @ |
|
| 5 | недопустимый индекс массива | функция или выражение в индексе |
| 6 | слишком большое значение параметра | |
| 7 | неверный тип массива или выход за границу | индекс 0 или больше максимума |
| 8 | процедура отсутствует | несовпадение первых четырёх букв имени |
| 9 | недопустимая операция в #f |
|
| 10 | недопустимый аргумент функции | sqr от отрицательного, log от нуля |
| 11 | синтаксическая ошибка в выражении | текст сразу после #c; 2*-3 |
| 12 | больше 45 вложенных циклов | незакрытый #end |
| 13 | файл данных отсутствует | |
| 14 | рекурсивный вызов процедуры | |
| 15 | больше 45 вложенных процедур | |
| 16 | переполнение массива | забыт сброс s(3) |
| 17 | неверная пара параметр=значение |
пропущен ] |
| 18 | недопустимое значение | ожидались число, буква или i(..)/r(..) |
| 19 | файл отсутствует | |
| 20 | недопустимая операция #io |
не из набора rf wf rb wb rd wd rt wt |
| 21 | комментарий программы не закрыт знаком = |
|
| 22 | текстовый комментарий не закрыт знаками ]! |
|
| 23 | нет файла в #f [op=line;] |
|
| 24 | деление на ноль | |
| 25 | переполнена база процедур (более 200) | |
| 26 | недопустимая операция #f |
|
| 27 | текстовый параметр не закрыт пробелом или ; |
|
| 28 | #rep с неположительным счётчиком |
счётчик оказался нулём |
| 31 | нет файла в #e [file=;] |
|
| 33 | число элементов в #d вне 1…500 |
символ # в тексте перед командой |
| 34 | цикл не закрыт к концу процедуры | |
| 35 | недопустимый формат в #io |
|
| 36 | недопустимая операция #te |
|
| 37 | недопустимая операция #m |
|
| 38 | #io с rt/wt не с массивом t() |
|
| 40 | форматированный текст не завершён | забыт \E |
| 41 | неизвестный код в форматированном тексте | опечатка после \ |
| 42 | слишком большое целое | |
| 900 | команда не поддержана этой реализацией | графика, GUI, звук |
| 1000 | программа остановлена | #stop или #exit — не ошибка |
Как поймать ошибку
По умолчанию ошибка прекращает выполнение. Чтобы обработать её самому, нужны
две вещи: параметр err не равен нулю и отмеченная командой #% точка
возврата. После ошибки исполнение продолжается с этой точки, а & получает
значение 10101.
# ok=1; !
#p [err=1;]
#%
#case 10101 # ok=0; #end |
# &=ok; !
#case 1 #io [op=rt; fir=t(1); n=10000; file=может-не-быть.txt;] #end |
# &=ok; !
#case 0 #pr файл прочитать не удалось\n\E #end |
#p [err=0;]
Разберём, как это работает. #% запоминает место, куда вернуться после
ошибки. При первом проходе & не равно 10101, и ветка #case 10101
пропускается. Если чтение файла сорвалось, исполнение возвращается сразу за
#%, а & становится 10101 — теперь ветка выполняется и сбрасывает флаг ok.
Флаг нужен, чтобы опасная команда не выполнилась повторно: иначе программа
снова наткнётся на ту же ошибку и снова вернётся к #%.
Код 900 в этот механизм не входит: он означает, что команда в принципе не реализована в порте, и требует запуска на оригинальном интерпретаторе.
Команды VKACL: обзор
В этом разделе описана каждая команда VKACL и каждая её операция. Порядок групп повторяет справочник автора: сначала многооперационные команды общего назначения, затем специализированные (анимация, PDF, PostScript, картинки как байты), затем команды с одной операцией и, наконец, номерные суперкоманды из библиотеки автора.
Где описание автора расходится с поведением интерпретатора, страницы следуют
интерпретатору (декомпилированный aclp.jar, проверки на нём же) и отмечают
расхождение в разделе «Тонкости».
Многооперационные команды
| Команда | Кратко | Что делает | Страница |
|---|---|---|---|
#f |
#f |
операции с файлами и папками: рабочая папка, размер, копирование, поиск и замена байтов, строки текста, редактор, конвертация картинок | #f |
#io |
#i |
чтение и запись массива в файл целиком: текст, байты, двоичные числа, числа по формату | #io |
#fr |
#fr |
показать картинку из памяти поверх всего и убрать её программно | #fr |
#g |
#g |
простая растровая графика: линии, фигуры, текст, оси, функции, аксонометрия | #g |
#m |
#m |
сообщения: терминал, окна с кнопками | #m |
#ma |
#ma |
математика над массивами: векторы, матрицы, комплексные числа, БПФ, свёртка, интерполяция | #ma |
#pf |
#pf |
окно-индикатор хода длительной работы | #pf |
#sys |
#sy |
секундомер и запуск внешних программ | #sys |
#te |
#te |
операции над текстовым массивом t(): поиск, замена, разбиение на слова, редактор, почта |
#te |
#w |
#w |
окна с картинками и научные графики: карты, графики функций, квази-3D | #w |
#z |
#z |
zip-архивы: каталог, упаковка, распаковка | #z |
Специализированные команды
| Команда | Кратко | Что делает | Страница |
|---|---|---|---|
#ag |
#ag |
окно анимации, фоновая музыка, опрос клавиш и мыши, слайд-шоу | #ag |
#bi |
#bi |
попиксельная обработка «сырых» байтовых картинок в файлах | #bi |
#eg |
#eg |
универсальная векторная графика (Java 2D): контуры, заливки, аффинные преобразования | #eg |
#pat |
#pat |
построение контуров (path) для #eg |
#pat |
#pd |
#pd |
создание PDF-документов, вставка страниц из других PDF | #pd |
#ps |
#ps |
векторная графика в EPS-файл | #ps |
Команды с одной операцией
| Команда | Кратко | Что делает | Страница |
|---|---|---|---|
# / #c |
# |
вычисления и присваивания | ядро |
#case |
#cas |
выполнить блок, если & равно метке; цикл «пока» |
ядро |
#ch |
#ch |
показать картинку и ждать клика или клавиши | #ch |
#col |
#co |
задать цвета в таблице цветов | #col |
#d |
#d |
заполнить массив или переменные списком значений | ядро |
#e |
#e |
выполнить процедуры, файл или текст из t() |
ядро |
#end |
#en |
конец блока #rep или #case |
ядро |
#exit |
#exi |
закрыть интерпретатор | ядро |
#go |
#go |
перейти на позицию в тексте программы | ядро |
#init |
#ini |
снять блокировку циклов после анимации, выключить звук | ядро |
#inp |
#inp |
панель с окнами ввода | #inp |
#p |
#p |
только задать параметры | ядро |
#pas |
#pas |
переслать значения между массивами | ядро |
#pr |
#pr |
напечатать форматированный текст в t() |
ядро |
#pro |
#pro |
определить процедуру | ядро |
#rea |
#rea |
прочитать числа из текста в t() |
ядро |
#rep |
#re |
повторить блок N раз | ядро |
#rob |
#rob |
пауза, снимок экрана, цвет пикселя | #rob |
#sel |
#se |
таблица кнопок для выбора варианта | #sel |
#so |
#so |
проигрывание и запись звука | #so |
#stop |
#st |
закончить текущую программу | ядро |
#v |
#v |
разложить элементы массива по переменным | ядро |
#% |
#% |
запомнить позицию для #go и для возврата после ошибки |
ядро |
##N |
— | номерная суперкоманда из библиотеки автора | суперкоманды |
Столбец «Кратко» — самая короткая запись, которая ещё попадает в нужную команду. Имя команды ищется в таблице подстрокой по первым трём буквам (см. Модель исполнения), поэтому некоторые сокращения коварны:
| Запись | На самом деле | Нужно писать |
|---|---|---|
#in |
#w (подстрока слова WIN) |
#inp или #ini |
#ro |
#pro |
#rob |
#pa |
#p |
#pas или #pat |
#ex |
#e |
#exi |
#ca |
#c |
#cas |
#i |
#io |
— |
#s |
#pas |
#se, #so, #st, #sy |
#a, #r |
#p |
#ag, #rea, #rep, #rob |
Общие соглашения
Операции
Многооперационные команды выбирают операцию по параметру op. Сколько букв
значимо, у каждой команды своё:
| Команда | Значимо букв op |
Неизвестная операция |
|---|---|---|
#ag, #fr, #pf |
1 | ошибка 55, 78, 84 |
#io, #sys, #w, #ps |
2 | ошибка 20, 49, 29, 65 |
#g, #eg, #pat, #ma, #z, #bi, #so |
3 | ошибка 52, 53, 54, 48, 51, 66, 56 |
#m |
3, сравнение точное | ошибка 37 |
#f, #te, #pd |
4 | ошибка 9, 36, 74 |
Лишние буквы игнорируются: op=close и op=clo в #g одно и то же. Но у #f
значимы четыре буквы, поэтому op=top там не сработает, а нужно op=topn.
Параметры и их короткие имена
Числовые параметры — это ячейки s(7)…s(44) (таблица в разделе
Поле параметров). Имя параметра ищется подстрокой по первым
трём буквам в таблице
FIR · · OPE FIL FOR NUM COD BEG LEN MOD TWI THE WID HEI XSH YSH STY BOT TOP NXF NYF SAV TSI UNI ERR FKI FSI COL TFO TKI MSI MKI TRX TRY SCA RAT SIZ ORD DIR EMP XPO YPO PAL. Автор часто пишет сокращения; в этом справочнике параметры
названы полными именами, а соответствие такое:
| Автор пишет | Это параметр | Ячейка |
|---|---|---|
tw, th |
twi, the |
s(12), s(13) |
xs, ys |
xsh, ysh |
s(16), s(17) |
st, bo, to |
sty, bot, top |
s(18), s(19), s(20) |
sa |
sav |
s(23) |
ts, un |
tsi, uni |
s(24), s(25) |
tf, tk |
tfo, tki |
s(30), s(31) |
ms, mk |
msi, mki |
s(32), s(33) |
sc, ra |
sca, rat |
s(36), s(37) |
di |
dir |
s(40) |
em, emp |
em |
s(41) |
xp, yp |
xpo, ypo |
s(42), s(43) |
pa |
pal |
s(44) |
Опасные сокращения, которые попадают не туда: wi — это twi, he — the,
si — tsi (а не siz), co — c (а не col), or — form, f и fi —
fir (для имени файла нужно минимум fil), mi — ошибка 2. Пишите wid,
hei, siz, col, ord, file полностью.
Куда команды кладут результаты
| Где | Что обычно там оказывается |
|---|---|
s(1), s(2) |
размер файла, число найденных совпадений, код модификатора клика и код клавиши |
s(3) |
позиция следующей записи в t(); её сдвигают все команды, которые печатают в t() |
s(4), s(5) |
начало и длина последнего фрагмента, записанного в t() |
s(6) |
наибольшая занятая позиция t() |
s(12), s(13) |
ширина и высота прочитанной картинки |
s(102)…s(105) |
координаты мыши x1 y1 x2 y2 после клика или протяжки |
s(106), s(107) |
размеры экрана |
& |
номер нажатой кнопки, признак «ОК/Отмена», найден ли шрифт |
A B C D E, V0 V1, $ |
входные и выходные скаляры команд #ma и #sys |
i(), r() |
списки позиций, таблицы координат, результаты #ma |
Файлы и папки
- Относительные имена у большинства операций отсчитываются от рабочей
папки, которую задаёт
#f [op=fold;]. Исключения оговорены на страницах команд:#e,#z,#sys,#fс операциямиfold,html,choo,fcat,alphработают от папки интерпретатора. - Имя файла в параметре
fileне длиннее 42 символов. Команды#io,#f,#w,#ag,#pd,#sys,#eпонимаютfile=arg: тогда имя берётся из первого аргумента — форматированного текста — и может быть любой длины. - Абсолютный путь (
C:/папка/файл) распознаётся по двоеточию во второй позиции, но только если рабочая папка не задана (#f [op=fold; file=null;]). - Имя, начинающееся с
&, в#io(rt,rd),#w,#agи#so [op=mid;]означает файл из папкиresourcesвнутри jar-файла интерпретатора.
Картинки и контуры в памяти
Графические команды сохраняют готовые картинки в память под номерами 1…100
(параметр sav), а берут их оттуда параметром n. Контуры #pat хранятся
отдельно, тоже под номерами 1…100. Номер вне диапазона при записи молча
игнорируется, при чтении даёт ошибку 63 (картинка) или 62 (контур).
Команды ядра
Здесь собраны команды, из которых складывается любая программа: вычисления, заполнение и пересылка массивов, печать в текстовый массив, ветвления, циклы, процедуры и переходы. Подробное введение — в туториале (вычисления, массивы, текст, ветвления и циклы, процедуры); эта страница — справка.
Общее правило для команд со списком аргументов переменной длины (# , #d,
#v, #e): список кончается на # (следующая команда), @ (конец процедуры)
или !. Если после такой команды идёт поясняющий текст, перед ним обязателен
!.
# и #c — вычисления
# приёмник=выражение; приёмник=выражение; ...
#c приёмник=выражение; ...
Решётка с пробелом — краткая форма команды #c. Приёмник — скалярная
переменная или элемент любого массива: a, x1, ab, i(k), r(k+1),
s(3), t(5). Выражение вычисляется полным вычислителем (см.
Выражения и функции) и обязательно заканчивается ;.
| Куда пишем | Что происходит со значением |
|---|---|
скаляр, r() |
хранится как есть (вещественное) |
i(), s() |
округляется до ближайшего целого |
t() |
трактуется как код символа; отрицательные от −64 до −1 превращаются в кириллицу А…я |
Внутри списка можно оставить комментарий: он начинается с ; и кончается
знаком =, например # a=1; ;здесь начальное значение= b=2;. Проще, однако,
закончить команду ! и писать пояснение обычным текстом.
# s(3)=1; a=2; b=a^3+1; i(1)=b/2; !
Здесь уже можно писать пояснения.
#pr a=\I3 a; b=\I3 b; i(1)=\I3 i(1);\n\E
Тонкости. Знаки < и > — минимум и максимум, а не сравнения, и
связывают они сильнее умножения. Унарный минус допустим только в начале
выражения и после (. Индексы массивов вычисляются урезанным вычислителем:
без функций и скобок.
#d — заполнить массив
#d N приёмник значение значение ... [N приёмник значения ...] [!]
Записывает N значений подряд, начиная с элемента приёмник. Групп
«число — приёмник — значения» в одной команде может быть сколько угодно.
| Элемент | Что допускается |
|---|---|
N |
от 1 до 500, иначе ошибка 33 |
| приёмник | элемент любого массива (r(11), i(1), s(9), t(1)) или скалярная переменная |
| значение | число, переменная или элемент массива; выражения не вычисляются |
значение*k |
повторить значение k раз |
Если приёмник — скаляр, заполняются следующие по порядку переменные того же
вида: #d 3 A 1 2 3 задаёт A, B, C; #d 2 AZ 5 6 — AZ и BZ. Так
задают входные данные суперкоманд. Приёмником может быть и s(): тогда #d
задаёт сразу несколько параметров команды.
# s(3)=1; k=7; !
#d 6 r(1) 1.5 2,5 k 0*3 !
#d 3 A 10 20 30 !
#pr \G r(1) r(2) r(3) r(4);\n\I4 A B C;\n\E
Тонкости.
- Запятая — десятичный разделитель:
2,5— это 2.5. Запятая с пробелом2, 5— два числа. *означает повтор, а не умножение:#d 3 r(1) 2*3даёт2 2 2.- Значение может быть переменной, но не выражением:
#d 1 r(1) k+1запишетk, а+1окажется лишним текстом. - Точка с запятой внутри списка открывает комментарий до знака
=.
#v — разложить массив по переменным
#v N источник приёмник1 приёмник2 ... приёмникN [N источник ...] [!]
Обратная к #d команда: берёт N элементов подряд, начиная с источник, и
присваивает их перечисленным приёмникам (переменным или элементам массивов).
N должно быть не меньше 1; верхней границы нет.
# s(3)=1; !
#d 3 r(11) 1.5 2.5 3.5 !
#v 3 r(11) a b c !
#pr \G a b c;\n\E
#pas — переслать массив
#pas N источник приёмник
Копирует N элементов (N ≥ 1, иначе ошибка 86) с приведением типа: в i() и
s() значения округляются, в t() попадают как коды символов, из t()
читаются коды. Перекрывающиеся области одного массива обрабатываются
правильно — #pas 4 r(1) r(2) сдвигает четыре числа на одну позицию вправо.
Группа в команде одна; для следующей пересылки нужна новая команда.
# s(3)=1; !
#pr (([[\E
#pas 4 t(1) i(11)
#pr коды \I4 i(11) i(12) i(13) i(14);\n\E
Тонкость. Имя нужно писать минимум из трёх букв: #pa — это #p.
#pr — печать в текстовый массив
#pr форматированный-текст\E
#pr (оно же #pri, #print) разбирает форматированный
текст и записывает результат в t(), начиная с позиции
s(3). После команды:
| Ячейка | Значение |
|---|---|
s(4) |
начало записанного фрагмента |
s(5) |
его длина |
s(3) |
сдвинута за конец фрагмента |
s(6) |
наибольшая занятая позиция t() |
Сам текст на экране не появляется — для этого есть
#m [op=txt;]. Код \Tp в следующем форматированном тексте
вставляет последний фрагмент, \TpN — его же без N последних символов
(\Tp4 превратит data.txt в data).
#pr — главный способ передать текст другим командам: имена файлов
(file=\Tp\E), заголовки окон, списки кнопок через |, входные тексты
суперкоманд.
# s(3)=1; !
#pr filename.dat\E
#pr \Tp4.png\E
#m [op=txt;] \Tp\n\E
Тонкости. Перед формированием нового текста обычно сбрасывают # s(3)=1;,
иначе t() постепенно заполняется до ошибки 16. Писать дальше позиции KY
нельзя: конец t() занят библиотекой суперкоманд (см.
Суперкоманды).
#rea — прочитать числа из текста
#rea [fir=приёмник; n=; b=; le=;]
Обратная к #pr операция: сканирует le символов t() начиная с t(b) и
записывает не более n чисел в массив, начиная с fir.
| Параметр | Смысл |
|---|---|
fir |
первый элемент приёмника: r(1), i(10), скаляр |
n |
сколько чисел прочитать самое большее |
b, le |
начало и длина текста в t() (часто b=s(4); le=s(5);) |
| Результат | Значение |
|---|---|
s(1) |
сколько символов реально просмотрено |
s(2) |
число прочитанных чисел плюс один |
# s(3)=1; !
#pr 1 2,5 3\E
#rea [fir=r(1); n=10; b=s(4); le=s(5);]
# k=s(2)-1; !
#pr прочитано \I2 k; чисел: \G r(1) r(2) r(3);\n\E
Тонкости.
- Числа разделяются пробелами или переводами строк; запятая — это
десятичный разделитель (
2,5), а запятая с пробелом — разделитель чисел. - Слово в тексте разбирается как имя переменной (и подставляет её значение)
или вызывает ошибку 18 — поэтому текст со словами сначала режут командой
#te [op=trim;]. Точка с запятой открывает комментарий до=. - Граница
leпроверяется только между числами. Если диапазон кончается прямо на цифре, разбор последнего числа может продолжиться за границу, в случайные символы рабочего буфера (12превращается в121). Включайте в диапазон разделитель после последнего числа.
#p — только параметры
#p [параметр=значение; ...]
Ничего не делает, кроме установки параметров. Удобна, чтобы задать параметры
один раз перед циклом или включить обработку ошибок: #p [err=1;]. Пустая
команда #p [] иногда служит «заглушкой» в конце текста, который выполняют
через #e _text.
#rep, #case, #end — циклы и ветвления
#rep N ... #end
#case N ... #end
#case N ... #end |
#case N ... #end (x)
| Команда | Что делает |
|---|---|
#rep N |
выполнить блок N раз; N ≤ 0 — ошибка 28 |
#case N |
выполнить блок, если & в точности равно N; иначе пропустить его целиком вместе с вложенными блоками |
#end |
закрыть блок; для #case — повторить блок, если целые части & и N совпадают |
#end | |
сначала &=12345 (значение, не совпадающее ни с какой меткой), потом проверка — то есть блок не повторяется |
#end (x) |
сначала &=x, потом проверка |
N в #rep и #case и x в #end (x) — число, переменная или элемент
массива. Выражения здесь не вычисляются. Вложенность блоков — до 45
уровней (ошибка 12 при превышении, 85 при #end без пары, 34 если блок не
закрыт к концу процедуры).
# s(3)=1; q=0; &=1; !
#case 1
# q=q+1; w=-sgn(q-4); !
#end (w)
#pr q=\I2 q;\n\E
Блок выполнится четыре раза: пока q меньше 4, w равно 1.
Тонкости.
#rep n+1повторит блокnраз:+1— уже не аргумент. Считайте счётчик заранее:# m=n+1; !и#rep m.#end (-sgn(q-4))не работает — в скобках допустимы только число или переменная. Вычислите значение отдельной командой.#caseсравнивает точно, а#end— только целые части. При&=1.4блок#case 1не выполнится, но блок#case 1.4, установивший&=1.9, будет повторяться.
#pro и #e — процедуры
#pro ИМЯ тело-процедуры @
#e [c=; file=; b=; le=;] имя1 имя2 ... [!]
#e _имя
#e [file=путь;] _file
#e [b=; le=;] _text
#pro запоминает процедуру, не выполняя её. Значимы ровно четыре первых
символа имени (более длинное обрезается, остаток становится частью тела; имя
короче четырёх букв не найдётся). Тело кончается первым символом @.
Процедура регистрируется, когда интерпретатор доходит до #pro, поэтому
определение должно стоять раньше вызова. Всего процедур — не больше 200
(ошибка 25).
#e выполняет процедуры по списку имён.
| Параметр | Смысл |
|---|---|
c |
код условия: без _ список выполняется, только если & в точности равно c |
file |
путь к файлу для _file, от папки интерпретатора; file=arg — путь из аргумента |
b, le |
начало и длина текста в t() для _text |
| Имя в списке | Что выполняется |
|---|---|
_имя |
процедура, безусловно (подчёркивание ставят перед первым именем) |
имя |
процедура, если & равно c |
_file / file |
весь файл как программа |
_text / text |
le символов t() начиная с t(b) как программа |
_\NN |
встроенная Java-программа автора номер NN (\00…\10) |
#pro sqre # y=x*x; @
# s(3)=1; x=5; !
#e _sqre !
#pr y=\I4 y;\n\E
Тонкости.
- Условие проверяется один раз — для первого имени. Остальные процедуры
цепочки выполняются безусловно, даже если первая изменила
&. cсравнивается с&точно: при&=1.5не выполнится ниc=1, ниc=2.- После
#e, за которым идёт текст или конец файла, выполняемого из другой программы, нужен!— иначе следующее слово будет принято за имя процедуры (ошибка 8). _fileи_textнельзя ставить в цепочку, а обычную процедуру, которая вызывает суперкоманду (это тоже выполнение файла), лучше вызывать отдельной командой.- Тело процедуры кончается на первом символе
@— даже если он стоит в\@внутри форматированного текста; команды после него уже не входят в процедуру. Внутри процедур пишите\u64;. - Рекурсия запрещена (ошибка 14), вложенность вызовов — до 45 (ошибка 15).
- Текст, выполняемый через
_text, заканчивайте!или#p []. - Процедуры, объявленные внутри файла
_file(и##имя), по его окончании забываются; переопределённая в файле процедура возвращается к прежнему определению (проверено). Процедуры из_textостаются, но их код лежит в месте, которое следующий_textили_fileперезапишет. _file,_textи суперкоманды можно вкладывать друг в друга: каждый следующий текст кладётся за предыдущим и освобождает место при возврате.#e [b=KY; le=670; n=N;] _textвыполняет диспетчер суперкоманд напрямую и равносилен##N; так написаны некоторые готовые программы автора.- Из встроенных программ общеполезен большой текстовый редактор
\09: путь к файлу печатают заранее, затем#e [n=1; em=1; c=1;] _\09. Остальные номера — специальные расчётные программы автора.
#go и #% — переходы и возврат после ошибки
#%
#go n
#% записывает в переменную % позицию в тексте программы сразу за собой.
#go n переносит разбор на позицию n (число или скалярная переменная, без
выражений и элементов массивов); выполнение продолжается со следующего #
после этой позиции.
Вторая роль #% — точка возврата при ошибке. Если err (s(26)) не равен
нулю, ошибка не прерывает программу: управление переходит на позицию %, а
& получает значение 10101 (подробнее — в Кодах ошибок).
# s(3)=1; q=0; !
#%
# q=q+1; &=sgn(3-q); !
#case 1 #go % #end |
#pr q=\I2 q;\n\E
Тонкость. Переход изнутри блока #rep или #case наружу не закрывает
блок. Пример выше выходит так дважды, и это безопасно, но каждый такой выход
оставляет незакрытый уровень вложенности: после 45 выходов будет ошибка 12, а
внутри процедуры — ошибка 34 при возврате. Для длинных повторов используйте
цикл #case … #end.
#stop, #exit, #init
| Команда | Что делает |
|---|---|
#stop |
заканчивает текущую программу; остальной текст файла не выполняется |
#exit |
закрывает интерпретатор целиком (все окна, среда разработки) |
#init |
возвращает нормальную работу циклов, заблокированных закрытием окна анимации #ag, и выключает звук (#ag, #so) |
Тонкость. #init не восстанавливает служебные ячейки s() и параметры —
он касается только циклов и звука. Имена сокращаются до #st, #exi, #ini;
#ex — это уже #e.
Суперкоманды
Суперкоманда — готовая программа на VKACL, которую вызывают одной короткой
записью, как команду: ##33, ##2. Суперкоманды автора — это научные
графики и карты, анимации, меню, окна подсказок, интерполяция,
преобразование Фурье, служебные операции с файлами. Их код не встроен в
интерпретатор, а лежит в библиотеке, которая входит в дистрибутив.
Как устроен вызов ##N
Когда после ## стоит число, интерпретатор делает всего две вещи:
- записывает номер в
s(7)— то есть в параметрn; - выполняет как программу 670 символов текстового массива, начиная с
t(1 899 331).
В этом месте t() лежит диспетчер — небольшая программа на VKACL, которую
кладёт туда стартовая программа автора (start.acl) при запуске
интерпретатора. Диспетчер ищет суперкоманду номер n в файле-библиотеке (по
одной суперкоманде в строке), при первом вызове читает её и запоминает в конце
t(), а при следующих вызовах запускает уже из памяти. Поэтому номерные
суперкоманды работают быстро, в том числе в циклах, и не нагружают диск. Кэш
живёт, пока открыт интерпретатор; автор держит его открытым постоянно, а при
странном поведении советует просто перезапустить.
Из этого устройства вытекают правила для любой программы:
| Правило | Почему |
|---|---|
не писать в t() дальше позиции KY; чтобы положить m символов в конец доступной части, начинайте с KY−m |
конец t() занят диспетчером и кэшем; KY задаёт стартовая программа |
не использовать двухбуквенные переменные, оканчивающиеся на Y (AY…KY и другие) |
их использует диспетчер |
по возможности не использовать и двухбуквенные на X и Z |
часть из них предопределена стартовой программой, другие (AZ, BZ, ZZ, ZY, …) служат входами и выходами суперкоманд |
помнить, что после ##N параметр n равен N |
так диспетчер узнаёт номер |
не рассчитывать на ##N без стартовой программы автора |
без неё по адресу диспетчера пусто |
Суперкоманда исполняется как код из файла, поэтому процедуру, внутри которой
есть вызов суперкоманды, не ставьте в цепочку #e _a b c — вызывайте её
отдельной командой.
Как передавать данные
У суперкоманды нет своего поля параметров и аргументов. Данные передают через общую память:
| Что | Как | Пример |
|---|---|---|
| числа | в переменные, чаще всего одной командой #d: #d 7 A … заполняет A, B, …, G |
#d 7 A 1 101 1 -1 1 247 1100 ! |
| числа (новый стиль) | в конец r(): сначала # ZZ=s(109); !, потом #d k r(ZZ−m) … |
#d 3 r(ZZ-10) 100 100 2 ! |
| числа (старый стиль) | в начало r(): r(1), r(2), … |
#d 7 r(1) J x1 x2 n X1 X2 m ! |
| тексты | последний напечатанный фрагмент #pr; части разделяются | |
#pr имя-файла|Заголовок\E |
| параметры | общие параметры (pal, em, xpo, ypo, fk, fs…) действуют как обычно |
#p [pal=1; em=0;] |
Результаты возвращаются в & (номер кнопки), в переменные (AZ, BZ, DZ,
TZ, I1, S1, …), в r(), в файлы и окна — у каждой суперкоманды по-своему.
Суперкоманды работают в общей памяти и могут портить переменные и массивы;
у многих в описании перечислено, что именно они используют.
#pr 1D|2D|Какой график построить?\E ##33
#case 1 #m [op=txt;] Выбран одномерный\n\E #end |
#case 2 #m [op=txt;] Выбран двумерный\n\E #end |
Старая форма ##имя
Если после ## стоит не цифра, а имя, выполняется файл proc/имя.acl из
папки интерпретатора — точно так же, как #e [file=proc/имя.acl;] _file, но
короче. Файл читается с диска при каждом вызове, поэтому в циклах такая
форма медленная. Данные передаются теми же способами. Своих суперкоманд этого
вида пользователь может написать сколько угодно; автор советует описывать их
назначение, входы и выходы комментарием прямо в файле.
Каталог номерных суперкоманд
Описание по справочнику автора (acls-info). Номера 47–50 в каталоге
отсутствуют. «Текст» — то, что нужно напечатать #pr перед вызовом.
| № | Что делает | Входные данные | Результат |
|---|---|---|---|
| 1 | график 1D нескольких функций из r() на равномерной сетке |
A — начало данных, B — число точек (отрицательное — ширина по числу точек, с прокруткой), C — число функций, D, E — пределы аргумента, F — цвет первой кривой (отрицательный — узкий график 550 px), G — четыре разряда: тысячи 0 — сохранить без показа, 1 — показать и сохранить, 2 — только показать, 3 — ни то ни другое, три младших — масштаб в %; обычно 1100. Текст: файл|заголовок |
окно, файл файл.png (980×500 при 100 %), при режиме 3 — картинка памяти 2 |
| 2 | карта матрицы с осями и размером пикселя, линейная шкала | A — начало, B, C — точки по горизонтали и вертикали, D — шесть разрядов (добавка к размеру текста 20, обращение контраста, показ, масштаб %; отрицательное — голая картинка без осей), E — пикселей экрана на точку по x (десятки) и y (единицы); E>0 — числа нормируются на 0…1, E<0 — настоящие значения; F — начало 15 чисел разметки трёх осей (по 5: начало, конец, первая длинная риска, шаг, число коротких). Текст: файл|заголовок. Параметры pal, em, xpo, ypo |
окно, файл.png; портит последние 100 элементов r() и 5 элементов i() |
| 3 | аксонометрия поверхности z(x, y) с разметкой осей |
A — начало, B, C — точки по x и y, D — показ и масштаб (как у 1), E — десятки: 1 x-z, 2 y-z, 3 оба сечения; единицы: 0 — две вертикальные оси, 1 — правая, 2 — левая; F — начало 15 чисел разметки; G, H, I — направление взгляда; J — lg расстояния; K, L — масштабы x, y; M, N — место заголовка. Текст: файл|заголовок |
окно, файл.png |
| 4 | квази-трёхмерный график 2D функции | A — начало, B, C — точки по x и y, D, E — пределы x, F, G — пределы y, H — добавочный сдвиг вправо, I — добавка к сдвигу сечений в шагах, J — вертикальный сдвиг сечений в 0,001 максимума (10…50), K — размер текста, L, M — добавки к ширине 900 и высоте 600. Текст: имя файла |
окно, файл картинки |
| 5 | разметка одной числовой оси | r(1), r(2) — начало и конец оси |
r(3) — первая длинная риска, r(4) — шаг, r(5) — число коротких рисок |
| 6 | стандартные параметры внешнего редактора #f [op=edit;] |
— ; дальше пишут #f [file=имя;] |
параметры установлены |
| 7 | стандартные параметры меню ##14 | — | параметры установлены |
| 8 | квадрат модуля комплексной функции | AZ — начало, BZ — число комплексных чисел |
BZ вещественных чисел с AZ |
| 9 | интерполяция функции одной переменной | r(1) — начало данных, r(2)…r(4) — первый, последний аргумент и число точек исходной сетки, r(5)…r(7) — то же для новой |
новая функция на месте старой |
| 10 | интерполяция функции двух переменных на квадрате | r(1) — начало, r(2)…r(4) — сетка (одинаковая по обеим осям), r(5) — начало результата, r(6)…r(8) — новая сетка |
новая матрица |
| 11 | стандартные параметры встроенного редактора #f [op=edtf;] |
— ; дальше #f [file=имя;] |
параметры установлены |
| 12 | прибавить к комплексному массиву вещественное число | AZ — начало, BZ — длина, CZ — число |
на месте |
| 13 | комплексное сопряжение массива | AZ, BZ |
на месте |
| 14 | вертикальное фасонное меню без рамки | X, Y — угол окна, W, H — размер кнопки, K — начертание 0…3; цвета 1–5: фон, заголовок, надписи, два цвета градиента кнопок. Текст: заголовок|кнопка1|…|кнопкаN|шрифт| |
& — номер выбранной кнопки (мышью или клавишами 1…9, 0, A…Z) |
| 15 | предложение прочитать справку | $ — 0 для файла на компьютере, 1 для адреса в интернете. Текст: путь от папки интерпретатора или адрес |
по OK файл открывается программой просмотра |
| 16 | таблица из 99 кнопок для выбора варианта | обычно ничего; нестандартно — &Z=99 и цвета цифр и фона в r(1)…r(6) |
& — номер кнопки |
| 17 | подсказка в строке над панелью задач | текст подсказки; ZY — положение (0 — стандарт, 0…1 — сдвиг) |
окно; закрыть — #fr [op=c; mo=1;] |
| 18 | графики действительной и мнимой частей комплексной функции | четыре числа в r(ZZ−21)…: начало, число точек, полуширина области аргумента, номер вызова 1…9 (отрицательный — без показа). Текст: подпапка для картинок |
файлы scarReM.png, scarImM.png |
| 19 | анимация по нумерованным картинкам с масштабированием | Текст через пробелы: папка файл музыка N1 N2 W H T — папка, образец имени (номер из трёх цифр перед точкой), MIDI или nomusic, первый и последний номера, размер кадра, пауза в мс |
окно: пробел — шаг, Enter — автоматически, Esc — выход; портит %0 |
| 20 | анимация сечений двумерного массива | 17 чисел в r(1)…r(17): Nx Ny x1 x2, пределы и разметка осей x и y, номер первой кривой, индекс данных в r() (0 — из файла), пауза в 0,1 с. Текст: файл|заголовок |
окно; Enter, пробел, Backspace, стрелки управляют показом |
| 21 | картинка-матрица из других картинок | Текст: имя файла параметров в рабочей папке; в нём первая строка — подпапка, имена картинок и имя результата, вторая — картинок в строке и строк | файл png |
| 22 | разложить девять разрядов Q по переменным |
Q |
&1…&9 — разряды слева направо |
| 23 | картинка с текстом подсказки (новая версия 25) | текст или имя файла; r(ZZ−20)…: W H X Y M N N1 N2 — размер, угол, режим (0 — текст из печати, 1 — строки N1…N1+N−1 файла), номер картинки |
окно; закрыть — #fr [op=c; mo=1;] |
| 24 | старая универсальная форма ввода данных | L — ширина рамки; ZZ=s(109); процедура genp; текст: папка|файл-подписей|файл-параметров|файл-описания|файл-заметок| |
запускает genp с введёнными данными |
| 25 | картинка с текстом подсказки (первая версия) | переменные W H X Y M N N1 N2; текст |
окно; портит f1 f2 H J M N N1 N2 W X y Y |
| 26 | график части r() для отладки |
r(ZZ−10)…: начало, число элементов, номер вызова 0…9 (отрицательное число — сохранить в smN.jpg, оба отрицательные — только сохранить). Текст: подпапка |
окно или файл |
| 27 | кнопка OK для паузы | r(ZZ−10)…: координаты левого нижнего угла и масштаб |
ждёт нажатия |
| 28 | анимация сечений трёхмерного массива | 19 чисел в r(1)…: размеры, разметка осей, номер первого кадра, индекс данных, пауза, палитра, нормировка, масштаб. Текст: файл|заголовок |
окно, управление как у 20 |
| 29 | поиск минимума функции двух переменных с графикой | r(ZZ−70)…: a1 a2 s1 s2 n — начальная точка, шаги, число вычислений; процедура pcmf вычисляет C по B1, B2 |
AZ, BZ — точка минимума; использует r() с 997001 |
| 30 | шифрование текстового файла | Текст: полный-путь ключ вариант — ключ 1…255; вариант 1 — только зашифровать, 2 — расшифровать для правки и снова зашифровать, 3 — только расшифровать |
файл |
| 31 | разметка трёх осей для карты | F — куда писать 15 чисел; r(ZZ−30)…: x1 x2 y1 y2 z1 z2 |
15 чисел с r(F) (вход для 2) |
| 32 | фасонное меню в два столбца | как у 14, число кнопок чётное | & |
| 33 | сообщение с кнопками в один ряд | Текст: кнопка1|…|кнопкаK|сообщение (без кнопок — только OK) |
& — номер кнопки, −1 — окно закрыто |
| 34 | дата и время изменения файла | Текст: полный путь (при #f [op=fold; file=null;]) |
DZ — ГГММДД, TZ — ччммсс; портит r(1)…r(30) |
| 35 | ввод входных данных из файла | Текст: имя файла; A — строк с двумя числами, B — строк с текстовыми параметрами, C — куда в t() писать тексты |
числа в r(1)…, за ними длины текстов, тексты в t() с C |
| 36 | контейнер программы: выбор строки входных данных и запуск | имя файла, напечатанное с KY−500−N; режим в t(KY−1); процедура pr36 (или prex при &z=1) |
запускает процедуру со строкой \TI1 S1; &0=1 — начать заново |
| 37 | файл с последней датой изменения в папке | Текст: папка | имя файла (\Tp); портит начало третьей сотни i() и часть конца t() |
| 38 | копирование картинок jpg и png в другую папку с нумерацией | Текст: папка-источник папка-результат шапка |
& — число скопированных, 0 — нечего |
| 39 | число картинок jpg и png в папке | Текст: папка | & |
| 40 | график строки матрицы из r() с интегралом |
r(1)…r(6): начало строки, размеры n1 n2, шаг, режим U, порог e. Текст: имя |
окно и файлы .png, .dat; S — интеграл |
| 41 | прямое и обратное двумерное БПФ | r(ZZ−200)…: начало, N1 n1 d1 и N2 n2 d2 (размер — степень 2, кратность расширения 1, 2, 4, шаг), k — −1 прямое, 1 обратное |
на месте |
| 42 | сменить палитру pal=3 |
NP — номер файла pro/hdata/cmNP.txt |
копия в colmap.txt |
| 43 | выбрать строку файла в редакторе | Текст: имя файла | I1, S1 — начало и длина строки; &0 — 1 при нормальном выходе, 0 при ошибке |
| 44 | номер строки после правки файла | Текст: имя файла | j — номер строки; a, b — имя файла в t(); &0 |
| 45 | модуль и фаза комплексной волновой функции с записью | Текст: имя без расширения; 13 чисел в r(1)… |
файлы имяa.png, имяb.png, имяa.dat, имяb.dat |
| 46 | свёртка с гауссианой на произвольной сетке | r(1)…r(4): начало, число точек, полуширина в шагах сетки, начало рабочего массива |
на месте |
| 51 | справочная карточка: коды форматированного текста | — | — |
| 52 | справочная карточка: таблица цветов | — | — |
| 53 | справочная карточка: параметры по именам и номерам | — | — |
| 54 | справочная карточка: массивы и их размеры | — | — |
Тонкость. Карточки 53 и 54 местами расходятся с интерпретатором: длины
текстовых параметров file и form там названы 22 и 62 символа (на деле по
42), сокращение mi для msi не работает (ошибка 2), а размер i() указан
149 999 (на деле 249 999). Точные значения — в
Поле параметров и Памяти.
#f — файлы и папки
#f [op=xxxx; file=имя; другие параметры] [аргументы]
Команда выполняет операции над файлами и папками: задаёт рабочую папку,
сообщает размер и дату файла, копирует, режет и удаляет, ищет и заменяет
последовательности байтов, читает и пишет строки текста, открывает редактор и
браузер, конвертирует картинки. Операцию выбирают первые четыре буквы op
(неизвестная — ошибка 9). Чтение и запись массивов целиком делает соседняя
команда #io.
Все операции
op |
Что делает | Группа |
|---|---|---|
fold |
задать рабочую папку, проверить существование папки | папки |
fcat |
список файлов папки в t() |
папки |
choo |
диалог выбора файла | папки |
size |
размер файла в s(1) |
сведения |
modi |
время последнего изменения | сведения |
dele |
удалить файл | копирование |
copy |
склеить несколько файлов в один | копирование |
divi |
вырезать из файла регулярную «подматрицу» байтов | копирование |
find |
сосчитать вхождения последовательности байтов | байты |
repl |
заменить последовательность байтов | байты |
rep2 |
заменить пары «открывающая — закрывающая» | байты |
rep3 |
заменить фрагменты «начало … конец» | байты |
line |
прочитать, записать или удалить строку | текст |
list |
собрать строку из чередующихся кусков файла | текст |
alph |
упорядочить строки файла по алфавиту | текст |
ruco |
перекодировать файл из windows-1251 в UTF-8 | текст |
edit |
внешний текстовый редактор | редакторы |
edtf |
внутренний текстовый редактор | редакторы |
html |
простой браузер HTML | редакторы |
tobm |
картинка → байтовая карта серого | картинки |
tocm |
картинка → байтовая карта RGB | картинки |
tops |
картинка → EPS | картинки |
topn |
картинка из памяти → PNG | картинки |
w2jc |
перевернуть порядок байтов в 4-байтовых числах | двоичные |
cdpj |
файл .npy (Python) → числа double для VKACL |
двоичные |
mb64 |
кодирование в MIME Base64 и обратно | двоичные |
Общие правила
| Параметр | Смысл |
|---|---|
op |
код операции, значимы 4 буквы |
file |
имя файла или папки, до 42 символов; file=arg — имя из первого аргумента |
form |
второе имя (результат), до 42 символов |
- Если задано
file=arg, имя читается из первого форматированного текста до остальных аргументов операции. - Имена у большинства операций отсчитываются от рабочей папки. От папки
интерпретатора (без рабочей папки) работают
fold,fcat,choo,html,alph. Абсолютный путь видаC:/…распознаётся по двоеточию во второй позиции, но только когда рабочая папка не задана. - Результаты, которые пишутся в
t(), ложатся с позицииs(3); после записиs(4)иs(5)дают начало и длину,s(3)сдвигается.
Папки
fold — рабочая папка
#f [op=fold; file=папка; em=;]
| Параметр | Смысл |
|---|---|
file |
путь от папки интерпретатора, вложенность через /; null — работать без рабочей папки; oldf — вернуть предыдущую |
em |
0 — несуществующую папку создать (один уровень); не 0 — не создавать |
Рабочая папка действует до следующего fold — и после конца программы, пока
открыт интерпретатор. При em≠0 проверка существования возвращается через
сам параметр: если папки нет, em (s(41)) становится 0.
Проверить, есть ли папка pro/data, не создавая её.
#f [op=fold; file=pro/data; em=1;]
# ok=s(41); !
#f [op=fold; file=oldf; em=0;]
Тонкости. Папки с именами null и oldf задать невозможно. Даже когда
проверка показала, что папки нет, она всё равно становится рабочей — верните
прежнюю через file=oldf, как в примере. Если папка есть, em остаётся
ненулевым; его читают и другие команды (например, line при em≠0 удаляет
строку), поэтому сразу верните em=0. После задания рабочей папки
абсолютные пути C:/… в других командах перестают работать; для них нужно
file=null.
fcat — каталог папки
#f [op=fcat; file=папка;]
Записывает в t() имена всех файлов и подпапок, после каждого имени —
символ |. Путь отсчитывается от папки интерпретатора (рабочая не
используется), абсолютный допустим. Если file — не папка, s(5)=0.
choo — выбор файла
#f [op=choo; mo=; file=;] [расширения\E]
| Параметр | Смысл |
|---|---|
file |
папка (или файл в ней), с которой начинается просмотр; от папки интерпретатора |
mo |
0 — все файлы; 1 — только картинки gif, jpg, png с предпросмотром; 2 — фильтр по расширениям из аргумента, например txt|bat|mp3\E |
| Результат | Значение |
|---|---|
& |
1 — файл выбран, 2 — отказ или окно закрыто, −1 — ошибка диалога |
t() с s(3) |
путь к файлу: от папки интерпретатора, если файл внутри неё, иначе полный; разделители / |
s(4), s(5) |
начало и длина пути; при отказе s(5)=0 |
Тонкость. Перед работой с выбранным файлом проверьте и &, и s(5), и
наличие файла через size. Режим mo=2, по словам автора, в новых версиях
Java может не работать.
Сведения о файле
size — размер
#f [op=size; file=имя;]
В s(1) — размер в байтах; 0 означает, что файла нет (или он пуст).
modi — время изменения
#f [op=modi; file=имя;]
Время последнего изменения в миллисекундах от 1970 года не помещается в целое,
поэтому оно разбито на два числа: s(2) — число полных десятидневок
(864 000 000 мс), s(1) — остаток в миллисекундах. Время равно
s(2)·864000000 + s(1). Для отсутствующего файла s(1)=0.
Удаление, копирование, разрезание
dele — удалить
#f [op=dele; file=имя;]
Удаляет файл без подтверждения. Если файла нет, ничего не происходит.
copy — склеить файлы
#f [op=copy; n=; file=результат;] имя1\E имя2\E ...
Создаёт файл file, в котором подряд записано содержимое n файлов,
перечисленных аргументами. Отсутствующие файлы пропускаются молча; если нет
ни одного, получится пустой файл. Аргументов может быть больше n (лишние
останутся текстом), но не меньше.
divi — вырезать регулярные куски
#f [op=divi; file=; b=; le=; xsh=; n=;]
Файл рассматривается как матрица байтов: пропустить b байтов, взять le,
затем n−1 раз пропустить xsh и взять le. Получается ровно le·n байтов
— например, прямоугольный фрагмент «сырой» картинки.
Тонкость. Автор пишет, что результат записывается в файл form. В
действительности результат записывается поверх исходного файла file, а
form не используется. Сделайте копию заранее (copy с n=1).
Поиск и замена байтов
Все три операции берут последовательности байтов из целого массива i():
элементы i(b), i(b+1), … Коды символов ASCII совпадают с байтами; байты
windows-1251 от 128 до 255 можно задавать как есть или как отрицательные
от −128 до −1. Изменённый файл записывается на старое место.
find — сосчитать вхождения
#f [op=find; b=; le=; file=;]
Ищет последовательность i(b)…i(b+le−1); число вхождений — в s(2). Нет
файла — ошибка 19.
#d 2 i(11) 13 10 !
#f [op=find; b=11; le=2; file=text.txt;]
# nl=s(2); !
Так считают строки файла, записанного в Windows (пара байтов 13, 10).
repl — заменить
#f [op=repl; b=; le=; mo=; file=;]
Первые mo байтов из i(b)… — что искать, остальные le−mo — на что
заменить (может быть и 0 байтов, тогда найденное удаляется).
#d 2 i(11) 44 46 !
#f [op=repl; b=11; le=2; mo=1; file=some.txt;]
Все запятые в файле станут точками.
rep2 — заменить пары
#f [op=rep2; b=; le=; mo=; twi=; the=; file=;]
После каждого вхождения первой последовательности ищется вторая, и обе
заменяются. Раскладка в i(b)…:
| Байты | Смысл |
|---|---|
первые mo |
первая искомая последовательность |
следующие le−mo |
замена для неё |
следующие the |
вторая искомая последовательность |
следующие twi−the |
замена для неё |
Всего le+twi байтов. Пример автора — двойные круглые скобки на двойные
квадратные:
# s(3)=1; !
#pr (([[))]]\E
#pas 8 t(1) i(1)
#f [op=rep2; b=1; le=4; mo=2; twi=4; the=2; file=some.txt;]
Поскольку b, le, mo, twi, the — это s(9)…s(13), их можно задать
одной командой #d 5 s(9) 1 4 2 4 2.
rep3 — заменить фрагменты по началу и концу
#f [op=rep3; b=; le=; mo=; twi=; file=;]
Находит каждый фрагмент, который начинается одной последовательностью и кончается другой (середина любая), и заменяет весь фрагмент третьей.
Байты в i(b)… |
Смысл |
|---|---|
первые mo |
начало фрагмента |
следующие twi |
конец фрагмента |
остальные le−mo−twi |
замена (может быть пустой) |
# s(3)=1; !
#pr \\U{}.\E
#pas 5 t(1) i(1)
#f [op=rep3; b=1; le=5; mo=3; twi=1; file=some.txt;]
Все коды вида \U{…} заменятся точкой.
Текстовые файлы
line — строка файла
#f [op=line; file=; n=; b=; le=; em=;]
n |
Действие |
|---|---|
−N |
прочитать строку N в t() с позиции s(3); s(4), s(5) — начало и длина; строки нет — s(5)=0 |
N, em=0 |
записать строку N из t(b)…t(b+le−1); если строк меньше, файл дополняется пустыми строками |
N, em≠0 |
удалить строку N |
Файл должен существовать (иначе ошибка 23). После удаления строки верните
em=0: этот параметр читают и другие команды.
# s(3)=1; !
#pr первая\nвторая\nтретья\n\E
# n9=s(3)-1; !
#io [op=wt; fir=t(1); n=n9; file=list.txt;]
#f [op=line; file=list.txt; n=-2;]
#m [op=txt;] \Tp\n\E
list — чередующиеся куски
#f [op=list; file=; c=; b=; em=;]
c и b — коды байтов. При em=0 операция берёт символы от начала файла по
символ с кодом c включительно, затем пропускает всё до символа с кодом b
включительно, снова берёт до c и так далее. При em≠0 порядок обратный:
сначала пропуск, потом взятие. Результат — одна строка в t() с s(3); в
s(2) — число взятых кусков. Так из файла записей «имя — тело» быстро
получают список имён. Байты windows-1251 переводятся в кириллицу.
alph — сортировка строк
#f [op=alph;] исходный-файл\E результат\E
Читает текстовый файл, упорядочивает строки по алфавиту и пишет результат во
второй файл. Пути отсчитываются от папки интерпретатора (или полные); для
файлов рядом с программой их удобно собрать кодами \M\H. Если строки
начинаются с номеров, сортировка получается по номерам.
ruco — windows-1251 → UTF-8
#f [op=ruco; file=;]
Перекодирует файл на месте. В начало записывается метка порядка байтов UTF-8
(EF BB BF). Содержимое не проверяется: применённая к файлу не в
windows-1251 или повторно, операция его испортит.
Тонкость. Правильно переводятся только ASCII и буквы А…я. Остальные
символы верхней половины windows-1251 — Ё, ё, №, кавычки «ёлочки» —
превращаются в посторонние символы.
Редакторы и просмотр
edit — внешний редактор
#f [op=edit; file=; mo=; c=; em=; xsh=; ysh=; nx=; ny=;]
#f [op=edit; file=here; b=; le=; mo=; c=;] заголовок\E
| Параметр | Смысл |
|---|---|
file |
редактируемый файл (создаётся, если его нет) или here — часть t() |
mo |
для файла: 1 — сохранить при выходе через меню, 0 — только просмотр; для here: −1 — только просмотр, −2 — вернуть текст в t() |
b, le |
для here — начало и длина текста в t() |
c |
0 — не ждать закрытия окна; иначе ждать |
em |
единицы: 0 — окно по центру, 1 — левый верхний угол в (xsh, ysh) от угла экрана, 2 — от угла главного окна; десятки: 1 — размер (700+nx)×(высота экрана − 100 + ny) |
fk, fs |
шрифт редактора (вид 1…5 и размер); запоминаются в start.acl |
s(1) |
до вызова — начальная позиция курсора (с нуля) |
| Результат | Значение |
|---|---|
s(1) |
позиция курсора при выходе |
& |
1 — выход через меню или Esc, 2 — крестиком |
t() с s(3) |
для file=here — текст из редактора; s(4), s(5) — начало и длина |
fk, fs |
шрифт, выбранный пользователем |
Для file=here аргумент-заголовок обязателен. Меню редактора умеет искать,
менять шрифт и перенос строк, перекодировать неверную раскладку, показывать
HTML и картинки и запускать выделенное имя файла. Та же работа для части t()
короче записывается командой #te.
Тонкость. Если выйти крестиком при mo=1, изменения в файл не
записываются.
edtf — внутренний редактор
#f [op=edtf; file=; mo=; em=; xsh=; ysh=;] [заголовок\E]
То же, что edit, но окно открывается внутри главного окна интерпретатора
(em: 0 — в углу, 1 — в точке (xsh, ysh)).
Тонкость. Окно немодальное: программа сразу идёт дальше, и в текущем
интерпретаторе ни позиция курсора, ни &, ни текст для file=here в
программу не возвращаются. Если результат нужен, используйте edit.
html — простой браузер
#f [op=html; file=путь;]
#f [op=html; file=*N;] путь\E
Показывает HTML-файл встроенным браузером из ранних версий Java (без JavaScript, только простая разметка). Окна модальные; ссылка открывается в новом окне поверх прежнего. Путь — от папки интерпретатора или полный.
file |
Откуда путь |
|---|---|
| имя | из самого параметра |
*1 |
из аргумента: файл на компьютере |
*2 |
из аргумента: адрес в интернете без http:// |
*3 |
из аргумента: файл в папке resources внутри jar-файла |
edee — большой редактор
Операция описана автором, но в интерпретаторе её нет (op=edee даёт ошибку
9). Тот же редактор вызывается как встроенная программа:
# &=0; s(3)=1; !
#pr pro/notes.txt\E
#e [n=1; em=1; c=1;] _\09
При c=1 программа ждёт закрытия редактора; &=1, если выход был по Esc.
Картинки
Операции tobm, tocm, tops принимают файл gif, jpg или png (проверяется
расширение, иначе ошибка 58) или file=here — тогда берётся картинка из
памяти под номером n. Результат пишется в файл form в рабочей папке. После
операции s(12) и s(13) — ширина и высота картинки.
tobm — байтовая карта серого
#f [op=tobm; file=; form=; dir=; n=; col=;]
Каждый пиксель превращается в один байт (r·R + g·G + b·B)/255, где R G B —
компоненты цвета номер col из таблицы цветов; результат
ограничивается сверху 255. dir=1 — строки сверху вниз, иначе снизу вверх
(как в расчётных картах). Размер файла равен числу пикселей.
Тонкость. По умолчанию col=1, а цвет 1 — чёрный: получится файл из
нулей. Для обычного среднего по трём каналам возьмите цвет 245
(85 85 85); цветной фильтр — любой другой цвет.
tocm — байтовая карта RGB
#f [op=tocm; file=; form=; dir=; n=;]
Три байта (красный, зелёный, синий) на пиксель, dir как у tobm.
tops — EPS из картинки
#f [op=tops; file=; form=; mo=; uni=; n=;]
mo |
Результат |
|---|---|
| 0 | полный EPS, оттенки серого |
| 1 | полный EPS, цветной |
| 2 | фрагмент PostScript-кода (серый) для вставки через #ps [op=ps;] |
| 3 | фрагмент, цветной |
| 4 | полный EPS другим, более надёжным кодом; если цветов меньше 256 — с палитрой |
| 5 | фрагмент тем же кодом |
Другие значения — ошибка 59. uni для mo 0 и 1 — масштаб в единицах
0,0001 (отношение пикселя экрана к точке PostScript; у автора было 6255).
form — полное имя с расширением. Коды 0–3 автор писал сам, и файл
показывается правильно, только если картинка стоит в PostScript-коде последней;
коды 4 и 5 от этого свободны.
topn — PNG из памяти
#f [op=topng; n=; form=;]
Записывает картинку номер n в файл form.png (расширение добавляется само).
Нет картинки — ошибка 63. Полезно для линейной графики: JPEG, который пишут
сами графические команды, размывает линии.
Двоичные форматы
w2jc — порядок байтов
#f [op=w2jc; file=;]
Переставляет байты в каждой четвёрке в обратном порядке и пишет файл на место. VKACL, как и Java, хранит числа старшим байтом вперёд, программы Windows — младшим; операция переводит 4-байтовые числа из одного порядка в другой. Повторное применение возвращает исходное.
cdpj — массив NumPy
#f [op=cdpj; file=исходный.npy; form=результат;]
Отрезает 128-байтовую шапку файла .npy и переворачивает порядок байтов в
каждом 8-байтовом числе. Результат читается через
#io [op=rd; mo=3;].
mb64 — Base64
#f [op=mb64; mo=; file=; form=;]
mo=1 — закодировать файл (обычно картинку) в текст Base64, mo=2 —
раскодировать обратно. Имя результата получается из имени исходного файла
заменой последних символов на form: при file=pic.jpg и form=b64 будет
pic.b64.
Тонкость. Операция использует класс sun.misc.BASE64Encoder, которого
нет в Java 9 и новее: на современной Java интерпретатор падает с исключением.
#io — массив в файл и обратно
#io [op=xx; fir=элемент; n=; file=имя; form=; mo=; le=; ord=;]
Команда переносит подряд идущие элементы массива в файл или из файла целиком,
одной операцией. Операцию задают две буквы: первая — направление (r
читать, w писать), вторая — вид данных. Неизвестная пара — ошибка 20.
Операции над файлами как объектами (размер, копирование, строки) — в
#f.
op |
Данные | Массив | Вспомогательные параметры |
|---|---|---|---|
rt / wt |
текст | только t() |
— |
rb / wb |
байты | любой | le — пропуск при чтении |
rd / wd |
числа в двоичном коде | любой | mo — формат числа, le — пропуск, ord |
rf / wf |
числа текстом | только i() и r() |
form — формат |
Параметры
| Параметр | Смысл |
|---|---|
fir |
первый элемент массива: t(1), i(10), r(k) (до 8 символов: r(9999999) уже не поместится, пишите r(k)) |
n |
число элементов; для rt — сколько символов прочитать самое большее |
file |
имя файла от рабочей папки; file=arg — имя из аргумента |
form |
формат для rf/wf |
mo |
формат двоичного числа для rd/wd |
le |
сколько байтов пропустить в начале файла при чтении (rb, rd) |
ord |
порядок байтов для mo=5: 0 — старший первым, иначе младший первым |
Читающие операции требуют, чтобы файл существовал (ошибка 19). Запись всегда создаёт файл заново.
rt, wt — текст
#io [op=rt; fir=t(k); n=; file=;]
#io [op=wt; fir=t(k); n=; file=;]
rt читает файл как текст и копирует в t() не больше n символов,
начиная с элемента fir (а не с s(3)). После чтения s(4) — начало,
s(5) — сколько символов прочитано; s(3) не меняется.
wt записывает n символов t() начиная с fir. Символ с кодом 10 в файле
становится переводом строки системы (в Windows — парой 13, 10). Готовить
содержимое удобно командой #pr.
# s(3)=1; !
#pr строка один\nстрока два\n\E
# n9=s(3)-1; !
#io [op=wt; fir=t(1); n=n9; file=out.txt;]
#io [op=rt; fir=t(1000); n=100000; file=out.txt;]
# ln=s(5); !
Тонкости. Реально прочитанное количество — в s(5), не в s(1). Имя с
& впереди (file=&help.txt) читает файл из папки resources внутри
jar-файла интерпретатора, но только когда рабочая папка не задана.
rb, wb — байты
#io [op=rb; fir=; n=; le=; file=;]
#io [op=wb; fir=; n=; file=;]
rb пропускает le байтов и читает n байтов как целые от −128 до 127.
При чтении в t() байты кириллицы windows-1251 (А…я, коды 192…255)
превращаются в буквы Юникода; байты 128…191 — в символы с кодами 128…191
(буквы Ё, ё так не читаются).
wb пишет значения как байты: из t() буквы А…я — в кодировке
windows-1251, из i() числа 128…255 — как соответствующие байты.
#io [op=rb; fir=i(1); n=4; le=0; file=pic.raw;]
Язык интерпретируемый, поэтому побайтовая обработка больших файлов медленна;
для картинок есть #bi и #f.
rd, wd — двоичные числа
#io [op=rd; fir=; n=; mo=; le=; ord=; file=;]
#io [op=wd; fir=; n=; mo=; ord=; file=;]
mo |
Формат | Байтов на число |
|---|---|---|
| 1 | вещественное float | 4 |
| 2 | целое int со знаком | 4 |
| 3 | вещественное double | 8 |
| 4 | целое short со знаком | 2 |
| 5 | целое без знака; порядок байтов задаёт ord |
2 |
Другие mo — ошибка 73. Для mo 1–4 порядок байтов как в Java: старший
первым. Файлы программ Windows переворачивают операцией
#f [op=w2jc;]. При wd с mo=5 значение больше 65535 —
ошибка 86.
При чтении le — число пропускаемых байтов (не чисел), а в s(1)
возвращается, сколько байтов реально пропущено.
# s(3)=1; !
#d 3 r(1) 1.5 2.5 3.5 !
#io [op=wd; fir=r(1); n=3; mo=1; file=f.dat;]
#io [op=rd; fir=r(11); n=2; mo=1; le=4; file=f.dat;]
#pr \G r(11) r(12);\n\E
Второе чтение пропускает первое число и даёт 2.5 и 3.5.
Тонкость. Если заказать больше чисел, чем есть в файле, ошибка не фиксируется: сообщение об исключении Java попадает только в терминал.
rf, wf — числа текстом
#io [op=rf; fir=; n=; form=*K; file=;]
#io [op=wf; fir=; n=; form=*N; file=;]
#io [op=wf; fir=; n=; form=EN.M.L; file=;]
Работают только с i() и r() (другой массив — ошибка 7). Числа из других
массивов сначала пересылают командой #pas.
rf читает n чисел подряд в любом виде, который понимает
#d: через пробелы и переводы строк, с точкой или запятой,
с порядком E. Формат здесь означает другое: form=*K — пропустить K
строк в начале файла (K — число или переменная).
wf пишет числа по формату:
form |
Вид строки |
|---|---|
*N |
по N чисел в строке, каждое — пробел и поле из 10 символов, как у \G |
EN.M.L |
по N чисел в строке, поле из M символов, L знаков после точки, порядок с буквой E; нужно M ≥ L+7, иначе ошибка 35 |
Например, 6 чисел с form=E3.10.3 дают две строки вида
1.000E+00 2.000E+00 3.000E+00. Строки кончаются переводом строки системы.
Более сложный вид файла собирают в t() командой #pr и пишут через wt.
# s(3)=1; !
#d 4 r(1) 1 2 3 4 !
#io [op=wf; fir=r(1); n=4; form=*2; file=nums.txt;]
#io [op=rf; fir=r(11); n=4; form=*0; file=nums.txt;]
#pr \G r(11) r(12) r(13) r(14);\n\E
Тонкости.
wfбез формата (пустойformили не начинающийся с*илиE) не пишет ничего и не сообщает об ошибке.form— общий параметр: оставшийся от прошлой командыform=*5заставитrfпропустить пять строк. Задавайте его в каждой команде.- Если в файле меньше
nчисел,rfкончается ошибкой 18.
#te — операции с текстовым массивом
#te [op=xxxx; b=; le=; другие параметры] [аргумент\E]
Команда работает с куском массива t() от t(b) длиной le символов:
ищет символы и подстроки, заменяет символы, режет текст на слова, отсекает
хвостовые пробелы, показывает кусок в редакторе. Значимы четыре буквы op;
неизвестная операция — ошибка 36. Понятия «строка» в языке нет: строка — это
пара чисел «начало, длина», и #te выдаёт именно такие пары.
op |
Что делает | Результат |
|---|---|---|
find |
найти все позиции символа | i(n)…, s(1) |
fitt |
найти все вхождения подстроки | i(n)…, s(1) |
repl |
заменить символ на другой | сам текст |
trim |
разбить на слова по пробелам | пары в i(n)…, s(1) |
tail |
отсечь хвостовые пробелы и переводы строк | новое le |
show |
показать кусок в редакторе без правки | s(1), & |
edit |
отредактировать кусок и получить результат | t() с s(3), s(1), & |
emls |
отправить письмо по электронной почте | t() с s(3) |
Коды символов — коды Юникода: для латиницы и цифр они совпадают с ASCII,
русские буквы А…я имеют коды 1040…1103.
find — позиции символа
#te [op=find; b=; le=; c=код; n=;]
Записывает в i(n), i(n+1), … индексы t() всех символов с кодом c;
их число — в s(1).
fitt — позиции подстроки
#te [op=fitt; b=; le=; c=начало; twi=длина; n=;]
Образец лежит в самом t(): twi символов начиная с t(c) (здесь c —
индекс, а не код). Индексы начала каждого вхождения — в i(n)…, их число — в
s(1). После найденного вхождения поиск продолжается за его концом, так что
перекрывающиеся вхождения не считаются.
repl — замена символа
#te [op=repl; b=; le=; c=старый-код; mo=новый-код;]
Заменяет каждый символ с кодом c на символ с кодом mo.
trim — слова
#te [op=trim; b=; le=; n=;]
Находит куски текста, разделённые пробелами, и записывает для каждого пару
«начало, длина»: i(n), i(n+1) — первый кусок, i(n+2), i(n+3) — второй и
так далее. Число кусков — в s(1). Пары прямо подходят как b и le для
#rea и других команд.
# s(3)=1; !
#pr x= 12 y= 3,5\u32;\E
#te [op=trim; b=s(4); le=s(5); n=1;]
# k=s(1); !
#rea [fir=r(1); n=1; b=i(3); le=i(4)+1;]
#rea [fir=r(2); n=1; b=i(7); le=i(8)+1;]
#pr кусков \I2 k; x=\G r(1); y=\G r(2);\n\E
Здесь четыре куска: x=, 12, y=, 3,5; второй и четвёртый читаются как
числа 12 и 3.5. Длина для #rea взята на единицу больше, чтобы в диапазон
попал пробел после числа (почему это нужно — см. тонкости
#rea).
Тонкости.
- Последний кусок, упирающийся в конец диапазона, теряется: для него
записывается только начало, а в
s(1)он не входит. Оставляйте в конце текста пробел (в примере это\u32;: обычный пробел перед\Eсъедается). - Разделитель — только пробел. Перевод строки и табуляция считаются частью слова.
tail — хвост
#te [op=tail; b=; le=;]
Уменьшает le (s(10)) так, чтобы кусок не кончался пробелами, символами
перевода строки или возврата каретки. Удобно после чтения строк из файлов и
окон ввода.
show — просмотр
#te [op=show; b=; le=;] заголовок\E
То же, что #f [op=edit; file=here; mo=-1; c=1;]: кусок
t() показывается в редакторе без возможности сохранить правку. s(1) до
вызова — начальная позиция курсора (с нуля), после — позиция при выходе;
& — 1 при выходе через меню или Esc, 2 — крестиком. Положение и размер
окна, шрифт задаются параметрами em, xsh, ysh, nx, ny, fk, fs,
как у #f [op=edit;].
edit — правка
#te [op=edit; b=; le=;] заголовок\E
То же, что #f [op=edit; file=here; mo=-2; c=1;]: после закрытия редактора
текст записывается в t() с позиции s(3); s(4), s(5) — начало и длина,
s(3) сдвигается. s(1) и & — как у show.
# s(3)=1; !
#pr Отредактируйте этот текст\E
#te [op=edit; b=s(4); le=s(5);] Правка\E
#m [op=txt;] \Tp\n\E
emls — электронная почта
#te [op=emls;] поле1|поле2|...|поле9|текст письма\E
Отправляет письмо через почтовый сервер (нужен интернет). Аргумент состоит
из десяти полей через |: девять служебных (сервер, адреса и прочее) и текст
письма. Назначение служебных полей автор не описывает, а отсылает к примеру
pro/emls1.acl из дистрибутива. Если программа отправки что-то вернула, этот
текст записывается в t() с позиции s(3); иначе s(5)=0.
#ma — математика над массивами
#ma [op=xxx; b=; le=; nx=; ny=; trx=; ...] [аргументы]
Команда выполняет над частями массива r() операции, которые на самом VKACL
писать долго и считать медленно: заполнение и поэлементные функции векторов,
действия с матрицами, комплексная арифметика, быстрое преобразование Фурье,
свёртка, интерполяция, поиск пиков. Код операций написан на Java и работает
на порядки быстрее цикла на VKACL. Значимы три буквы op; неизвестная
операция — ошибка 48.
Соглашения
| Понятие | Как лежит в памяти |
|---|---|
| вектор | le чисел r(b), r(b+1), …, r(b+le−1) |
| второй вектор | такой же длины, начиная с r(b+trx); trx может быть отрицательным |
матрица nx × ny |
по строкам: строка k (с нуля) занимает r(b+k·nx) … r(b+k·nx+nx−1); nx — длина строки (первый индекс), ny — число строк |
| комплексный массив | пары «действительная, мнимая часть»: r(b), r(b+1) — первое число, r(b+2), r(b+3) — второе |
Почти все операции пишут результат на место исходных данных или сразу за ними; куда именно — сказано в описании каждой. Кроме параметров, часть операций берёт числа из скалярных переменных и возвращает результат в них:
| Переменная | Где используется |
|---|---|
A, B |
vig (начало и шаг аргумента), mmr (угол), результаты cwm |
C |
константа для vic, via, vac, vmc, vpo, mmi; результат vvs, cwm; период для mip |
D |
шаг для via, ширина для vig, множитель для fft, период для mip, диаметр шара в bsi, bsr; результат cwm |
E |
малая добавка против деления на ноль в ccd, dcc |
V0, V1 |
границы для var |
N, K, N1 |
число шаров, начало и число отрезков стенки в bsm, bsi, bsr |
Операции, читающие файлы (mcg, mmi, smh, rfh), ищут их в рабочей
папке.
Все операции
| Группа | Операции |
|---|---|
| заполнение вектора | vic, via, vig |
| поэлементные функции | vac, vmc, vpo, vex, vlo, vsi, vco, vin, vba, var |
| два вектора | vva, vvm, vvs |
| сортировка и пики | vor, cwm |
| производные и первообразные | fdf, sdf, ffd, fsd |
| матрицы | mtr, mii, fno, mss, mds, mip, mmr, tom, gis |
| интерполяция | fis, ffi, mmi |
| комплексные массивы | com, ccm, ccd, mcc, dcc, cen, cne |
| Фурье и свёртка | fft, mcg |
специальные вычисления vsm |
vsm в семи режимах |
| изображения детекторов | smh, rfh |
| разметка осей | box |
| система шаров | bsm, bsi, bsr |
Имя vlm есть в таблице операций, но ничего не делает.
Заполнение вектора
op |
Что записывает в r(b+i), i = 0 … le−1 |
|---|---|
vic |
C |
via |
C + D·i — арифметическая прогрессия |
vig |
exp(−a·(A + B·i − C)²), где a = 4·ln 2 / D² — гауссиана с центром C и полной шириной на половине высоты D; аргумент начинается с A и растёт с шагом B |
# s(3)=1; A=-1; B=0.5; C=0; D=1; !
#ma [op=vig; b=1; le=5;]
#pr \G r(1) r(2) r(3) r(4) r(5);\n\E
Получится 0.0625 0.5 1 0.5 0.0625: на расстоянии половины ширины от
центра значение ровно 1/2.
Поэлементные функции
Параметры b, le; результат на месте вектора.
op |
x превращается в |
Замечание |
|---|---|---|
vac |
x + C |
|
vmc |
x · C |
|
vpo |
x^C |
проверки допустимости нет |
vex |
exp(x) |
|
vlo |
ln(x) |
для x ≤ 0 получится не число, ошибки нет |
vsi |
sin(x) |
|
vco |
cos(x) |
|
vin |
⌊x⌋ — целая часть снизу |
пересылка в i() округляет, а не отбрасывает |
vba |
x + 256, если x < 0 |
байты −128…127 → коды 0…255 |
var |
x, ограниченное снизу V0 и сверху V1 |
Тонкость. В справочнике автора имена vac и vmc набраны с русской
буквой «с». Скопированные оттуда, они дают ошибку 48 — набирайте латиницей.
Два вектора
Первый вектор — r(b)…, второй — r(b+trx)…, оба длины le. Векторы не
должны перекрываться (кроме trx=0).
op |
Результат |
|---|---|
vva |
первый вектор заменяется суммой; для вычитания второй сначала умножают на −1 (vmc) |
vvm |
первый вектор заменяется поэлементным произведением; при trx=0 — квадратами |
vvs |
скалярное произведение — в переменную C |
# s(3)=1; !
#d 4 r(1) 1 2 3 4 !
#d 4 r(5) 2 2 2 2 !
#ma [op=vvs; b=1; le=4; trx=4;]
#pr скалярное произведение = \G C;\n\E
Сортировка и параметры пика
vor — упорядочить
#ma [op=vor; b=; le=; mo=;]
mo=1 — по возрастанию, mo=2 — по убыванию. В i(1)…i(le) записываются
прежние номера элементов (с единицы, относительно b) в новом порядке: по ним
тем же образом переставляют другие векторы.
# s(3)=1; !
#d 5 r(1) 3.5 1.25 4.75 2.5 0.5 !
#ma [op=vor; b=1; le=5; mo=1;]
#pr \G r(1) r(2) r(3) r(4) r(5);\n\I3 i(1) i(2) i(3) i(4) i(5);\n\E
Результат: 0.5 1.25 2.5 3.5 4.75 и номера 5 2 4 1 3.
Тонкости. Автор пишет, что mo=0 сортирует по убыванию; на деле при
mo=0 порядок не меняется (массив i() всё равно заполняется числами
1…le). Номера всегда пишутся с i(1), затирая то, что там было.
cwm — максимум и его ширина
#ma [op=cwm; b=; le=; mo=;]
| Результат | Значение |
|---|---|
A |
наименьшее значение вектора |
B |
наибольшее значение, уточнённое параболой по соседним точкам (не меньше любого элемента) |
C |
положение максимума, дробный номер элемента с единицы |
D |
ширина области, где значения выше уровня: B/2 при mo=0, (A+B)/2 при mo=1; 0, если уровень не пересечён с обеих сторон |
Ширина получается в шагах сетки; для физических единиц её умножают на шаг.
Производные и первообразные
Функция задана на равномерной сетке с шагом 1; при другом шаге результат
делят на шаг (для второй производной — на его квадрат) или умножают на шаг.
Исходный вектор F лежит в r(b+trx)…, результат f — в r(b)…, длина
le = N.
op |
Формула | Края |
|---|---|---|
fdf |
f[k] = (F[k+1] − F[k−1])/2 — первая производная |
f[1]=f[2], f[N]=f[N−1] |
sdf |
f[k] = F[k+1] + F[k−1] − 2F[k] — вторая производная |
так же |
ffd |
f[k+1] = f[k] + (F[k] + F[k+1])/2 — функция по производной (трапеции) |
f[1] задают заранее |
fsd |
f[k+1] = F[k] + 2f[k] − f[k−1] вперёд и f[k−1] = F[k] + 2f[k] − f[k+1] назад — функция по второй производной |
две точки f[n], f[n+1] задают заранее |
У fsd параметр n — номер (с единицы, внутри вектора) первой из двух
известных точек. При n=1 расчёт идёт слева направо; при n>1 сначала
вычисляются точки правее, потом левее. Это нужно, когда вторая производная у
края определена плохо и движение от края портит весь результат.
Матрицы
mtr — транспонирование
#ma [op=mtr; b=; nx=; ny=;]
Матрица из ny строк длины nx заменяется транспонированной: nx строк
длины ny. Удобно после чтения таблицы из файла по строкам: столбцы (отдельные
функции) становятся непрерывными кусками.
mii — обращение порядка индексов
#ma [op=mii; b=; nx=; ny=; mo=;]
mo |
Что меняется |
|---|---|
| 0 | обратный порядок и элементов в строках, и самих строк (поворот на 180°) |
| 1 | обратный порядок элементов в каждой строке (отражение слева направо) |
| 2 | обратный порядок строк (отражение сверху вниз) |
fno — минимум, максимум, среднее, нормировка
#ma [op=fno; b=; nx=; ny=; mo=;]
Для каждой из ny строк находит минимум, максимум и среднее и пишет их сразу
за матрицей: с r(b+nx·ny) — ny минимумов, затем ny максимумов, затем
ny средних. При mo=0 каждая строка вдобавок нормируется на отрезок
[0, 1]: (v − min)/(max − min); при других mo матрица не меняется.
mss — суммы по строкам и столбцам
#ma [op=mss; b=; nx=; ny=; em=;]
Результаты пишутся подряд сразу за матрицей, с r(b+nx·ny):
| Случай | Что записывается |
|---|---|
ny>1, em=0 |
nx сумм по столбцам (для каждого первого индекса — сумма по строкам), затем ny сумм по строкам, затем общая сумма |
ny>1, em=1 |
только nx сумм по столбцам и общая сумма |
ny>1, em=2 |
только ny сумм по строкам и общая сумма |
ny=1 |
только сумма всего вектора |
Для матрицы 1 2 3 / 4 5 6 (nx=3, ny=2) при em=0 за ней появится
5 7 9 6 15 21. Это численное интегрирование функции двух переменных по
одной, по другой и по обеим.
mds — диагональное сечение
#ma [op=mds; b=; nx=; ny=; xpo=; ypo=; dir=; n=; sav=;]
Вектор длины n с r(sav) обнуляется, в его середину записывается элемент
матрицы в столбце xpo и строке ypo (с единицы), а затем вектор
заполняется элементами диагонали через эту точку, пока она не выйдет за
матрицу: вперёд и назад от середины. dir=1 — диагональ вправо-вверх,
dir=−1 — влево-вверх. Часть элементов может остаться нулями. Используется
для интегрирования локальной функции вдоль диагонали.
mip — размножение периода
# C=p1; D=p2; !
#ma [op=mip; b=; nx=; ny=;]
В центре матрицы выделяется прямоугольник p1 × p2 (периоды в шагах сетки,
могут быть дробными), а все элементы вне его пересчитываются из условия
периодичности с линейной интерполяцией: сначала по вертикали, потом по
горизонтали. Так заполняют большую матрицу копиями одного периода или
восстанавливают периодичность, испорченную у краёв. Чтобы не было скачков,
значения на границах периода должны совпадать. Одномерный случай: ny=1,
D=1.
mmr — поворот квадратной матрицы
# A=угол; !
#ma [op=mmr; b=; le=;]
Матрица le × le поворачивается вокруг центра на угол A в радианах, как
чёрно-белая картинка; значения берутся билинейной интерполяцией, точки,
пришедшие из-за края, равны нулю. Результат пишется сразу за исходной
матрицей, с r(b+le²).
tom — томографическая обратная проекция
#ma [op=tom; n=; le=; siz=; b=;]
Исходные данные с r(n): siz проекций по le значений, каждая проекция —
непрерывный кусок. Проекция номер m соответствует углу π·m/siz.
Результат — квадратная матрица le × le с r(b): для каждой её точки
суммируются интерполированные значения всех проекций. Области не должны
перекрываться. Во время расчёта показывается окно хода работы.
gis — гистограмма
#ma [op=gis; b=; le=; n=; sav=;]
Для каждого из le чисел r(b)… берётся целая часть снизу (прижатая к
отрезку 0…n−1), и соответствующий элемент гистограммы увеличивается на 1.
Гистограмма из n чисел пишется с r(sav); перед подсчётом она обнуляется.
Интерполяция
fis — кубический сплайн
#ma [op=fis; b=; nx=; ny=; siz=;]
Строки матрицы — функции, заданные на общей сетке с переменным шагом. Сетка
из nx значений аргумента лежит прямо перед матрицей, с r(b−nx); матрица —
ny строк длины nx с r(b). Каждая строка интерполируется кубическим
сплайном на равномерную сетку из siz точек от первого до последнего
значения аргумента. Новая матрица (ny строк длины siz) пишется сразу за
старой, с r(b+nx·ny). nx или siz меньше 2 — ошибка 60.
ffi — линейная интерполяция строк
#ma [op=ffi; b=; nx=; ny=; c=; wid=; n=;]
Раскладка исходных данных та же, что у fis. Новая сетка — wid точек
(хоть одна) от r(c) до r(c+1); результат, ny строк длины wid, пишется
с r(n). Точка вне исходного интервала получает граничное значение.
# s(3)=1; !
#d 3 r(1) 0 1 3 !
#d 3 r(4) 0 10 30 !
#d 2 r(21) 0 3 !
#ma [op=ffi; b=4; nx=3; ny=1; c=21; wid=4; n=31;]
#pr \G r(31) r(32) r(33) r(34);\n\E
Функция 0, 10, 30 на сетке 0, 1, 3 переносится на сетку 0, 1, 2, 3: получится
0 10 20 30.
mmi — матрица в матрицу
#ma [op=mmi; n=; b=; nx=; ny=; sav=; wid=; hei=; file=; form=; em=;]
Исходная матрица nx × ny описывает прямоугольник [xi1, xi2] × [yi1, yi2],
новая wid × hei — прямоугольник [xo1, xo2] × [yo1, yo2]. Восемь чисел
xi1 xi2 yi1 yi2 xo1 xo2 yo1 yo2 лежат с r(n). Шаг сетки
(x2 − x1)/(nx − 1), интерполяция линейная.
| Параметр | Смысл |
|---|---|
file |
файл с исходной матрицей (числа float, 4 байта); here — матрица в r(b)… |
form |
файл для результата (float); here — результат в r(sav)… |
em |
точки вне исходного прямоугольника: при em=1 получают значение C, иначе — среднее исходной матрицы |
Операция оптимизирована под одномерный случай: сначала интерполируются
строки, потом столбцы. Поэтому при большом ny и одной выходной точке
(wid=hei=1) она работает непропорционально долго — ограничьте ny двумя
нужными строками.
Комплексные массивы
ccm, ccd — умножение и деление
#ma [op=ccm; b=; le=; trx=;]
#ma [op=ccd; b=; le=; trx=;]
Первый массив из le комплексных чисел — с r(b), второй — с r(b+trx).
Результат заменяет первый массив. ccd делит по формуле
c1·conj(c2)/(|c2|² + E²), поэтому переменная E должна быть задана малым
числом.
mcc и dcc — старые варианты тех же операций: размер задаётся в nx, а
второй массив лежит сразу за первым (r(b+2·nx)). Их оставили для старых
программ.
cen, cne — модуль и фаза
#ma [op=cen; b=; n=; trx=;]
#ma [op=cne; b=; n=; trx=; nx=; ny=;]
op |
Откуда | Куда |
|---|---|---|
cen |
n модулей с r(b) и сразу за ними n фаз |
n комплексных чисел с r(b+trx) |
cne |
n комплексных чисел с r(b) |
n модулей с r(b+trx) и сразу за ними n фаз |
Области не должны перекрываться (|trx| > 2n); это не проверяется. cne
«выпрямляет» фазу — убирает скачки на 2π, двигаясь от точки номер nx в обе
стороны (выберите её там, где фаза меняется медленнее всего; при nx вне
1…n берётся n/2). Для двумерных массивов выпрямление отключают, задав
ny=10101.
com — программа комплексной арифметики
#ma [op=com; em=0;] K A B C K A B C ... !
#ma [op=com; em=1; b=;] Xabc Xabc ... !
#ma [op=com; em=2; b=;]
Операция выполняет последовательность действий над комплексными числами в
r(): над первыми двумя операндами, с результатом в третьем.
Код K (em=0) |
Символ (em=1) |
Действие |
|---|---|---|
| 1 | + |
C = A + B |
| 2 | - |
C = A − B |
| 3 | * |
C = A · B |
| 4 | / |
C = A / B |
| 5 | E |
C = exp(A) |
| 6 | C |
C = cos(A) |
| 7 | S |
C = sin(A) |
| 8 | T |
C = tan(A) |
| 9 | P |
C = A^Re(B) — только действительная степень |
| 10 | L |
C = ln(A) |
| 11 | 0 |
C = J0(A) — функция Бесселя |
| 12 | 1 |
C = J1(A) |
При em=0 каждая команда — четыре числа: код и индексы в r()
действительных частей трёх чисел (мнимые лежат следом). Для функций второй
операнд не нужен, на его месте можно писать 0.
При em=1 комплексные числа называются буквами a…z: a — это r(b),
b — r(b+2), c — r(b+4) и так далее. Команда — символ действия и три
буквы; писать их можно слитно (*abc) или через пробелы (* a b c).
Список команд кончается на #, @ или !; если дальше идёт текст, !
обязателен.
# s(3)=1; !
#d 4 r(1) 1 2 3 4 !
#ma [op=com; em=1; b=1;] *abc !
#pr (1+2i)(3+4i) = \G r(5) r(6);\n\E
Получится −5 + 10i. То же при em=0: #ma [op=com; em=0;] 3 1 3 5 !.
При em=2 операция умножает комплексные матрицы. Шесть целых чисел лежат с
i(b): i1 i2 i3 n1 n2 n3 — начало первой матрицы, второй и результата в
r(), число строк первой матрицы, число её столбцов (оно же число строк
второй) и число столбцов второй. Области не должны пересекаться. При
размерностях n 1 1 получается умножение вектора на число, при n 1 m —
матрица из двух векторов.
Тонкость. Автор честно предупреждает: ошибки в такой записи искать
трудно. Отлаживайте программу com на числах, результат которых знаете.
Фурье и свёртка
fft — быстрое преобразование Фурье
# D=множитель; !
#ma [op=fft; b=; nx=k; em=;]
Комплексный массив из N = 2^|k| чисел с r(b) заменяется своим
Фурье-образом. |k| не больше 22 (ошибка 57). Знак k задаёт знак в
показателе экспоненты: при k>0 вычисляется
fq[n] = Σ exp(+2πi·nm/N)·fx[m], при k<0 — с минусом. Результат умножается
на переменную D.
em |
Что вычисляется |
|---|---|
| 0 | интеграл Фурье: сумма с фазовыми множителями, так что функция и образ заданы на симметричных сетках d·(n + (1−N)/2); старый код через комплексные объекты |
| 1 | только сумма, как в numpy.fft: образ сдвинут на полпериода, знаки чередуются, но обратное преобразование точно восстанавливает функцию |
| 2 | то же, что 0, без комплексных объектов, немного быстрее |
| 3 | то же, что 1, без комплексных объектов, примерно вдвое быстрее |
Для интеграла Фурье автор рекомендует задавать в D множитель d/2π, где
d — шаг сетки.
# s(3)=1; !
#d 8 r(1) 1 0 2 0 3 0 4 0 !
# D=1; !
#ma [op=fft; b=1; nx=2; em=1;]
# D=0.25; !
#ma [op=fft; b=1; nx=-2; em=1;]
#pr \G r(1) r(3) r(5) r(7);\n\E
Прямое и обратное преобразования с множителем 1/N возвращают 1 2 3 4.
mcg — свёртка с гауссианой
#ma [op=mcg; n=; b=; nx=; ny=; file=; form=; sav=;]
Матрица nx × ny (обе размерности — степени двойки; ny=1 — одномерный
случай) сворачивается с гауссианой методом двойного БПФ. Три числа с r(n):
σx, σy (в шагах сетки) и ε.
ε |
Что делается с Фурье-образом каждой строки/столбца |
|---|---|
| 0 | умножается на G(q) = exp(−(σq)²/2) — свёртка (размытие) |
| > 0 | умножается на 1/√(G² + ε²) — развёртка с регуляризацией |
Если σx или σy равно нулю, по этому направлению ничего не делается.
Источник: file — файл чисел float (4 байта) или here — r(b)…; результат:
form — файл float или here — r(sav)…. Перед преобразованием из каждой
строки вычитается среднее её крайних значений, а потом прибавляется обратно —
это уменьшает краевые эффекты.
vsm — специальные вычисления
#ma [op=vsm; mo=; b=; le=; nx=; ny=; top=; n=;]
Набор независимых процедур для больших массивов, выбираемых параметром mo.
mo |
Что делает | Данные | Результат |
|---|---|---|---|
| 1 | убирает шум около среднего 1: значения, отличающиеся от 1 меньше чем на E = top·10⁻⁹, становятся ровно 1, к остальным прибавляется константа, чтобы среднее снова было 1 |
вектор b, le |
на месте |
| 2 | убирает «плохие» пиксели и шум детектора (см. ниже) | матрица b, nx, ny; le, top |
на месте |
| 3 | три наибольших значения | вектор b, le |
r(1)…r(6): пары «смещение от начала, значение», третий по величине первым |
| 4 | n наибольших значений |
вектор b, le; n |
r(1)…r(2n): пары «смещение, значение», наибольшее первым |
| 5 | сглаживание по трём точкам: x → x/2 + (левый + правый)/4 в каждой строке; линейная функция не меняется |
матрица b, nx, ny |
на месте; крайние точки строки копируют соседние |
| 6 | пять сечений квадратной матрицы: горизонталь и вертикаль через середину, две диагонали и окружность диаметром N/2 |
матрица N × N с r(b), N = le |
5 строк по N чисел с r(n) |
| 7 | x → arctg(x) |
вектор b, le |
на месте |
Режим 2 обрабатывает строки матрицы по очереди. При top>0 сравниваются
соседние числа: если разность больше top, аномальное число заменяется
полусуммой соседей. При top<0 в окне из le точек (не меньше трёх)
ищется максимум, и если он превышает среднее остальных больше чем на |top|,
заменяется средним. При top=0 все числа заменяются скользящими средними по
le точкам, то есть шум сглаживается. Крайние числа строк остаются прежними.
Тонкости. Режимы 3 и 4 всегда пишут результат в начало r(), а смещения
в них отсчитываются с нуля. В справочнике автора для mo=6 перепутаны роли
параметров: на деле матрица берётся с r(b), а сечения пишутся с r(n).
Изображения детекторов
Обе операции читают 16-битовое изображение из файла: file — имя, le —
размер заголовка в байтах, twi, the — ширина и высота в пикселях, ord —
порядок байтов (0 — старший первым, иначе младший первым).
smh — поиск фокуса
#ma [op=smh; file=; le=; twi=; the=; ord=; b=; bot=; em=; top=;]
Из каждого пикселя вычитается фон bot (отрицательное становится нулём).
Максимум ищется по сумме квадрата 3×3, без полосы в 5 пикселей у краёв.
| Результат | Значение |
|---|---|
r(b), r(b+1) |
координаты максимума, номера пикселей с нуля |
r(b+2) |
значение в максимуме |
r(b+3), r(b+4) |
полная ширина на половине высоты по x и по y |
r(b+5), r(b+6) |
левая и нижняя границы этих полуширин |
с r(b+7) |
при em=1 или 3 — профиль по x через максимум: сначала число точек, затем значения; при em=2 или 3 — следом профиль по y |
При top>0 профили усредняются по полосе шириной 2·top+1 пикселей. Автор
описывает только первые пять чисел; остальное видно из кода.
rfh — фрагмент изображения
#ma [op=rfh; file=; le=; twi=; the=; ord=; b=; wid=; hei=; xsh=; ysh=;]
Вырезает прямоугольник wid × hei, левый нижний угол которого — пиксель
(xsh, ysh) (считая с единицы; изображение трактуется как записанное снизу
вверх), и пишет его в r(b)… по строкам. Фрагмент шириной или высотой 1 —
кусок строки или столбца.
box — разметка осей
#ma [op=box; wid=; hei=; sty=; bot=; top=; uni=; b=;]
Вычисляет всё, что нужно, чтобы нарисовать прямоугольник осей научного
графика средствами #eg — так же, как это делают #w [op=pf;] и
#g [op=axes;], но с возможностью дальше рисовать самому.
Входные данные: размер области осей wid, hei; вид осей и длины рисок
sty, bot, top (как в #w); с r(b) — четыре числа xmi xma fmi fma при uni=0 (автоматическая разметка) или одиннадцать чисел ручной
разметки при uni≠0.
| Результат | Значение |
|---|---|
i(1) |
N — число точек ломаных линий осей и рисок |
i(2) |
M — число подписей-чисел |
r(1)…r(2N) |
координаты точек x1 y1 x2 y2 … |
i(3)…i(N+1) |
видимость отрезков: 1 — соединить точку с следующей, 0 — нет |
с r(2N+1) |
по четыре числа на подпись: координаты, само число, ось (0 — левая, 1 — нижняя, 2 — правая, 3 — верхняя) |
с r(2N+4M+1) |
xbeg cx ybeg cy — начала осей и масштабы для пересчёта функции в координаты рисунка |
Тонкость. Результат всегда пишется в начало r() и i(), затирая то,
что там было. Входные данные берите подальше. Пример использования —
суперкоманда ##pfFCH автора.
Система шаров
Три операции без описания в справочнике автора; их смысл восстановлен по
коду. Они моделируют движение N одинаковых шаров на плоскости — основу
простых анимаций и игр. Каждый шар — четыре числа x y vx vy, шары лежат
подряд с r(1); число шаров — в переменной N.
op |
Что делает |
|---|---|
bsm |
шаг движения: x += vx, y += vy для каждого шара |
bsi |
столкновения: шары, центры которых ближе диаметра D, раздвигаются вдоль линии центров на расстояние D+1 и обмениваются составляющими скоростей вдоль этой линии (упругий удар равных масс) |
bsr |
отражение от стенки-ломаной: точки (x, y) лежат с r(K), отрезков N1; шар радиуса D/2, оказавшийся ближе к отрезку, выталкивается на расстояние D/2, а его скорость отражается от отрезка |
Стенки односторонние: шар удерживается с той стороны отрезка, куда смотрит
нормаль (dy, −dx) к направлению (dx, dy) от первой точки ко второй.
Например, отрезок от (20, 0) до (0, 0) держит шары в области y > 0, а
отрезок от (0, 0) до (20, 0) — в области y < 0; шар, оказавшийся не с
той стороны ближе D, будет перенесён сквозь стенку. Для каждого шара
учитывается только первый задевший его отрезок.
Два шара летят навстречу друг другу и отскакивают.
# s(3)=1; N=2; D=10; !
#d 8 r(1) 0 0 1 0 15 0 -1 0 !
#rep 5 #ma [op=bsm;] #ma [op=bsi;] #end
#pr x1=\G r(1); vx1=\G r(3); x2=\G r(5); vx2=\G r(7);\n\E
После пяти шагов первый шар в точке 1 летит влево (vx1=−1), второй в точке
16 — вправо.
#z — zip-архивы
#z [op=xxx; file=архив; n=; mo=;] имя1\E имя2\E ...
Команда показывает содержимое zip-архива, упаковывает в архив папки или
отдельные файлы и распаковывает их. Значимы три буквы op; неизвестная
операция — ошибка 51.
op |
Что делает | Аргументы |
|---|---|---|
cat |
каталог архива в t() |
нет |
sfo |
упаковать папки | n имён папок |
gfo |
распаковать папки | n имён папок |
sfi |
упаковать файлы | n имён файлов |
gfi |
распаковать файлы | n имён файлов |
| Параметр | Смысл |
|---|---|
file |
имя архива от папки интерпретатора (рабочая папка не используется), с расширением; расширение может быть любым |
n |
число аргументов-имён |
mo |
режим распаковки для gfo, gfi |
Имена папок и файлов в аргументах тоже отсчитываются от папки интерпретатора;
внутри архива они хранятся в виде папка/файл. Для cat, gfo, gfi архив
должен существовать (ошибка 69).
mo |
Режим распаковки |
|---|---|
| 0 | распаковать, заменив существующие файлы; недостающую папку создать |
| 1 | распаковать временно: файлы и созданные папки удаляются при закрытии интерпретатора |
| 2 | распаковать, только если папки (для gfi — файла) ещё нет; удобно для первого запуска дистрибутива |
cat — каталог
#z [op=cat; file=архив;]
Записывает в t() с позиции s(3) имена всех элементов архива через |;
s(4), s(5) — начало и длина. Файлы в папках выглядят как папка/файл,
сами папки — как папка/.
Тонкость. Для архива без единого элемента интерпретатор падает с исключением Java.
sfo — упаковать папки
#z [op=sfo; file=архив; n=;] папка1\E папка2\E ...
Создаёт архив из всех файлов перечисленных папок. Вложенные папки не
обрабатываются: по коду интерпретатора попытка прочитать подпапку как файл
обрывает упаковку. Папки с подпапками упаковывайте через sfi, перечислив
файлы.
gfo — распаковать папки
#z [op=gfo; file=архив; n=; mo=;] папка1\E папка2\E ...
Извлекает файлы, лежащие непосредственно в каждой из названных папок архива.
Вложенную папку one/two можно извлечь, только когда внешняя one уже
существует: сначала извлеките one, затем отдельной командой one/two. Имя
null означает файлы из корня архива.
sfi — упаковать файлы
#z [op=sfi; file=архив; n=;] имя1\E имя2\E ...
Создаёт архив из перечисленных файлов. Имя вида папка/файл создаёт папку
внутри архива. Отсутствующие файлы пропускаются. Удобно и для сжатия одного
большого файла.
gfi — распаковать файлы
#z [op=gfi; file=архив; n=; mo=;] папка/файл1\E ...
Извлекает перечисленные элементы архива на те же относительные пути. Если нет последней папки пути, она создаётся; внешние папки должны существовать.
#z [op=sfi; file=pro/backup.zip; n=2;] pro/a.acl\E pro/b.acl\E
# s(3)=1; !
#z [op=cat; file=pro/backup.zip;]
#m [op=txt;] \Tp\n\E
#sys — секундомер и внешние программы
#sys [op=xx; file=;] [командная строка\E]
Команда для системно-зависимых действий. Значимы две буквы op;
неизвестная операция — ошибка 49.
op |
Что делает | Результат |
|---|---|---|
st |
запомнить время («включить секундомер») | — |
gt |
время, прошедшее после st |
$ в секундах |
rp |
запустить внешнюю программу или командный файл | — |
st — старт секундомера
#sys [op=st;]
Запоминает текущее время системных часов.
gt — показание секундомера
#sys [op=gt;]
Записывает в переменную $ время в секундах, прошедшее после последнего
st, с точностью до миллисекунды. Можно вызывать несколько раз подряд.
# s(3)=1; !
#sys [op=st;]
#rep 100000 # a=sin(1); #end
#sys [op=gt;]
#pr цикл занял \N 8 3 $; с\n\E
Так оценивают время большого расчёта по одному прогону.
rp — запуск программы
#sys [op=rp; file=имя;]
#sys [op=rp; file=arg;] командная строка\E
file |
Что запускается |
|---|---|
| имя | исполняемый файл или командный файл .bat от папки интерпретатора; файл должен существовать (ошибка 50) |
arg |
командная строка из аргумента — любая программа с аргументами; наличие файла не проверяется |
Программа запускается в отдельном процессе, и VKACL-программа сразу идёт
дальше, не дожидаясь её конца. Если дальше нужны результаты внешней
программы, программу останавливают: окном #m [op=win;],
которое ждёт нажатия, или паузой #rob [mo=1;].
# s(3)=1; !
#pr C:\ncd "Program Files"\\Tetcolor\nTetColor.exe\n\E
# n9=s(3)-1; !
#io [op=wt; fir=t(1); n=n9; file=runpro.bat;]
#sys [op=rp; file=runpro.bat;]
Командный файл, собранный прямо из программы, обходит требование держать запускаемую программу в папке интерпретатора. В Linux файлу нужно дать атрибут исполняемого.
#m — сообщения и окна с кнопками
#m [op=xxx;] текст\E [ещё аргументы\E]
Команда показывает текст пользователю: в окне терминала или в диалоговом окне
с кнопками. Первый аргумент — форматированный текст —
читается всегда, при любой операции. Операцию задают три буквы op,
причём они должны точно совпасть с одной из перечисленных (op=text — это
ошибка 37, нужно op=txt).
op |
Что показывает | Ждёт пользователя | Результат |
|---|---|---|---|
txt |
текст в окне терминала | нет | — |
rtt |
стирает символы в конце терминала | нет | — |
win |
окно с кнопкой OK | да | — |
yno |
окно с кнопками Yes, No | да | & |
oce |
окно с кнопками OK, Cancel, Edit | да | & |
uni |
окно со своим заголовком и кнопками | да | & |
gen |
окно с кнопками в несколько рядов и настраиваемой раскладкой | да | & |
В окнах yno, oce и uni, закрытых крестиком, & становится равным 0.
txt — терминал
#m [op=txt;] текст\E
Дописывает текст в окно «Терминал», сопровождающее программу. Окно
появляется при первой записи и закрывается после конца программы; чтобы оно
осталось на экране, перед концом программы выполните
#rob [mo=2;]. Обычная связка — собрать текст в t() и показать
его кодом \Tp или \T:
# s(3)=1; x=3.14159; !
#pr x = \G x;\n\E
#m [op=txt;] \Tp\E
rtt — стереть конец терминала
#m [op=rtt; n=;] \E
Удаляет n последних символов терминала. Аргумент не используется, но
должен присутствовать хотя бы как пустой \E. Так делают обратный отсчёт:
печатают строку символов и стирают по одному по мере работы цикла.
win — сообщение
#m [op=win;] текст\E
Показывает текст в окне с кнопкой OK и ждёт, пока пользователь её нажмёт. Годится и как простая пауза «продолжить».
yno — да или нет
#m [op=yno;] вопрос\E
Кнопки Yes и No; & — 1 или 2.
#m [op=yno;] Сохранить результат?\E
#case 1
#io [op=wd; fir=r(1); n=100; mo=3; file=result.dat;]
#end |
oce — OK, Cancel, Edit
#m [op=oce;] текст\E
Кнопки OK, Cancel, Edit; & — 1, 2 или 3.
uni — свои кнопки
#m [op=uni;] текст\E заголовок|кнопка1|кнопка2|...\E
Второй аргумент задаёт через | заголовок окна и надписи кнопок; кнопок
столько, сколько надписей. Все кнопки в один ряд; & — номер нажатой, с
единицы.
#m [op=uni;] Что построить?\E Выбор|График|Карта|Выход\E
gen — окно общего вида
#m [op=gen; b=; n=; nx=; ny=; siz=;] заголовок\E текст\E кнопка1|кнопка2|...\E
Кнопки размещаются в n рядов. Строки текста разделяются \n; пустую строку
задают как \u32;\n, потому что совсем пустые строки не допускаются.
Раскладку задают целые числа в i(b), i(b+1), …:
| Числа по порядку | Сколько | Смысл |
|---|---|---|
| первые | по одному на строку текста | ширина пустого места после строки (строки центрируются; удлиняя короткие строки справа, их выравнивают влево); можно нули |
| следующие | n |
сколько кнопок в каждом ряду; в сумме — все кнопки |
| последние | n |
ширина полей слева и справа в каждом ряду кнопок |
| Параметр | Смысл |
|---|---|
nx, ny |
левый верхний угол окна от угла экрана; если хоть один отрицателен — окно по центру |
siz |
поля по краям окна, куда не заходят ни текст, ни кнопки |
& — номер нажатой кнопки. Упрощённый вариант с одним рядом кнопок —
суперкоманда ##33.
#sel — таблица кнопок
#sel [nx=; ny=; mo=; wid=; hei=; tfo=; tki=; tsi=; col=; em=; xsh=; ysh=;] заголовок\E кнопка1|кнопка2|...\E
Команда показывает панель с прямоугольной таблицей кнопок и ждёт, пока
пользователь нажмёт одну из них. Номер нажатой кнопки попадает в &, и
обычно за командой следует серия #case … #end |. Одна из самых
употребительных команд диалога.
| Параметр | Смысл |
|---|---|
nx |
кнопок в ряду |
ny |
рядов |
mo |
вид кнопок: 0 — текст на цветном прямоугольнике; 1 — картинки jpg; 2 — картинки png; 3 — картинки png внутри интерпретатора (для проигрывателя) |
wid, hei |
размер текстовой кнопки в пикселях |
tsi |
размер шрифта (не меньше 8) |
tfo |
шрифт 1…5: Monospaced, Serif, SansSerif, Dialog, DialogInput |
tki |
начертание: 0 обычное, 1 жирное, 2 наклонное, 3 жирное наклонное |
col |
для mo=0: номер цвета текста в таблице цветов; следующий номер — цвет фона |
em |
0 — панель по центру экрана; 1 — левый верхний угол в (xsh, ysh) от угла экрана; 2 — от угла главного окна программы |
Кнопки заполняют таблицу по рядам: сначала первый ряд, потом второй. Для
mo=1 и mo=2 надписи — это имена файлов картинок без расширения в рабочей
папке (можно папка/файл); для mo=3 — имена внутри папки com.vk jar-файла.
| Результат | Значение |
|---|---|
& |
номер нажатой кнопки с единицы; −1, если панель закрыта крестиком |
#sel [nx=3; ny=1; mo=0; wid=120; hei=40; tsi=16; tfo=3; tki=1; col=255; em=0;] Что делать?\E График|Таблица|Выход\E
#case 1 #m [op=txt;] Выбран график\n\E #end |
#case 2 #m [op=txt;] Выбрана таблица\n\E #end |
Тонкости.
- По умолчанию
col=1, а цвета 1 и 2 — чёрные: надписи на кнопках не видны. Цвет 255 (тёмно-синий) с фоном 256 (светло-коричневый) — сочетание, которое автор называет стандартным. - Надписи нужно перечислить для всех
nx·nyкнопок, даже пустых. - Если заголовок — слово
null, окно показывается без рамки, и закрыть его можно только кнопкой, которую должна предусмотреть сама программа. - После
em=1илиem=2вернитеem=0: этот параметр читают многие команды.
#inp — окна ввода
#inp [n=; le=; mo=; em=; xsh=; ysh=;] заголовок\E подписи-и-тексты...
Команда открывает панель с n однострочными окнами ввода, у каждого своя
подпись и начальный текст, и кнопками OK и Cancel. После OK тексты всех окон
записываются в t().
Аргументы
Первый аргумент — заголовок панели. Дальше — в зависимости от чётности mo:
mo |
Аргументы после заголовка |
|---|---|
| чётное (0, 2, …) | n пар: подпись\E текст\E подпись\E текст\E … |
| нечётное (1, 3, …) | два аргумента: все подписи через | и все начальные тексты через |; если частей меньше n — ошибка 61 |
При n=0 панель вводит пароль: одно окно без подписи, вместо символов
показываются звёздочки, аргумент только один — заголовок.
Параметры
| Параметр | Смысл |
|---|---|
n |
число окон ввода; 0 — ввод пароля |
le |
ширина пустого места по бокам от кнопок; этим задаётся ширина всей панели (обычно около 50) |
mo |
раскладка, см. ниже |
em |
единицы: 0 — панель по центру, 1 — угол в (xsh, ysh) от угла экрана, 2 — от угла главного окна; десятки: 1 — добавить ряд кнопок Help, Notes, Save Var, Choose Var |
mo |
Раскладка |
|---|---|
| 0, 1 | подпись над окном, все в один столбец; кнопки по центру |
| 2, 3 | подпись и окно в одной строке, один столбец; кнопки слева |
| 4, 5 | то же, кнопки справа |
| 6, 7 | два столбца (n чётное) |
| 8, 9 | три столбца (n делится на 3) |
| больше 9 | по 4, 5 … пары в строке, без выравнивания столбцов |
Результат
| Где | Значение |
|---|---|
& |
1 — OK, 2 — Cancel, 3…6 — кнопки Help, Notes, Save Var, Choose Var |
t() с s(3) |
тексты всех окон, после каждого символ с кодом 10 (не пишется при Cancel) |
s(4), s(5) |
начало записи и её длина вместе с символами 10 |
Для одного окна или пароля сам текст занимает s(5)−1 символов. Кнопки
дополнительного ряда только сообщают о намерении пользователя через & —
справку, заметки и сохранение вариантов программа делает сама.
# s(3)=1; !
#inp [n=2; le=50; mo=3; em=0;] Размер картинки\E Ширина|Высота\E 640|480\E
#case 1
#rea [fir=r(1); n=2; b=s(4); le=s(5);]
#end |
Числа из окон ввода превращаются в значения командой
#rea: символ 10 между ними служит разделителем.
Тонкости. Имя команды пишется минимум тремя буквами: #in попадает в
#w. После em≠0 верните em=0. Автор сам теперь предпочитает вводить
данные через текстовый редактор (#f [op=edit;]) — такой
ввод проще сохранять и править.
#ch — выбор кликом по картинке
#ch [n=; xsh=; ysh=;]
Команда показывает картинку из памяти без рамки и ждёт, пока пользователь кликнет по ней мышью или нажмёт клавишу. Затем картинка исчезает, а программа получает координаты клика и код клавиши.
| Параметр | Смысл |
|---|---|
n |
номер картинки в памяти, 1…100 (нет картинки — ошибка 63) |
xsh, ysh |
левый верхний угол картинки от левого верхнего угла экрана |
| Результат | Значение |
|---|---|
s(102), s(103) |
координаты курсора в момент клика, от левого нижнего угла картинки |
s(1) |
модификатор клика: 16 — простой клик, 17 — с Shift, 18 — с Ctrl и т. д. |
s(2) |
код нажатой клавиши |
Таблицы модификаторов и кодов клавиш — в описании
#w [op=im;].
Команда даёт выбор общего вида: на картинке может быть инструкция «нажмите
клавишу», карта, по которой кликают, или таблица кнопок любой формы (например,
таблица Менделеева). Анализ координат программа делает сама; готовую таблицу
прямоугольных кнопок проще получить командой #sel.
#g [op=open; twi=300; the=100; col=256;]
#g [op=text; nx=150; ny=45; col=255; tfo=3; tki=1; tsi=18; sty=2;] Нажмите Y или N\E
#g [op=close; sav=9;]
#ch [n=9; xsh=200; ysh=200;]
# kc=s(2); !
Клавиши букв дают коды заглавных латинских букв: Y — 89, N — 78.
#fr — картинка поверх экрана
#fr [op=o; n=; mo=; xsh=; ysh=;] [заголовок\E]
#fr [op=c; mo=;] [заголовок\E]
Команда выставляет на экран картинку, заранее сохранённую в памяти (номер
1…100; сохраняют её #w, #g, #eg), не
останавливая программу, и убирает её программно, без участия пользователя.
Так показывают комментарии рядом с окнами диалога, строку состояния,
сообщения о ходе расчёта. Операцию задаёт одна буква: o — открыть, c —
закрыть; другая — ошибка 78.
| Параметр | Смысл |
|---|---|
n |
номер картинки в памяти (нет картинки — ошибка 63) |
mo |
0 — внутреннее окно с рамкой и заголовком внутри главного окна интерпретатора; 1…10 — окно без рамки номер mo |
xsh, ysh |
левый верхний угол от левого верхнего угла экрана (для mo=0 — главного окна) |
o — показать
При mo=0 аргумент — заголовок внутреннего окна; такое окно живёт внутри
главного окна интерпретатора и вместе с ним сворачивается. В проигрывателе
(версии без главного окна) этот вариант не работает. При mo от 1 до 10
картинка показывается анонимно, без рамки и заголовка; аргумент не нужен.
Одновременно можно держать до 10 таких картинок, в том числе одну поверх
другой.
c — убрать
При mo=0 аргумент — заголовок: закрываются внутренние окна с этим
заголовком. При mo>0 убирается анонимная картинка номер mo.
Нарисовать строку состояния и показать её внизу экрана.
# s(3)=1; y=s(107)-60; !
#g [op=open; twi=400; the=30; col=256;]
#g [op=text; nx=10; ny=8; col=255; tfo=3; tki=0; tsi=16; sty=1;] Идёт расчёт...\E
#g [op=close; sav=7;]
#fr [op=o; n=7; mo=1; xsh=20; ysh=y;]
#rep 100000 # a=sin(1); #end
#fr [op=c; mo=1;]
Тонкости. Размер экрана — в s(106) и s(107). Анонимная картинка не
должна перекрывать окна анимации или диалога: кликнув по ней, пользователь
уводит фокус, и программа может потерять управление. Готовая подсказка в
строке состояния — суперкоманда ##17.
#pf — индикатор хода работы
#pf [op=o; le=;]
#pf [op=m; siz=;]
#pf [op=c;]
Команда открывает окно «Progress» с полосой, которая постепенно закрашивается, и процентом выполнения посередине. Долгий расчёт без такого окна выглядит как зависание. Операцию задаёт одна буква; другая — ошибка 84.
op |
Что делает | Параметр |
|---|---|---|
o |
открыть окно (всегда в центре экрана) | le — значение, соответствующее 100 % |
m |
закрасить полосу до значения siz и показать siz/le·100 % |
siz — от 0 до le; выходящее за пределы прижимается к границе |
c |
закрыть окно | — |
# k=0; !
#pf [op=o; le=999;]
#rep 1000
# r(k+1)=exp(-0.001*k); k=k+1; !
#pf [op=m; siz=k;]
#end
#pf [op=c;]
#pf [op=o;] ставят перед циклом, #pf [op=m;] — внутри, #pf [op=c;] —
после.
#rob — пауза, снимок экрана, цвет пикселя
#rob [mo=; le=; n=; xsh=; ysh=; wid=; hei=;]
Когда-то команда имитировала действия пользователя (нажатия клавиш, движение
мыши). Эти функции автор убрал, оставив имя ради совместимости и несколько
полезных действий. Операцию выбирает не op, а mo.
mo |
Что делает | Параметры | Результат |
|---|---|---|---|
| 1 | пауза | le — длительность в миллисекундах |
— |
| 2 | не закрывать окно терминала после конца программы | — | — |
| 3 | снимок части экрана в память | n — номер картинки, xsh, ysh — левый верхний угол, wid, hei — размер |
картинка n |
| 4 | цвет пикселя экрана | xsh, ysh — координаты |
s(1), s(2), s(3) — красный, зелёный, синий |
Другие значения mo ничего не делают.
#m [op=txt;] Подождите две секунды...\n\E
#rob [mo=1; le=2000;]
#rob [mo=2;]
Пауза нужна при анимации из заранее сохранённых кадров, после запуска внешней
программы через #sys и в слайд-шоу. Снимок экрана (mo=3) затем
можно показать, дорисовать или сохранить в файл командами #w,
#g, #f [op=topng;].
Тонкость. mo=4 записывает синюю компоненту в s(3) — позицию печати в
t(). Сразу сохраните цвет и восстановите s(3):
#rob [mo=4; xsh=100; ysh=100;]
# cr=s(1); cg=s(2); cb=s(3); s(3)=1; !
#col — таблица цветов
#col [b=; le=; fir=;]
Графические команды задают цвет не тремя компонентами, а номером в
таблице из 256 цветов. Команда #col переопределяет le цветов подряд,
начиная с номера b; компоненты — 3·le чисел (красный, зелёный, синий)
подряд, начиная с элемента fir.
| Параметр | Смысл |
|---|---|
b |
номер первого переопределяемого цвета, от 1 (меньше — ошибка 17) |
le |
сколько цветов |
fir |
первый элемент с компонентами: i(1), r(1) или скалярная переменная |
Компоненты отбрасывают дробную часть и прижимаются к диапазону 0…255. Таблицу можно менять в любой момент.
#d 6 i(1) 255 0 0 122 122 122 !
#col [b=2; le=2; fir=i(1);]
Теперь цвет 2 — красный, цвет 3 — серый.
Таблица при запуске
| Номер | RGB | Цвет |
|---|---|---|
| 1…243 | 0 0 0 | чёрный |
| 244 | 128 0 0 | тёмно-красный |
| 245 | 85 85 85 | тёмно-серый |
| 246 | 255 255 255 | белый |
| 247 | 0 0 0 | чёрный |
| 248 | 255 0 0 | красный |
| 249 | 0 0 255 | синий |
| 250 | 0 195 0 | зелёный |
| 251 | 122 122 122 | серый |
| 252 | 152 128 0 | коричневый |
| 253 | 152 0 152 | фиолетовый |
| 254 | 0 255 255 | голубой |
| 255 | 0 0 128 | тёмно-синий |
| 256 | 220 200 180 | светло-коричневый |
Где используется
Параметр col в команде |
Что красит |
|---|---|
#g, #eg |
фон при открытии графика, линии, фигуры, текст |
#w [op=pf;] |
первую кривую; следующие кривые — следующими номерами |
#sel |
текст кнопок (col) и их фон (col+1) |
#f [op=tobm;] |
веса каналов при переводе картинки в серый |
#pd, #ps |
текст и линии в PDF и EPS |
Цветные карты числовых матриц красятся не этой таблицей, а палитрой pal
(см. #w [op=im;]).
Тонкость. В справочнике автора цвет 251 назван как 128 128 128; в
интерпретаторе он 122 122 122.
#w — картинки и научные графики
#w [op=xx; file=; form=; sav=; c=; ...] [аргументы]
Команда показывает готовые картинки (gif, jpg, png), превращает числовые
матрицы в серые и цветные карты и строит научные графики: кривые в осях,
квази-трёхмерные графики, карты в осях, составные картинки. Результат
показывается в окне, сохраняется в память под номером или записывается в
файл jpg. Операцию задают две буквы op; неизвестная — ошибка 29.
op |
Что строит |
|---|---|
im |
картинку из файла, памяти или интернета; карту числовой матрицы |
pf |
график функций в осях с подписями |
mp |
квази-трёхмерный график: строки матрицы — кривые, сдвинутые друг за другом |
mm |
картинку (обычно карту) в прямоугольнике осей с подписями |
ff |
составную картинку из нескольких картинок памяти |
Более гибкое рисование — в #g и #eg, векторные
графики — в #ps.
Общие правила
Файл. Параметр file проверяется до выполнения любой операции: файл
должен существовать в рабочей папке, либо имя должно быть here, либо
начинаться с & (файл внутри jar-файла). Иначе — ошибка 13. Поэтому для
картинок из памяти, из интернета и для ff пишите file=here. Если
file=arg или form=arg, имена берутся из аргументов (сначала для file,
потом для form) до остальных аргументов операции.
Куда девается картинка — одинаково для #w, #g, #eg:
sav |
Что происходит |
|---|---|
| 1…100 | картинка сохраняется в память под этим номером, на экран не выводится |
| 0 | показывается в окне |
| −1 | показывается и записывается в файл form.jpg в рабочей папке |
| −2 | только записывается в файл form.jpg |
form — имя без расширения. Заголовок окна у im, pf, mp, mm — имя
файла из file, у ff — аргумент.
| Параметр окна | Смысл |
|---|---|
c |
0 — показать и сразу идти дальше; иначе ждать, пока пользователь кликнет по картинке или нажмёт клавишу |
em |
0 — окно по центру экрана; 1 — левый верхний угол окна в точке (xpo, ypo) от угла экрана |
| Ячейка | Значение |
|---|---|
s(1) |
модификатор клика |
s(2) |
код клавиши, если окно закрыто клавиатурой |
s(102)…s(105) |
x1 y1 x2 y2 — точки нажатия и отпускания кнопки мыши, если по картинке протянули мышь (так выделяют область) |
| Модификатор | Клик |
|---|---|
| 16 | простой |
| 17 | с Shift |
| 18 | с Ctrl |
| 19 | с Shift и Ctrl |
| 24 | с Alt |
| 25 | с Alt и Shift |
| 26 | с Alt и Ctrl |
| 27 | с Alt, Ctrl и Shift |
| Клавиша | Код |
|---|---|
цифры 0…9 |
48…57 |
буквы A…Z (любой регистр) |
65…90 |
, - . / |
44, 45, 46, 47 |
; = [ \ ] |
59, 61, 91, 92, 93 |
', ` |
222, 192 |
| Backspace, Enter, CapsLock, Esc, пробел | 8, 10, 20, 27, 32 |
| PgUp, PgDn, End, Home | 33, 34, 35, 36 |
| стрелки влево, вверх, вправо, вниз | 37, 38, 39, 40 |
| F1…F12 | 112…123 |
| Insert, Delete | 155, 127 |
Tab, Shift, Ctrl и Alt сами по себе окно не закрывают. Коды клавиш удобны для слайд-шоу: следующая картинка — по пробелу, выход — по Esc.
im — картинка или карта
#w [op=im; file=; mo=; n=; twi=; the=; wid=; hei=; xsh=; ysh=; sca=; sav=; form=; c=; em=;]
Источник картинки выбирает mo:
mo |
Источник | Что делается |
|---|---|---|
| 0 | файл gif, jpg, png | показывается как есть; s(12), s(13) — ширина и высота |
| 1 | такой же файл | масштабирование к twi × the и/или вырезание части |
| 2 | картинка памяти n |
масштабирование |
| 3 | картинка памяти n |
вырезание части |
| −1 | адрес в интернете из аргумента | показывается как есть |
| 8, 16, 24, 32, 100, 125 | числовые данные | карта, см. ниже |
Масштабирование (mo 1, 2) выполняется, если хотя бы одно из twi,
the положительно; отрицательное вычисляется так, чтобы сохранить пропорции.
Способ задаёт sca: 1 — по умолчанию, 2 — быстрый, 4 — сглаживающий,
8 — повтор пикселей, 16 — усреднение по площади. После операции s(12),
s(13) — новый размер.
Вырезание (mo 1, 3) выполняется, если wid, hei положительны, а
xsh, ysh неотрицательны: показывается часть wid × hei, левый нижний
угол которой отстоит на (xsh, ysh) от левого нижнего угла картинки. Часть,
вылезающая за край, обрезается.
Тонкость. sca — это ещё и масштаб в процентах у #g, по умолчанию он
равен 100, а у #w допустимы только 1, 2, 4, 8, 16. Масштабирование с
sca=100 — ошибка 71: задавайте sca явно.
#w [op=im; file=photo.jpg; mo=1; twi=400; the=-1; sca=4; sav=0; c=1; em=0;]
# kc=s(2); !
Карты числовых данных
mo |
Данные в файле | Значение пикселя |
|---|---|---|
| 8 | байт на точку | сам байт — уровень серого 0…255 |
| 16 | два байта на точку, без знака; порядок задаёт ord (0 — старший первым) |
масштабирование в серый |
| 24 | три байта на точку: красный, зелёный, синий | цвет как есть |
| 32 | число float (4 байта) на точку; при file=here — числа из r(le)… |
масштабирование в серый |
| 100 | данные не читаются, а вычисляются: линейная шкала от r(b) до r(b+1) (нужно file=here) |
масштабирование в серый |
| 125 | один бит на точку, 8 точек в байте (сканы страниц) | чёрный или белый |
| Параметр | Смысл |
|---|---|
le |
размер заголовка файла в байтах (при mo=32, file=here — первый индекс r()) |
twi |
полная ширина данных в точках |
the |
полная высота |
wid, hei |
размер показываемой части; у mo=100 один из них должен быть 1 (ошибка 46) |
xsh, ysh |
сдвиг показываемой части от начала данных |
dir |
1 — строки записаны сверху вниз, иначе снизу вверх (как в расчётах) |
nx, ny |
сколько пикселей экрана по горизонтали и вертикали отводить на точку данных |
sty, bot, top, b |
масштабирование в серый, см. ниже |
sca |
только для mo=125: масштаб в процентах (обычно уменьшение) |
pal |
палитра, см. ниже |
Масштабирование в серый (mo 16, 32, 100). Пусть Fmin, Fmax —
наименьшее и наибольшее значения. Для mo=100 они всегда берутся из r(b),
r(b+1); для 16 и 32 — оттуда же, если |sty| > 10, а иначе вычисляются по
данным и записываются в r(b), r(b+1). Показывается окно значений
Fmi = Fmin + (Fmax − Fmin)·bot/100000
Fma = Fmin + (Fmax − Fmin)·top/100000
а вид шкалы задаёт последняя цифра |sty|:
| Цифра | Шкала |
|---|---|
| 1 | линейная: 255·(f − Fmi)/(Fma − Fmi) |
| 2 | логарифмическая: 255·ln(f/Fmi)/ln(Fma/Fmi); нужно Fmi > 0, иначе ошибка 30 |
| 3 | корень: 255·√((f − Fmi)/(Fma − Fmi)) |
Отрицательный sty обращает контраст: минимум белый, максимум чёрный.
Палитра pal (параметр 44) превращает уровень 0…255 в цвет:
pal |
Цвета от минимума к максимуму |
|---|---|
| 0 и больше 3 | от чёрного к белому |
| 1 | синий → красный → белый |
| 2 | чёрный → синий → зелёный → красный → белый |
| 3 | из файла colmap.txt в папке интерпретатора: 768 целых чисел текстом — 256 красных, 256 зелёных, 256 синих; файл читается в момент рисования, поэтому палитру можно менять по ходу программы |
Пример автора — показать кусок 16-битного изображения детектора в формате
edf (параметры с c по sav — это s(8)…s(23), их удобно задать одной
командой #d):
#d 16 s(8) 1 1 3072 16 2048 2048 128 128 1408 968 -2 1 999 4 4 0 !
#w [op=im; file=any.edf;]
Здесь заголовок 3072 байта, данные 2048×2048, показывается часть 128×128 со сдвигом (1408, 968), шкала логарифмическая обращённая, каждая точка — квадрат 4×4 пикселя.
Тонкости.
- По умолчанию
top=0, и окно значений вырождается — картинка получается сплошь чёрной. Задавайтеbotиtopявно, например 1 и 99999. - Если последняя цифра
styне 1, 2 или 3, картинка тоже чёрная. - Для
mo16 и 32 без|sty|>10найденныеFmin,Fmaxзатираютr(b),r(b+1): направьтеbна свободное место.
pf — график функций
#w [op=pf; file=; b=; le=; mo=; nx=; ny=; col=; msi=; mki=; оси...; n=; sav=; form=; c=;] [Xmin Xmax] подписи...
Данные. Числа float из файла (после le байтов заголовка) или, при
file=here, из r(b)…. Данные идут столбцами по nx точек, столбцов ny:
mo |
Смысл столбцов | Кривых |
|---|---|---|
| 0 | все столбцы — функции; аргумент равномерный от Xmin до Xmax, это первые два аргумента команды |
ny |
| 1 | первый столбец — аргумент, остальные — функции | ny−1 |
| 2 | пары «аргумент, функция» | ny/2 |
Кривые. Первая рисуется цветом col, следующие — следующими номерами
таблицы цветов. При msi=0 все кривые — линии толщиной 1. При
msi>0 это размер маркеров в пикселях, а mki — пятизначное число, цифры
которого (слева направо) задают вид первых пяти кривых, дальше по кругу:
Цифра mki |
Вид |
|---|---|
| 0 | линия |
| 1 | пустой квадрат |
| 2 | залитый квадрат |
| 3 | пустой круг |
| 4 | залитый круг |
Например, mki=1234 (то есть 01234) — линия, пустой квадрат, залитый
квадрат, пустой круг, залитый круг.
Подписи. Их число — n; каждая задаётся аргументами x y rts текст\E:
левый нижний угол текста от левого нижнего угла картинки и добавка rts к
размеру шрифта tsi.
Фон графика белый, оси чёрные. Ошибки: 44 — nx·ny ≤ 0, 32 — файл меньше,
чем нужно, 68 — нулевой размер картинки, 43 — неверная ручная разметка осей.
Две гауссианы на одном графике, данные в r().
# x=-2; k=1; !
#rep 101
# r(k)=x; r(k+101)=100*exp(0-x*x); r(k+202)=80*exp(0-(x-0.5)*(x-0.5)); x=x+0.04; k=k+1; !
#end
#d 3 i(1) 255 0 0 !
#col [b=2; le=1; fir=i(1);]
#w [op=pf; file=here; b=1; le=0; mo=1; nx=101; ny=3; col=2; msi=0; twi=600; the=400; wid=480; hei=300; xsh=80; ysh=60; sty=1; bot=4; top=8; tsi=14; tfo=3; tki=0; uni=0; n=2; sav=0; c=1; em=0;] 300 15 2 x\E 20 375 2 Две гауссианы\E
Оси и подписи чисел
Этот способ описания осей общий для #w [op=pf;], #w [op=mm;],
#g [op=axes;], #ps [op=pf;] и
#ma [op=box;].
| Параметр | Смысл |
|---|---|
twi, the |
полный размер картинки в пикселях |
wid, hei |
размер прямоугольника осей |
xsh, ysh |
левый нижний угол прямоугольника осей от левого нижнего угла картинки |
bot, top |
длина коротких и длинных рисок |
tsi, tfo, tki |
размер, шрифт (1…5) и начертание (0…2) чисел на осях; tki=3 здесь сбрасывается в 0, хотя в #g оно означает жирный наклонный |
sty |
вид осей, пятизначное число lbrtm |
uni |
0 — разметка автоматически; иначе номер j элемента r() с ручной разметкой |
Цифры sty = lbrtm относятся к левой (l), нижней (b), правой (r) и
верхней (t) осям:
| Цифра оси | Ось |
|---|---|
| 0 | есть; числа у левой и нижней, у правой и верхней — нет |
| 1 | оси нет |
| 2 | есть; числа у правой и верхней, у левой и нижней — нет |
Последняя цифра m: 0 — риски внутрь, 1 — наружу. Так, sty=1 — все четыре
оси, числа слева и снизу, риски наружу; sty=11211 — только правая ось с
числами. Если риски внутрь, а длинные риски длиной в половину большей
стороны, получается сетка.
Ручная разметка (uni=j) — одиннадцать чисел с r(j):
| Элемент | Смысл |
|---|---|
r(j) |
единица функции: график показывает f/r(j) |
r(j+1), r(j+2) |
начало и конец оси x |
r(j+3) |
значение у первой длинной риски на x |
r(j+4) |
шаг между длинными рисками на x |
r(j+5) |
число коротких рисок между длинными на x |
r(j+6)…r(j+10) |
то же для оси y |
mp — квази-трёхмерный график
#w [op=mp; file=; le=; b=; nx=; ny=; twi=; the=; wid=; hei=; xsh=; ysh=; bot=; top=; trx=; try=; tsi=; tfo=; tki=; sav=; form=; c=;] xmi xma ymi yma
Матрица f(x, y) — ny строк по nx чисел float из файла (после le
байтов) или из r(b)… при file=here — рисуется как набор кривых: каждая
следующая строка сдвинута вправо и вверх и заслоняет невидимые части
предыдущих. Аргументы — пределы осей: xmi xma для первого аргумента (сетка
равномерная), ymi yma — для второго, он размечается на наклонной третьей
оси справа.
| Параметр | Смысл |
|---|---|
trx |
сдвиг следующей кривой вправо, в шагах сетки по x (обычно 1); при 0 рисуется замкнутый прямоугольник без третьей оси |
try |
сдвиг следующей кривой вверх, в тысячных долях максимума функции |
wid, hei, xsh, ysh |
размер и положение прямоугольника осей |
Числа на осях ставятся автоматически; подписей нет — их добавляют, сохранив
картинку в память и дорисовав командой #g. nx меньше 2 — ошибка
24.
mm — картинка в осях
#w [op=mm; file=; mo=; b=; uni=; twi=; the=; wid=; hei=; xsh=; ysh=; sty=; bot=; top=; tsi=; tfo=; tki=; n=; sav=; form=; c=;] подписи...
Ставит картинку (настоящую, а не числовую матрицу — матрицу сначала
превращают в картинку операцией im с сохранением в память) в центр
прямоугольника осей и размечает оси. Картинка берётся из файла или, при
file=here, из памяти под номером mo. При uni=0 пределы осей берутся из
r(b)…r(b+3): xmi xma fmi fma. Подписи — как у pf.
Тонкость. При ручной разметке первое из одиннадцати чисел (единица
функции) здесь не используется, но место под него нужно: если ваши десять
чисел разметки начинаются с r(j), задайте uni=j−1.
ff — составная картинка
#w [op=ff; file=here; n=; b=; sav=; form=; c=;] заголовок\E
Картинка памяти номер 1 — основа; на неё накладываются картинки 2…n.
Картинка номер k сдвигается на (i(b+2k−4), i(b+2k−3)) пикселей: по
горизонтали от левого края основы, по вертикали от нижнего края. Типичное
применение — карта и шкала серого к ней, полная картина и её сечения. Ту же
работу гибче делают #g и #eg.
Карта 200x200 в памяти 1, шкала 20x200 в памяти 2 справа от неё.
#d 2 i(1) 210 0 !
#w [op=ff; file=here; n=2; b=1; sav=0; c=1;] Карта со шкалой\E
#g — простая графика
#g [op=open; twi=; the=; col=;]
#g [op=фигура; ...] [текст\E]
#g [op=close; sav=; form=; c=;] [заголовок\E]
Команда рисует растровую картинку по шагам: открыть холст, нанести линии,
фигуры, тексты, готовые картинки, оси и графики функций, закрыть — показать,
сохранить в память или в файл. Координаты — целые пиксели от левого нижнего
угла холста (ось y вверх). Значимы три буквы op; неизвестная операция —
ошибка 52, рисование без открытого холста — ошибка 80, повторное открытие
без закрытия — ошибка 82. Не смешивайте открытые холсты #g и
#eg: интерпретатор хранит рисуемую картинку в одном месте, и
открытие второго холста подменяет первый.
op |
Что делает |
|---|---|
open |
новый холст |
cont |
продолжить рисование на картинке из памяти |
close |
закончить и показать или сохранить |
text |
строка текста |
line |
ломаная |
area |
многоугольник |
rect |
прямоугольник |
oval |
эллипс |
arc |
дуга или сектор эллипса |
image |
готовая картинка |
axes |
прямоугольник осей с числами и подписями |
rfun |
прочитать функции для графика |
dfun |
нарисовать функции в осях |
axon |
аксонометрия поверхности z(x, y) |
Сдвиг и масштаб всего рисунка
Три параметра позволяют переставить и масштабировать рисунок целиком, не меняя координаты в программе:
| Параметр | Смысл |
|---|---|
trx, try |
вектор, прибавляемый ко всем координатам |
sca |
масштаб в процентах (100 — без изменения); положительный масштабирует и размеры, и положения; отрицательный — только размеры объектов по модулю, положения не трогает |
Готовые картинки (image) и размеры осей не масштабируются.
Тонкость. sca использует и #w [op=im;], где он означает
способ масштабирования (1…16). После такого #w рисунок #g окажется
уменьшенным до нескольких процентов — задавайте #p [trx=0; try=0; sca=100;]
перед началом рисования.
open, cont, close
#g [op=open; twi=; the=; col=;]
Открывает холст twi × the пикселей, залитый цветом col из
таблицы цветов. Размеры читаются и при закрытии, и операциями
axes, dfun, поэтому до close менять twi и the нельзя. Команды,
которые их меняют (например, #w [op=im;] для загрузки картинки в память),
выполняйте до open.
#g [op=cont; n=;]
Открывает для рисования картинку памяти номер n (нет — ошибка 63).
#g [op=close; sav=; form=; c=; em=; xpo=; ypo=;] заголовок\E
Закрывает холст; судьба картинки — по правилам sav: номер
памяти, показ, файл form.jpg. Аргумент-заголовок окна читается только при
sav=0 и sav=−1; в остальных случаях текст после команды — просто
комментарий. При показе с c≠0 программа ждёт клика или клавиши и получает
модификатор и код клавиши в s(1), s(2). em=1 ставит окно
в точку (xpo, ypo) от угла экрана.
text — текст
#g [op=text; nx=; ny=; sty=; col=; tfo=; tki=; tsi=;] текст\E
| Параметр | Смысл |
|---|---|
nx, ny |
точка привязки |
sty |
1 — текст начинается в точке, 2 — точка в середине строки, 3 — строка кончается в точке; по вертикали точка всегда на базовой линии |
col |
цвет |
tfo |
шрифт: 1 Monospaced, 2 Serif, 3 SansSerif, 4 Dialog, 5 DialogInput (другое — SansSerif) |
tki |
0 обычный, 1 жирный, 2 наклонный, 3 жирный наклонный |
tsi |
размер в пикселях (разумно 12…16) |
Греческие буквы вставляют кодами Юникода: \U945; — α, \U946; — β,
\U947; — γ, \U948; — δ, \U916; — Δ, \U952; — θ, \U955; — λ,
\U956; — μ, \U960; — π, \U963; — σ, \U969; — ω. Русские буквы
пишутся обычным текстом.
line, area — ломаная и многоугольник
#g [op=line; nx=; ny=; n=; b=; col=;]
#g [op=area; nx=; ny=; n=; b=; col=; mo=;]
Начальная точка — (nx, ny); n отрезков заданы приращениями в целом
массиве: i(b), i(b+1) — вектор первого отрезка, i(b+2), i(b+3) —
второго и так далее.
area дополнительно замыкает ломаную в многоугольник: при mo=0 он
заливается цветом col, при mo=1 рисуется только контур.
rect, oval, arc — фигуры
#g [op=rect; nx=; ny=; wid=; hei=; col=; mo=;]
#g [op=oval; nx=; ny=; wid=; hei=; col=; mo=;]
#g [op=arc; nx=; ny=; wid=; hei=; col=; mo=; b=; le=;]
Прямоугольник wid × hei с центром в (nx, ny), эллипс, вписанный в
такой прямоугольник, или часть эллипса. mo=0 — залить, mo=1 — только
контур.
У arc b — начальный угол, le — угловая ширина, в градусах; углы
отсчитываются от направления «на три часа» против часовой стрелки. С mo=0
получается залитый сектор.
image — готовая картинка
#g [op=image; nx=; ny=; n=; file=;]
При n>0 картинка берётся из памяти, иначе из файла file в рабочей папке
(нет файла — ошибка 13). Центр картинки ставится в (nx, ny); сама картинка
не масштабируется.
axes, rfun, dfun — график функций
Эти три операции делают то же, что #w [op=pf;], но позволяют
рисовать разные функции разными цветами, поверх других элементов, и ставить
область функций не там, где оси.
#g [op=rfun; file=; b=; le=; mo=; nx=; ny=; n=;] [Xmin Xmax]
#g [op=axes; b=; wid=; hei=; xsh=; ysh=; col=; sty=; bot=; top=; tsi=; tfo=; tki=; uni=; n=;] подписи...
#g [op=dfun; b=; col=; mo=; nx=; ny=; msi=; mki=;]
rfun читает функции так же, как #w [op=pf;]: из файла в рабочей папке
(числа float после le байтов) или из r(b)… при file=here; mo, nx,
ny и аргументы Xmin Xmax — оттуда же. Пределы xmi xma fmi fma
записываются в r(n)…r(n+3).
axes рисует прямоугольник осей wid × hei с центром в (xsh, ysh) и
подписи (их n, каждая — x y rts текст\E от левого нижнего угла холста).
Пределы для автоматической разметки берутся из r(b)…r(b+3). Остальное — как
в описании осей.
dfun рисует функции, прочитанные последним rfun, в масштабе осей,
нарисованных последним axes. Пределы берутся из r(b)…r(b+3) и должны
совпадать с теми, что вернул rfun.
Тонкость. rfun возвращает пределы в r(n), а axes и dfun берут их
из r(b): при rfun параметр b занят под адрес данных. Задавайте b для
axes и dfun равным n из rfun. the при этом должен оставаться равным
высоте холста.
axon — аксонометрия поверхности
#g [op=axon; b=; n=; c=; wid=; hei=; xsh=; ysh=; col=; tsi=; tfo=; tki=;]
Рисует однозначную поверхность z(x, y) линиями x-z и y-z сечений с
удалением невидимых линий, в трёхмерных осях. Значения функции — матрица
nx × ny без аргументов с r(b). Картинка занимает прямоугольник
wid × hei с левым нижним углом (xsh, ysh). Шрифт чисел — tfo, tki
(0…2), tsi.
Восемнадцать вещественных параметров с r(n):
| Элементы | Смысл |
|---|---|
xmi xma xfm xdm |
пределы оси x, значение у первой короткой риски, шаг коротких рисок |
ymi yma yfm ydm |
то же для y |
zmi zma zfm zdm |
то же для z |
vp1 vp2 vp3 |
направление на точку зрения (нормируется; алгоритм рассчитан на направления около 1 1 1) |
vpm |
десятичный логарифм расстояния до точки зрения: 3 — это 1000 |
hx hy |
масштабы аргументов x и y (обычно 1); подбираются так, чтобы Δx·hx и Δy·hy были близки к Δz, когда величины в разных единицах |
Двенадцать целых параметров с i(c):
| Элементы | Смысл |
|---|---|
nx ny |
число точек по x и по y (произведение не больше 65536, иначе ошибка 87) |
ngv |
1 — x-z сечения, 2 — y-z сечения, 3 — оба |
bot top |
длина коротких и длинных рисок в тысячных долях диагонали |
nxfm nxsm |
номер первой короткой риски, которая становится длинной с числом, и число коротких рисок между длинными по x |
nyfm nysm, nzfm nzsm |
то же для y и z |
nax |
0 — обе вертикальные оси, средняя ось и уровни; 1 — только правая вертикальная ось у оси x; 2 — только левая у оси y |
Векторный вариант того же графика — #ps [op=ax;], готовая
программа с разметкой осей — суперкоманда ##3.
Пример
#p [trx=0; try=0; sca=100;]
#g [op=open; twi=300; the=200; col=246;]
#g [op=rect; nx=150; ny=100; wid=200; hei=120; col=249; mo=1;]
#g [op=oval; nx=150; ny=100; wid=80; hei=80; col=248; mo=0;]
#g [op=arc; nx=150; ny=100; wid=120; hei=120; col=250; mo=1; b=0; le=90;]
#d 4 i(1) 100 0 0 50 !
#g [op=line; nx=20; ny=20; n=2; b=1; col=250;]
#g [op=text; nx=150; ny=175; col=255; tfo=3; tki=1; tsi=16; sty=2;] Фигуры\E
#g [op=close; sav=-1; form=shapes; c=1;] Пример графики\E
Синяя рамка, красный круг в центре, зелёная четверть окружности справа
вверху, ломаная «вправо на 100, вверх на 50» из точки (20, 20) и заголовок;
картинка показывается и записывается в shapes.jpg.
#eg — универсальная графика
#eg [op=open; twi=; the=; col=;]
#eg [op=xxx; ...] [аргументы]
#eg [op=close; sav=; form=; c=;] [заголовок\E]
Команда рисует на основе пакета Java 2D, устроенного по идеям PostScript:
любой объект — это контур (path), который можно обвести линией заданной
толщины и рисунка или залить сплошным цветом, градиентом или текстурой; ко
всем последующим объектам можно применять сдвиг, поворот, масштаб и скос.
Контуры строит отдельная команда #pat, а #eg использует их по
номеру. Качество выше, чем у #g, но и программировать сложнее.
Значимы три буквы op; неизвестная операция — ошибка 53, рисование без
открытого холста — ошибка 39, повторное открытие — ошибка 82. Сглаживание
включено всегда.
Координаты
- Координаты вещественные и отсчитываются от левого верхнего угла холста, ось y направлена вниз. Поднять объект — значит уменьшить y.
- Поскольку параметры команд целые, координаты, размеры и углы задаются не
параметрами, а элементами
r(): параметрbуказывает, откуда их брать. - Единица — точка 1/72 дюйма; на экране она примерно соответствует пикселю. Готовый рисунок можно промасштабировать целиком.
op |
Что делает | Числа в r(b)… |
|---|---|---|
open |
новый холст twi × the, фон col |
— |
cont |
продолжить картинку памяти n |
— |
close |
закончить, показать или сохранить | — |
trans |
сдвиг последующих объектов | x y |
rotate |
поворот вокруг текущего начала координат | угол в радианах |
scale |
масштаб | sx sy |
shear |
скос | x y |
clip |
обрезать последующее по контуру n |
— |
paint |
способ закраски | для градиента x1 y1 x2 y2 |
fill |
залить контур n |
— |
draw |
обвести контур n |
толщина, предел острия, пунктир, фаза |
text |
строка текста | x y |
mtxt |
несколько строк текста | — (всё в аргументах) |
image |
картинка из памяти | x y угол shx shy sx sy |
chfont |
проверить наличие шрифта | — |
open, cont, close
open открывает холст twi × the, залитый цветом col из
таблицы цветов. cont вместо нового холста открывает картинку
памяти номер n (нет — ошибка 63). close работает так же, как у #g:
правила sav, файл form.jpg, заголовок-аргумент только при
sav 0 и −1, ожидание клика при c≠0, положение окна em=1, xpo, ypo.
Картинки из файлов загружайте в память (например,
#w [op=im; sav=…;]) до открытия холста.
trans, rotate, scale, shear — преобразования
#eg [op=trans; b=;] сдвиг на (r(b), r(b+1))
#eg [op=rotate; b=;] поворот на r(b) радиан
#eg [op=scale; b=;] масштаб r(b) по x, r(b+1) по y
#eg [op=shear; b=;] скос: r(b) по x, r(b+1) по y
Преобразования накапливаются и действуют на все последующие объекты, в том числе текст и картинки. Поворот идёт вокруг начала координат, поэтому, чтобы повернуть объект вокруг его центра, сначала сдвигают начало в центр.
clip — обрезка
#eg [op=clip; n=;]
Всё, что рисуется дальше, видно только внутри замкнутого контура номер n.
paint — способ закраски
#eg [op=paint; mo=; col=; b=; sty=; c=;]
mo |
Закраска |
|---|---|
| 1 | сплошной цвет col |
| 2 | градиент от цвета col в точке (r(b), r(b+1)) к цвету col+1 в точке (r(b+2), r(b+3)); sty=0 — за пределами отрезка цвет постоянный, sty=1 — переход повторяется периодически |
| 3 | текстура: копии картинки памяти номер c (не n!) |
Закраска действует на fill, draw и текст.
fill — залить контур
#eg [op=fill; n=;]
Заливает контур номер n текущей закраской с учётом всех преобразований.
Незаданный контур — ошибка 62.
draw — обвести контур
#eg [op=draw; n=; b=; le=; mo=; sty=;]
| Элемент | Смысл |
|---|---|
r(b) |
толщина линии |
r(b+1) |
предел длины острого угла для соединения «острие» (не меньше 1) |
r(b+2) … r(b+1+le) |
пунктир: длина штриха, длина пропуска, штрих, … — повторяется вдоль линии |
r(b+2+le) |
фаза пунктира — длина первого отрезка |
mo |
концы линии: 0 — обрезаны точно по концу, 1 — скруглены, 2 — квадратные, выступающие на полтолщины |
sty |
соединения отрезков: 0 — острие, 1 — скругление, 2 — срез |
Значения mo и sty вне 0…2 заменяются на 1.
Тонкость. Пунктир обязателен: при le=0 Java отвергает пустой пунктир, и
интерпретатор падает с исключением. Сплошная линия получается пунктиром из
штриха и нулевого пропуска: le=2, r(b+2)=1, r(b+3)=0.
text — строка текста
#eg [op=text; b=; sty=; tki=; tsi=; form=; em=;] текст\E
| Параметр | Смысл |
|---|---|
r(b), r(b+1) |
точка привязки |
sty |
1…9: по горизонтали 1, 4, 7 — начало строки, 2, 5, 8 — середина, 3, 6, 9 — конец; по вертикали 1…3 — низ, 4…6 — середина высоты, 7…9 — верх |
tki |
0 обычный, 1 жирный, 2 наклонный, 3 жирный наклонный |
tsi |
размер |
form |
имя семейства шрифтов — любого установленного в системе |
em |
больше 0 — y отсчитывается от нижнего края холста (только без scale) |
Имя шрифта с пробелами прямо в параметр не записать (пробел оканчивает
значение) — его печатают в t() и подставляют ссылкой:
#pr Times New Roman\E
#p [form=\Tp\E]
Греческие буквы — кодами Юникода (\U945; и т. д., см. #g).
После em>0 верните em=0.
mtxt — несколько строк
#eg [op=mtxt; n=; tki=; tsi=; form=; em=;] st x y ts текст\E st x y ts текст\E ...
n строк, каждая описана пятью аргументами: st — привязка (1 — начало,
2 — середина, 3 — конец строки; знак минус — координаты абсолютные, иначе
отсчитываются от точки предыдущей строки, начиная с (0, 0)), x y,
добавка ts к базовому размеру tsi, сам текст. Шрифт — form, начертание —
tki. При em>0 абсолютные y отсчитываются от нижнего края.
image — картинка
#eg [op=image; n=; b=; em=;]
Ставит картинку памяти номер n с собственным преобразованием, которое
выполняется до общего:
| Элемент | Смысл |
|---|---|
r(b), r(b+1) |
центр картинки (от верхнего левого угла; при em>0 y от нижнего края) |
r(b+2) |
поворот вокруг центра, радианы |
r(b+3), r(b+4) |
скос |
r(b+5), r(b+6) |
масштаб по x и по y — обязательно задайте, при нуле картинка не видна |
chfont — есть ли шрифт
#eg [op=chfont; form=имя;]
&=1, если семейство шрифтов установлено, иначе &=0. Работает и без
открытого холста. Нужна для переносимости: отсутствующий шрифт Java молча
заменяет своим, и текст перестаёт помещаться.
Если перед этим открыт документ #pd и выполнено
#pd [op=opeg;], все операции #eg, кроме open и
close, рисуют прямо в PDF.
Пример
#d 4 r(1) 20 20 160 80 !
#pat [op=rect; b=1; n=1;]
#eg [op=open; twi=200; the=120; col=246;]
#d 4 r(11) 20 0 180 0 !
#eg [op=paint; mo=2; col=249; b=11; sty=0;]
#eg [op=fill; n=1;]
#d 5 r(21) 3 1 8 4 0 !
#eg [op=paint; mo=1; col=247;]
#eg [op=draw; n=1; b=21; le=2; mo=0; sty=0;]
#d 2 r(31) 100 60 !
#eg [op=paint; mo=1; col=246;]
#eg [op=text; b=31; sty=5; tki=1; tsi=18; form=Serif;] Градиент\E
#eg [op=close; sav=0; c=1;] Пример универсальной графики\E
Прямоугольник залит градиентом от синего к зелёному, обведён чёрным пунктиром толщиной 3, по центру — белая надпись.
#pat — контуры для #eg
#pat [op=open; b=;]
#pat [op=line; b=;] ...
#pat [op=close; n=; mo=;]
#pat [op=rect; b=; n=;]
Команда строит контуры (path) — сложные линии из отрезков прямых и кривых
Безье, эллипсов и дуг — и хранит их под номерами 1…100. Команда
#eg потом заливает, обводит их или обрезает по ним рисунок. Один и
тот же контур можно использовать много раз. Значимы три буквы op;
неизвестная операция — ошибка 54.
Координаты, как и в #eg, вещественные, от левого верхнего угла, ось y
вниз; они берутся из r() начиная с r(b).
op |
Что делает | Числа в r(b)… |
|---|---|---|
open |
начать новый текущий контур, поставить перо в точку | x y |
cont |
сделать текущим сохранённый контур n и продолжать его |
— |
line |
отрезок из текущей точки | x y — конец |
quad |
квадратичная кривая: касательные в концах проходят через управляющую точку | x1 y1 — управляющая точка, x2 y2 — конец |
cub |
кубическая кривая: касательная в начале направлена к первой управляющей точке, в конце — от второй | x1 y1 x2 y2 — управляющие точки, x3 y3 — конец |
app |
присоединить сохранённый контур n к текущему; mo=1 — соединив отрезком |
— |
close |
сохранить текущий контур под номером n; mo=1 — замкнуть отрезком в начальную точку |
— |
rect |
сразу сохранить под номером n прямоугольник |
x y w h — левый верхний угол, ширина, высота |
ell |
сразу сохранить под номером n эллипс, вписанный в прямоугольник |
x y w h |
arc |
сразу сохранить под номером n часть такого эллипса |
x y w h, начальный угол, угловая ширина |
У arc параметр mo задаёт вид: 0 — открытая дуга, 1 — дуга с хордой,
2 — сектор («кусок пирога»).
Треугольник как контур 3, залитый красным.
#d 6 r(1) 100 10 180 150 20 150 !
#pat [op=open; b=1;]
#pat [op=line; b=3;]
#pat [op=line; b=5;]
#pat [op=close; n=3; mo=1;]
#eg [op=open; twi=200; the=170; col=246;]
#eg [op=paint; mo=1; col=248;]
#eg [op=fill; n=3;]
#eg [op=close; sav=0; c=1;] Треугольник\E
Тонкости.
- Углы в
arcзадаются в градусах (от направления «на три часа» против часовой стрелки), хотя в справочнике автора написано «в радианах». rect,ellиarcзаменяют текущий контур: если вы строили контур операциямиopen/lineи не сохранили его черезclose, он пропадёт.contс номером несохранённого контура делает текущий контур пустым, и следующая операция приводит к исключению Java.- Для заливки контур должен быть замкнутым;
fillзамыкает его сам, аdrawрисует ровно то, что построено.
#ps — векторная графика в EPS
#ps [op=of; twi=; the=; form=;]
#ps [op=ps | pf | ax; ...]
#ps [op=cf;]
Команда пишет рисунок на языке PostScript в файл encapsulated PostScript
(.eps). Такая графика векторная: печатается без потери качества,
вставляется в статьи LaTeX, показывается программой Ghostview (GSview) или
после перевода в PDF. Сам интерпретатор EPS не показывает. Рисунок
собирается из готовых фрагментов, каждый — одной операцией. Значимы две
буквы op; короче двух — ошибка 45, неизвестная — ошибка 65, рисование
без открытого файла — ошибка 81.
op |
Что делает |
|---|---|
of |
открыть файл, записать заголовок и пролог |
ps |
вставить готовый PostScript-код из файла или из t() |
pf |
нарисовать одну функцию в осях, как #w [op=pf;] |
ax |
аксонометрия поверхности, как #g [op=axon;] |
cf |
закончить и закрыть файл |
Единицы и общий сдвиг
Размеры рисунка — в точках PostScript (1/72 дюйма; лист A4 — 596×843 точки).
Операции ps, pf, ax оборачивают свой фрагмент в преобразование:
| Параметр | Смысл |
|---|---|
trx, try |
сдвиг фрагмента в десятых долях точки |
sca |
масштаб в сотых долях: 100 — натуральный размер |
rat |
только у ps: поворот в десятых долях градуса |
Поэтому один и тот же фрагмент можно ставить в разные места, в разном
масштабе и много раз. Параметр rat обычно равен 0; оставшееся от другой
команды значение повернёт вставленный фрагмент.
of — открыть файл
#ps [op=of; twi=; the=; form=имя;]
Создаёт в рабочей папке файл имя.eps с рамкой twi × the точек и пишет
пролог — набор коротких команд-сокращений (m — перейти, l — линия,
ls — отрезок, srgb — цвет, slw — толщина, r — поворот, s, sc, se
— текст с привязкой слева, по центру, справа, L, G, H — текст 14 пт
шрифтами Palatino, Symbol, Helvetica и другие). Ими удобно пользоваться во
фрагментах для ps; пролог можно прочитать в любом созданном файле. Эта
операция должна быть первой.
ps — готовый код
#ps [op=ps; file=; b=; le=; trx=; try=; sca=; rat=;]
Вставляет PostScript-код из файла file в рабочей папке (нет файла — ошибка
13) или, при file=here, le символов из t() начиная с t(b). Так
вставляют растровые картинки, превращённые во фрагменты операцией
#f [op=tops; mo=2 или 3;], подписи и любые собственные
рисунки. Например, подпись в точке (100, 50), повёрнутая на 90°:
#ps [op=of; twi=200; the=200; form=label;]
# s(3)=1; !
#pr 100 50 m 90 r (Intensity)L -90 r\E
#ps [op=ps; file=here; b=s(4); le=s(5); trx=0; try=0; sca=100; rat=0;]
#ps [op=cf;]
Буква L печатает латиницей, G — греческими буквами. Русский текст автор
выводит собственным шрифтом; это отдельная техника, описанная в его книге о
PostScript.
pf — функция в осях
#ps [op=pf; file=; b=; le=; mo=; nx=; col=; msi=; mki=; siz=; оси...; trx=; try=; sca=;] [X1 X2]
Строит график одной функции — в отличие от #w, за одну операцию рисуется
одна кривая, зато операцию можно повторять с разными функциями, цветами и
маркерами в тех же или других осях.
| Параметр | Смысл |
|---|---|
file |
файл чисел float в рабочей папке (после le байтов заголовка) или here — r(b)… |
nx |
число точек |
mo |
0 — в данных только значения, аргумент равномерный от X1 до X2 (аргументы команды); 1 — сначала nx аргументов, затем nx значений |
col |
цвет кривой (оси всегда чёрные) |
mki |
0 — сплошная линия толщиной msi (по словам автора — в сотых долях точки); 1 — белый квадрат, 2 — цветной квадрат, 3 — белый круг, 4 — цветной круг размером msi; больше 4 — ошибка 64 |
siz |
толщина линий осей — 0,5·siz точки |
wid, hei, xsh, ysh, sty, bot, top, uni |
оси, как в #w; sty=11111 — без осей |
tsi |
размер чисел на осях в точках (шрифт Helvetica) |
ax — аксонометрия
#ps [op=ax; b=; n=; c=; wid=; hei=; col=; tsi=; trx=; try=; sca=;]
Всё как у #g [op=axon;]: функция z(x, y) с r(b),
восемнадцать вещественных параметров с r(n), двенадцать целых с i(c).
Отличия: wid, hei — размер прямоугольника, в котором лежат линии (числа
на осях могут выходить за него); xsh, ysh не используются — положение
задают trx, try (они должны быть положительными, иначе числа уйдут за
рамку); шрифт чисел фиксирован, tsi — его размер в точках.
cf — закрыть
#ps [op=cf;]
Дописывает окончание и закрывает файл. Без неё файл неполон.
Пример
Гауссова поверхность 91 на 91 точку в EPS.
# y=-9; d=0.2; j=21; !
#rep 91
# x=-9; !
#rep 91 # r(j)=exp(-0.03*(x*x+y*y)); j=j+1; x=x+d; #end
# y=y+d; !
#end
#ps [op=of; twi=450; the=320; form=axexam;]
#d 12 i(1) 91 91 3 10 20 2 3 2 3 1 1 0 !
#d 18 r(1) -0,9 0,9 -0,9 0,1 -0,9 0,9 -0,9 0,1 0 1 0 0,1 1 1 0.5 3 1 1 !
#p [tsi=14; col=247;]
#ps [op=ax; trx=750; try=500; sca=100; n=1; c=1; b=21; wid=300; hei=250;]
#ps [op=cf;]
Тонкость. В похожем примере автора стоят trx=75; try=50; sca=1;. По
коду интерпретатора сдвиг задаётся в десятых долях точки, а масштаб — в
сотых, так что с такими значениями рисунок получится в сто раз меньше
натурального. Для натурального размера нужно sca=100.
#pd — PDF-документы
#pd [op=open; file=имя.pdf; twi=; the=; wid=; hei=; xsh=; ysh=; mo=;] [аргументы]
#pd [op=para | text | imag | page | ...; ...]
#pd [op=clos;]
Команда создаёт документ PDF: абзацы текста, надписи в заданных точках,
картинки, векторная графика #eg, страницы из других PDF-файлов,
колонтитулы, пароли. В основе — библиотека iText 1.3 (Bruno Lowagie). Все
размеры — в точках (pt, 1/72 дюйма; лист A4 — 596×843 pt). Значимы четыре
буквы op; неизвестная операция — ошибка 74, неверное расширение файла —
ошибка 75, операция без открытого документа — ошибка 76.
op |
Что делает |
|---|---|
open |
начать документ |
clos |
закончить и записать файл |
para |
абзац текста в потоке |
text |
строка текста в заданной точке, с поворотом |
imag |
картинка в потоке или в заданной точке |
page |
перейти на новую страницу |
smar |
поля следующей страницы |
smmi |
зеркальные поля |
spgn |
номер страницы |
rpdf |
прочитать внешний PDF |
wpdf |
вставить страницу прочитанного PDF |
opeg |
начать векторную графику #eg прямо в PDF |
cleg |
поставить эту графику на страницу |
Тонкость. Встроенные шрифты PDF не содержат русских букв. Русский текст
рисуют командой #eg в картинку и вставляют операцией imag.
open — начать документ
| Параметр | Смысл |
|---|---|
file |
имя файла с расширением .pdf в рабочей папке; file=arg — из аргумента |
twi, the |
размер листа |
wid, hei |
размер области текста |
xsh, ysh |
левое и нижнее поля (правое и верхнее — остаток) |
mo |
четырёхзначное KLMN из нулей и единиц: N — нижний колонтитул, M — верхний, L — метаданные, K — пароль |
Для каждой единицы в mo читается аргумент, в порядке: нижний колонтитул,
верхний колонтитул, метаданные, пароль.
| Аргумент | Вид | Дополнительно |
|---|---|---|
| колонтитул | текст|номер|рамка\E: номер > 0 — нумеровать страницы начиная с него; рамка — сумма 1 (верх), 2 (низ), 4 (лево), 8 (право) |
выравнивание: bot для нижнего, top для верхнего — 0 слева, 1 по центру, 2 справа |
| метаданные | заголовок|тема|ключевые слова|создатель|автор\E |
в документе не видны |
| пароль | пароль пользователя и пароль владельца подряд, \E |
le — длина пароля пользователя; sty=1 — слабое шифрование (иначе сильное); sav — сумма разрешений |
| Разрешение | Число |
|---|---|
| печать | 2052 |
| печать низкого качества | 4 |
| изменение содержимого | 8 |
| копирование | 16 |
| изменение примечаний | 32 |
| заполнение форм | 256 |
| программы чтения с экрана | 512 |
| сборка документа | 1024 |
Разрешить печать и копирование — sav=2068. Остальные действия потребуют
пароля.
clos — закончить
Закрывает документ и дописывает файл. Без неё PDF неполон.
para — абзац
#pd [op=para; b=; tfo=; tki=; tsi=; col=;] текст\E
| Параметр | Смысл |
|---|---|
tfo |
семейство: 0 Courier, 1 Helvetica, 2 Times-Roman, 3 Symbol, 4 ZapfDingbats |
tki |
начертание: 0 обычное, 1 жирное, 2 курсив, 3 жирный курсив, 4 подчёркнутое, 8 зачёркнутое |
tsi |
размер в pt |
col |
цвет из таблицы цветов |
r(b)…r(b+5) |
отступ перед абзацем, отступ после, выравнивание (0 слева, 1 по центру, 2 справа), отступ первой строки, поле слева, поле справа |
Абзац начинается с новой строки; переход на новую страницу — автоматический.
text — надпись в точке
#pd [op=text; b=; tfo=; col=; sty=;] текст\E
| Параметр | Смысл |
|---|---|
tfo |
шрифт 1…15: Courier (1–4: обычный, жирный, наклонный, жирный наклонный), Helvetica (5–8, так же), Times (9–12: обычный, жирный, курсив, жирный курсив), 13 Times-Roman, 14 Symbol, 15 ZapfDingbats |
r(b)…r(b+3) |
размер в pt, координаты x, y на странице, угол поворота |
sty |
привязка к точке: 0 — левым краем, 1 — серединой, 2 — правым краем |
Тонкость. Автор пишет, что угол задаётся в радианах; библиотека iText принимает его в градусах.
imag — картинка
#pd [op=imag; file=; mo=; b=;]
Картинка из файла jpg, gif, png, bmp, tif, wmf или eps (файл с другим
расширением молча пропускается). mo — двузначное KM:
| Разряд | Значения |
|---|---|
K |
0 — в потоке текста после предыдущего; 1 — по абсолютным координатам левого нижнего угла |
M |
масштаб: 0 — в процентах, 1 — до заданной ширины, 2 — до заданной высоты (пропорции сохраняются) |
| Элемент | Смысл |
|---|---|
r(b), r(b+1) |
при K=1 — координаты; при K=0 — отступы до и после картинки |
r(b+2) |
при K=0 — положение в строке: 0 слева, 1 по центру, 2 справа |
r(b+3) |
проценты, ширина или высота в pt — по M |
r(b+4) |
поворот в градусах |
Прозрачности нет: картинки, поставленные позже, закрывают ранние. Поэтому картинки по абсолютным координатам ставят после потоковых.
page — новая страница
Принудительно переводит вывод на следующую страницу.
smar, smmi, spgn — поля и нумерация
| Операция | Что делает |
|---|---|
#pd [op=smar; b=;] |
поля следующей страницы из r(b)…r(b+3): левое, правое, верхнее, нижнее |
#pd [op=smmi; mo=;] |
mo=1 — зеркальные поля на чётных и нечётных страницах, иначе нет |
#pd [op=spgn; n=;] |
номер текущей страницы (и включение нумерации) |
rpdf, wpdf — страницы другого PDF
#pd [op=rpdf; file=другой.pdf; b=;]
#pd [op=wpdf; n=; b=;]
rpdf читает внешний файл (открытый документ не нужен): число страниц — в
s(1), размеры страниц — в r(b)… парами «ширина, высота». wpdf ставит
страницу номер n прочитанного файла на текущую страницу документа с
преобразованием из r(b)…r(b+4): сдвиг по x и y от левого нижнего угла (pt),
масштаб по x и y (1 — без изменений), поворот в градусах. Так собирают
несколько страниц на одном листе, поворачивают и переупорядочивают страницы.
opeg, cleg — векторная графика в PDF
#pd [op=opeg; wid=; hei=; col=;]
#eg [...] ...
#pd [op=cleg; xsh=; ysh=;]
opeg открывает область графики wid × hei, залитую цветом col; после неё
любые операции #eg, кроме open и close, рисуют прямо в PDF
(векторно). cleg ставит нарисованное на страницу с левым и нижним полями
xsh, ysh. Открытый холст #eg при opeg — ошибка 82, cleg без opeg —
ошибка 39.
Пример
#pd [op=open; file=report.pdf; twi=596; the=843; wid=480; hei=700; xsh=58; ysh=70; mo=1;] VKACL report|1|1\E
#d 6 r(1) 0 12 1 0 0 0 !
#pd [op=para; b=1; tfo=2; tki=1; tsi=18; col=247;] Measurement report\E
#d 6 r(1) 0 6 0 20 0 0 !
#pd [op=para; b=1; tfo=2; tki=0; tsi=12; col=247;] The picture below was made by the program.\E
#d 5 r(11) 10 10 1 300 0 !
#pd [op=imag; file=pic.png; mo=1; b=11;]
#pd [op=clos;]
Документ A4 с нижним колонтитулом «VKACL report», номерами страниц с первой и линией над колонтитулом; заголовок по центру, абзац с красной строкой и картинка шириной 300 pt по центру.
#bi — обработка байтовых картинок
#bi [op=xxx; file=; form=; rat=; bot=; top=; mo=; b=;] [список файлов\E]
Команда обрабатывает «сырые» картинки — файлы, где каждый байт означает
уровень серого точки (такие делает, например,
#f [op=tobm;]). Байт трактуется как целое 0…255; после
преобразования отрицательные значения становятся 0, большие 255 — 255.
Исходный файл file не меняется, результат пишется в файл form; оба имени
— в рабочей папке. Значимы три буквы op; неизвестная операция — ошибка
66, недопустимые параметры — ошибка 67, нет файла — ошибка 19.
Преобразования одной картинки
op |
Новое значение f из исходного b |
Параметры |
|---|---|---|
add |
b + rat — ярче или темнее |
rat любого знака |
mul |
b·rat/1000; при rat ≤ 0 — 255 + b·rat/1000, то есть обращение контраста |
rat (1000 — без изменений) |
inc |
отрезок [bot, top] растягивается на [0, 255] — контраст выше |
0 < bot < top < 255 |
dec |
[0, 255] сжимается в [bot, top] — контраст ниже |
0 < bot < top < 255 |
cha |
m + (b − m)·rat/1000, где m — среднее по картинке |
rat (1000 — без изменений) |
pow |
255·(b/255)^(rat/1000) — неравномерный градиент при тех же пределах |
rat (1000 — без изменений) |
log |
(ln(b + p1) − ln(255 + p2 − b) + f1)·f2, где f1 = ln(255 + p2) − ln p1, f2 = 255/(ln(255 + p1) − ln p2 + f1); сглаженный аналог dec — градиент в середине меньше |
p1 = bot > 0, p2 = top > 0 |
exp |
255/(1 + exp((p2 − b)/p1)), где p2 = (bot+top)/2, p1 = p2 − bot; сглаженный аналог inc — градиент в середине больше |
0 < bot < top < 255, top − bot чётное |
#bi [op=inc; bot=40; top=200; file=scan.raw; form=scan2.raw;]
Несколько картинок
sup, pro, div работают со списком файлов, который задают двумя
способами:
file |
Аргумент |
|---|---|
list |
имена через |: 1.rif|2.rif|3.rif\E |
order |
базовое имя с номером перед расширением из трёх букв, например my00.rif\E; номера от bot до top подставляются вместо последних цифр: my01.rif, my02.rif, … |
Результат имеет размер первого файла. Файлы меньшего размера используются целиком, большего — только их начало. Отсутствующий файл пропускается с сообщением в терминале.
op |
Что вычисляется |
|---|---|
sup |
взвешенная сумма Σ b_k·i(b+k−1) с целыми весами из i(b)… (отрицательные — вычитание); затем mo=0 — отрицательные обнуляются, а максимум приводится к 255; mo=1 — весь диапазон от минимума до максимума переводится в 0…255 |
pro |
произведение всех картинок, максимум приводится к 255 |
div |
первая картинка, делённая на вторую (нулевые байты делителя заменяются на 1), максимум приводится к 255; остальные файлы списка не используются |
#d 3 i(1) 1 2 3 !
#bi [op=sup; mo=0; file=list; form=sum.rif; b=1;] 1.rif|2.rif|3.rif\E
#bi [op=sup; mo=0; file=order; form=sum2.rif; b=1; bot=1; top=3;] my00.rif\E
Первая команда складывает три картинки с весами 1, 2, 3; вторая делает то же
для my01.rif…my03.rif. Сложение удобно, когда детектор не выдерживает
длинной экспозиции и один кадр снимают много раз; умножение на маску из нулей
и единиц вырезает часть картинки.
Тонкость. Картинки разной ширины складываются «вслепую», байт за байтом:
меньшая картинка размазывается по большей. Для таких случаев сначала
вырежьте из большой картинки фрагмент нужного размера
(#f [op=divi;]).
#ag — анимация
#ag [op=o; wid=; hei=; xsh=; ysh=; file=;] заголовок\E
#ag [op=m; n=; xsh=; ysh=; file=;] заголовок\E
#ag [op=p;] #ag [op=i;] #ag [op=c;]
#ag [op=s;] адрес-протокола\E
Команда открывает окно анимации, показывает в нём по очереди картинки из
памяти (их заранее рисуют #g, #eg или загружают
#w), играет фоновую музыку и сообщает программе о нажатиях клавиш и
действиях мышью — этого хватает для презентаций и простых интерактивных игр.
Операцию задаёт одна буква; другая — ошибка 55.
op |
Что делает |
|---|---|
o |
открыть окно анимации, включить фоновую музыку |
m |
показать кадр, сменить заголовок, получить действия пользователя |
p |
только получить действия пользователя |
i |
обнулить сведения о действиях |
c |
закрыть окно, выключить музыку |
s |
запустить готовую программу слайд-шоу |
o — открыть окно
| Параметр | Смысл |
|---|---|
wid, hei |
полный размер окна в пикселях |
xsh, ysh |
левый верхний угол окна от угла экрана |
file |
фоновая музыка, повторяется бесконечно: файл .wav, .au, .aif или .mid в рабочей папке; &имя — файл внутри jar-файла; nomusic — без музыки; arg — имя из первого аргумента (заголовок тогда — второй аргумент) |
Аргумент — заголовок окна. Отсутствующий файл музыки ошибкой не считается. Для фона разумнее всего MIDI: файлы маленькие.
Тонкость. В новых версиях Java окно поначалу прозрачное и показывает то,
что было под ним. Сразу после o выставьте первый кадр операцией m.
m — кадр
| Параметр | Смысл |
|---|---|
n |
номер картинки в памяти |
xsh, ysh |
сдвиг центра картинки от центра окна |
file |
звуковой файл, проигрываемый один раз; nomusic — без звука |
Аргумент заменяет заголовок окна. Окно имеет полосу заголовка высотой около
26 пикселей: чтобы картинка W × H поместилась целиком, задайте окну высоту
H+26 и сдвиг ysh=−13.
После показа кадра программа получает сведения о действиях пользователя с момента последнего обнуления:
| Ячейка | Значение |
|---|---|
s(1) |
модификатор клика (см. таблицу #w) |
s(2) |
код нажатой клавиши |
s(102), s(103) |
текущее положение мыши в окне |
s(104), s(105) |
точка отпускания кнопки после протяжки |
s(108) |
кратность клика: 1 — одинарный, 2 — двойной, … |
Если музыка не нужна, всё равно пишите file=nomusic: проверка
несуществующего файла отнимает время в каждом кадре. Одновременное
проигрывание звука и подготовка кадра ухудшают звук — автор советует
готовить кадр в тишине, а звук давать, пока кадр стоит на экране.
p и i — опрос действий
p только возвращает те же сведения, что и m, без показа кадра — так
пишут цикл ожидания клавиши. Сведения сохраняются, пока их не обнулит i;
без обнуления одно нажатие будет «видно» вечно. Клавиатура опрашивается
надёжно, клики мыши — по словам автора, пока нестабильно. Окно анимации не
всегда активно, поэтому клавишу иногда приходится подержать.
Ждать нажатия любой клавиши.
#ag [op=i;]
# &=1; !
#case 1
#rob [mo=1; le=50;]
#ag [op=p;]
# &=1-sgn(s(2)); !
#end
c — закрыть
Закрывает окно и выключает музыку. Если пользователь закрыл окно крестиком
во время показа, интерпретатор блокирует циклы: тело любого #rep и
#case-цикла выполняется только один раз, чтобы бесконечная анимация
кончилась. Нормальную работу циклов возвращает #init,
поэтому после анимации всегда пишут #ag [op=c;] и #init.
Кадры 1…10 заранее сохранены в память.
#ag [op=o; wid=320; hei=266; xsh=100; ysh=100; file=nomusic;] Анимация\E
# k=1; !
#rep 10
#ag [op=m; n=k; xsh=0; ysh=-13; file=nomusic;] Кадр\E
#rob [mo=1; le=100;]
# k=k+1; !
#end
#ag [op=c;]
#init
Для быстрой анимации кадры лучше приготовить заранее и сохранить в память, а
темп задавать паузой #rob [mo=1;]: рисование кадра прямо в цикле
иногда даёт случайные задержки.
s — слайд-шоу
#ag [op=s;] адрес\E
Запускает готовую программу слайд-шоу с переходами между картинками —
локальными или из интернета. Ей управляет файл-протокол, адрес которого — в
аргументе: File:C:/папка/show.vks для локального файла или обычный адрес
http://…. Путь к файлу рядом с программой удобно собрать кодами \M\H.
Правила записи протокола автор описывает отдельно на своём сайте
(kohnvict.ucoz.ru/acl/vkss.htm).
#so — звук
#so [op=psf; n=; c=; siz=; sty=; mo=; le=;] файл1\E файл2\E ...
#so [op=rsf; xsh=; ysh=; rat=; siz=; mo=; sty=; b=; le=;]
#so [op=mid; file=;]
Команда проигрывает звуковые файлы и записывает звук с микрофона. Значимы
три буквы op; неизвестная операция — ошибка 56. Команда писалась под
Java 1.4.2; автор предупреждает, что в новых версиях Java её работу нужно
проверять.
psf — проиграть файлы
| Параметр | Смысл |
|---|---|
n |
число файлов; их имена — аргументы, по одному в каждом, в рабочей папке |
c |
канал 1…10; проигрыватели в разных каналах звучат одновременно |
siz |
громкость в процентах: 100 — как в файле; MIDI не бывает громче 100, WAVE, AU, AIFF — бывают |
sty |
панорама от −100 до 100 (распределение между динамиками), обычно 0 |
mo |
0 — проиграть один раз; иначе повторять по кругу |
le |
параметр звукового процесса, обычно 100 (или 99); другие значения дают эффекты, подбираемые на слух |
Файлы проигрываются по очереди, другие форматы не поддерживаются. Бесконечное
проигрывание (mo≠0) останавливает только #init.
Автор советует сочетать звук с окном анимации #ag: держать
программу в цикле, а после цикла поставить #init — закрытие окна анимации
завершит цикл и остановит звук. Нормальный звук получается, когда открыто
мало окон и программа не занята тяжёлым расчётом.
#so [op=psf; n=2; c=1; siz=100; sty=0; mo=0; le=100;] intro.wav\E theme.mid\E
rsf — записать звук
Открывает диалог записи: пользователь вводит имя файла (без расширения) и записывает сколько угодно клипов, например комментарии к слайдам. Файлы сохраняются в рабочую папку, кодировка — PCM.
| Параметр | Смысл |
|---|---|
xsh, ysh |
положение окна диалога от угла экрана (размер фиксирован) |
rat |
частота выборки: 8000, 11025, 16000, 22050 или 44100 (качество CD) |
siz |
разрядность: 8 или 16 бит |
mo |
1 — моно, 2 — стерео |
sty |
тип файла: 1 — WAVE (.wav), 2 — AU (.au), 3 — AIFF (.aif) |
b, le |
текст в t(), который показывает кнопка Help диалога |
mid — фоновая музыка
Операция не описана в справочнике автора; по коду она берёт файл file из
рабочей папки (или &имя из jar-файла) и проигрывает его по кругу — так же,
как фоновая музыка окна анимации. Останавливает её #init или
#ag [op=c;].
Песочница
Программы выполняются прямо в браузере: интерпретатор ядра VKACL собран в WebAssembly и встроен в страницу, поэтому всё работает даже без интернета и при открытии книги прямо с диска. Выберите пример из списка или пишите своё; запуск — кнопкой или Ctrl+Enter.
Песочница работает только на сайте книги.
Что здесь работает
Ядро языка: вычисления, память, ветвления, циклы, процедуры, форматированный
текст, #d, #v, #pas, #pr, #m, операции над массивами #ma,
файловые команды #io, #f, #te.
Окна выбора и ввода (#sel, #inp, #m [op=gen;], суперкоманда ##33)
заменены вопросами: ответы берутся по одному из поля «Ответы на вопросы
программы» под редактором — номер кнопки или значение поля.
Файлы. Без подключённой папки файлы живут в памяти только на время одного запуска: то, что программа записала, показывается под выводом, а каждый файл можно скачать по ссылке. Кнопка «Подключить папку» (есть в Chrome, Edge, Opera, Яндекс Браузере) даёт программе настоящую папку на диске: перед запуском её файлы читаются, после — изменённые и новые записываются обратно. Браузер спросит разрешение один раз. В Firefox и Safari такой возможности нет, и на месте кнопки стоит подсказка.
Графики, окна с картинками, звука, PDF здесь нет — такая команда честно сообщит, что не поддерживается. Для них нужен интерпретатор автора.
Шпаргалка
# a=1; b=a*2; ! вычисления; ! — конец списка присваиваний
#pr текст \G b;\n\E сформировать текст
#m [op=txt;] \Tp\E показать последний фрагмент
#rep 5 ... #end цикл
#case 1 ... #end | ветка
#pro имя ... @ процедура
#e _имя ! вызов
#ma [op=vic; b=1; le=5;] операция над массивом целиком
Три правила, о которых легко забыть:
- в поясняющем тексте не должно быть символа
#— иначе он будет выполнен как команда; - после
#c,#d,#v,#eперед поясняющим текстом нужен!; <и>— это минимум и максимум, и они связывают сильнее+и*.
Полный список — в справочнике команд, подводные камни — в главе Ловушки языка.
Реализация на Rust
В проекте есть независимая реализация ядра VKACL — acl-core. Она нужна для
двух вещей: чтобы примеры в этой книге запускались в браузере и в терминале, и
чтобы поведение языка было зафиксировано проверяемыми тестами, а не только
описанием. Заменой интерпретатору автора она не является и не задумывалась.
Что есть
| Область | Состояние |
|---|---|
Разбор потока команд, комментарии, !, @ |
есть |
Вычисления #c, все операции и функции |
есть |
Память: скаляры, двухсимвольные переменные, i(), r(), t(), s() |
есть |
#d, #v, #pas, #p |
есть |
#case, #rep, #end, #go, #%, обработка ошибок |
есть |
#pro, #e, #e _text, #e _file, ##имя |
есть |
Форматированный текст целиком, включая \TpN |
есть |
#pr, #read, #m |
есть |
#ma — операции над массивами |
есть все, кроме tom (окно прогресса), box (разметка осей графики), smh и rfh (файлы детекторов) и mmi/mcg с записью в файл |
#io, #f, #te |
файловые и текстовые операции есть; графические и сетевые — нет |
#sel, #inp, #m, #f [op=edit;], редактор #e _\09 |
вместо окон — вопросы в консоли |
#pf (индикатор хода) |
пропускается: программе он ничего не возвращает |
Номерные суперкоманды ##N |
из библиотеки автора proc00.txt, если она лежит рядом с программой; без неё — только ##33 |
Графика #w, #g, #eg, анимация, звук, PDF, архивы |
нет |
Неподдержанная команда не игнорируется: программа останавливается с кодом 900 и названием того, чего не хватает.
Окна становятся вопросами
Команды, открывающие окна выбора и ввода, в терминале задают вопросы:
── Что посчитать? ──
[1] Факториал 7 [2] Сумма 1..100 [3] Выход
> 2
Ответ ложится туда же, куда его кладёт окно в оригинале: номер кнопки — в
&, введённые значения — в t() с позиции s(3). Поэтому программы,
написанные для окон, работают без изменений. В песочнице ответы берутся из
поля под редактором.
Редактор текста (#f [op=edit;]) показывает файл с номерами строк и ждёт
одного ответа: Enter — выйти, номер — поставить курсор в начало этой строки
и выйти, любой другой текст — дописать его новой строкой. Позиция курсора
попадает в s(1), как в оригинале, а изменённый файл при mo=1
сохраняется.
Готовые программы автора в консоли
Суперкоманды автора — обычный код на VKACL в файле proc00.txt. Если
программа лежит в папке vkacl из дистрибутива автора, суперкоманды берутся
оттуда так же, как их берёт диспетчер оригинала. На этом построен
проигрыватель.acl из архива этой книги: скопируйте его в папку vkacl и
перетащите на запуск.bat (или наберите в этой папке
путь-к-acl.exe проигрыватель.acl). В другом месте он объяснит, что делать,
и закончит работу.
Проигрыватель спрашивает номер программы, записывает её код и данные в
pro/0.acl и pro/0.par, как это делает кнопка Index в меню автора, и
запускает её. Так работает, например, калькулятор №62: редактор показывает
строки файла данных, вы выбираете строку с формулами или вводите новую, и
программа печатает значения a…h.
Из 79 программ дистрибутива (№80 в нём нет) без ошибок до конца доходят 26, остальные останавливаются на графике, PDF или окнах (ошибка 900). 20 программ сверены с оригиналом, запущенным в пакетном режиме с теми же данными: созданные файлы совпадают байт в байт, а где оригинал останавливается с ошибкой, порт останавливается с той же.
Как проверялась точность
Эталоном служит сам интерпретатор автора. Небольшая обвязка на Java вызывает
его напрямую, без окон (сообщения об ошибках она закрывает сама и записывает
их текст). Набор программ из corpus/tests/ прогоняется через оригинал, его
вывод сохраняется как эталон, и с ним посимвольно сравнивается вывод этой
реализации. Совпадает всё: арифметика и приоритеты, все форматы чисел, циклы
и ветвления, процедуры, работа с массивами и файлами, операции #ma, функции
Бесселя и интегралы Френеля — их приближения перенесены коэффициент в
коэффициент.
Где реализация сознательно отличается
При проверке нашлись места, где интерпретатор автора, по-видимому, ошибается —
например, печатает 1000 как 1.0000+02 или теряет знак у bj1 от
отрицательного аргумента. Каждый такой случай подтверждён запуском. Здесь эти
места работают правильно, а подробный список с примерами и предлагаемыми
исправлениями передан автору. Для остальных программ разница незаметна.
Запуск из терминала
Готовая программа acl.exe (Windows 10/11, около 600 КБ, без установки):
acl.exe программа.acl
Проще всего — перетащить файл .acl на запуск.bat: окно останется открытым
с результатом. Кодировка файла — windows-1251 или UTF-8, определяется сама.
При первом запуске скачанного .exe Windows может показать «Система Windows
защитила ваш компьютер»: программа не подписана. Нажмите «Подробнее» →
«Выполнить в любом случае».
Сборка из исходников
cargo build --release -p acl-cli
cargo test
cargo build -p acl-wasm --target wasm32-unknown-unknown --release
Модуль WebAssembly обходится без wasm-bindgen и встраивается прямо в
страницу песочницы, поэтому она работает и при открытии книги с диска.