IRO UTSUSHI
Приложение, которое никогда не просит назвать чувство словами. Капните цвет на воду, размешайте его пальцем — и движение вашей руки останется единственной картиной.
Доступно в App StoreЧто умеет приложение
- Капните цвет и размешайте … Капните на воду до пяти цветов из палитры из шести и размешайте их пальцем в единую картину. Две палитры — «спокойные цвета» и «яркие цвета» — можно переключать даже после того, как цвет уже капнут.
- Никаких слов, никаких категорий … Здесь нет списка настроений на выбор, и подпись не добавляется впоследствии. Остаётся только след цвета и движения пальца.
- До 60 секунд на запись … О приближении конца сообщают рябь, свечение и звук. Вибрация для подгонки не используется.
- Четыре показателя движения … Скорость (медиана мгновенной скорости), разброс (среднее расстояние от центра тяжести), изменчивость (частота смены направления и разброс скорости) и динамика. По умолчанию они скрыты на экране результата: приложение, которое отказывается раскладывать чувства по категориям, не должно вести счёт баллам.
- Воспроизведение … Вода восстанавливается по сохранённой последовательности касаний и воспроизводится на скорости 1× или 2× с перемоткой вперёд и назад. Траекторию пальца и точки касаний можно наложить поверх воды.
- Экспорт и публикация … Экспорт в виде MP4 30 fps со звуком или в виде PNG. Историю можно листать свайпом вверх и вниз, а также удалять сразу несколько записей.
- Звук создаётся внутри приложения … Место касания становится нотой пентатонического звукоряда, а скорость движения — громкостью и яркостью обертонов. Доступно пять тембров: мягкие клавиши, калимба, арфа, стринг-пэд и стеклянная гармоника.
- Доступность и десять языков … Разработано в первую очередь с учётом потребностей слабовидящих пользователей: поддерживаются Dynamic Type, VoiceOver, «Усилить контраст», «Уменьшить прозрачность» и «Уменьшить движение». Доступно на японском, английском, испанском, французском, корейском, традиционном китайском, бразильском португальском, немецком, итальянском и вьетнамском языках.
Как это устроено
| Приложение | Swift + SwiftUI, написано как App Package для Swift Playgrounds, без единой внешней зависимости. |
|---|---|
| Вода | Симуляция жидкости, написанная на Metal. Поле скоростей, проекция давления, адвекция, усиление завихрений и смешение пигментов — всё выполняется на GPU. |
| Пигмент | Хранится в виде лагранжевых частиц и накладывается слоями по закону Бера — Ламберта с вычитающим смешением. Поскольку это частицы, они не размываются диффузией со временем. |
| Внешний вид | Преломление и блики рисуются по нормалям, аналитически выведенным из поля высот воды, плюс зернистый шум и дизеринг для предотвращения бандинга. |
| Ввод | Берётся из необработанных событий UIKit, все объединённые (coalesced) касания в пределах одного кадра передаются в жидкость. До пяти одновременных касаний записываются, воспроизводятся и измеряются как независимые штрихи — по одному на палец. |
| Хранение | Список истории содержит в JSON только лёгкую информацию; изображение — это один PNG-файл; последовательность касаний — бинарные данные фиксированной ширины, сжатые LZFSE, в отдельном каталоге для каждой записи. |
| Воспроизведение и экспорт | Вода восстанавливается путём повторного прогона симуляции по сохранённым шагам. MP4 — это не запись экрана: кадры пересобираются из этих шагов и записываются с частотой 30 fps. |
| Звук | Синтезируется внутри приложения — пентатонический звукоряд с полифонией до 16 голосов. Аудиофайлов нет. |
| Самопроверки | Поскольку среда не может использовать XCTest, при запуске в режиме отладки вместо этого выполняется набор написанных для этого приложения проверок (SelfChecks.swift). |
| Шифрование | Не используется вовсе; ответ о соответствии экспортным требованиям (export compliance) включён в приложение. |
Технически интересные детали
Хвост продолжает закручиваться после того, как палец прошёл
Адвекция включает поправку MacCormack, которая сохраняет тонкие вихри, исчезающие при простой полулагранжевой адвекции. Палец не толкает воду — он оставляет пару вихрей, вращающихся в противоположные стороны, вдоль направления движения, поэтому вода продолжает закручиваться ещё некоторое время после того, как палец ушёл. Все коэффициенты затухания и следования выражены «в секунду», поэтому движение выглядит одинаково и на устройстве с частотой 60 Гц, и на устройстве с частотой 120 Гц.
Разделение «видимой волны» и «волны, которая двигает»
Видимая сила ряби и её воздействие на пигмент — это отдельные параметры. Более того, рябь напрямую сдвигает положение пигмента, а не его скорость. Скорость пигмента каждый кадр подтягивается обратно к скорости потока воды — с постоянной времени около 0,36 секунды в плотных областях, — а рябь живёт меньше этого времени, поэтому измерения показали, что добавление скорости почти не двигало пигмент. Настройка внешнего вида и настройка ощущений от использования перестали мешать друг другу.
Решение не заставлять пигменты притягиваться друг к другу
Раньше существовала сила «слипания», собирающая пигмент вместе, но единственным устойчивым результатом был круглый комок: со временем вода заполнялась непрозрачными кругами, которые больше никогда не расходились. Теперь потемнение по краям, характерное для акварели, воспроизводится без перемещения пигмента. Поле плотности остаётся прежним, а край рисуется на его основе как затенение на поверхности воды, поэтому картина никак не «застывает».
Одна и та же запись всегда воспроизводится как одна и та же картина
Симуляция зафиксирована на 60 шагах в секунду, и для каждой записи рядом сохраняются реальные номера шагов, на которых был получен ввод UIKit, число шагов разгона, а также временные метки Float32 и координаты UInt16.
Воспроизведение доверяет этим сохранённым шагам больше, чем времени настенных часов. Скорость измеряется относительно UITouch.timestamp, поскольку движения в пределах одного кадра невозможно различить по времени настенных часов.
Предсказанные касания используются только для оценки скорости и никогда не влияют на положение пигмента.
Кроме того, SimulationEngineRegistry явно направляет каждый сохранённый simulationVersion к соответствующему движку.
Версия 6 зафиксирована вплоть до констант, часов и коэффициента переноса чернил, и неизвестная будущая версия никогда молча не передаётся в новейшую симуляцию.
Смысл в том, чтобы обновление приложения не пересобирало картину старой записи во что-то другое.
Баллы не показываются первыми
Четыре показателя не обрезаются по потолку — они лежат на кривой, асимптотически приближающейся к 100, поэтому одно быстрое движение не даёт максимальный балл. При этом на экране результата они по умолчанию скрыты. Если приложение, отказывающееся раскладывать чувства по словам, начинает с чисел, эти числа просто становятся новой меткой.
Конфиденциальность и обращения
IRO UTSUSHI хранит ваши записи только на вашем устройстве. В приложении нет регистрации учётной записи, рекламы, аналитики и функций отслеживания пользователей. Подробнее см. в Политике конфиденциальности IRO UTSUSHI.
С отзывами и сообщениями об ошибках вы также можете обратиться через страницу поддержки Sizu dev.