«Математика — це суперсила з мультиків 50-х». Автор книги «Геометрія для програмістів» розповідає, як математика допомагає в роботі розробника
У квітні 2023 року в американському видавництві Manning вийшла книга Geometry for Programmers («Геометрія для програмістів») авторства українського розробника Олександра Каленюка, який має диплом кандидата наук (PhD) з прикладної геометрії та інженерної графіки, що отримав після закінчення аспірантури Київського політехнічного інституту імені Ігоря Сікорського.
У перші тижні після виходу книжка перебувала в списку бестселерів на сайті видавництва, посідаючи спочатку десяту, а згодом — третю сходинку в топі продажів. Вона проводить читача дорогою від базових понять і термінів у прикладній геометрії до практичних порад для розробників.
DOU розпитав Каленюка про те, чому він вирішив написати цю книжку, що таке прикладна геометрія та чи обовʼязково розробникам мати глибокі математичні знання.
«Інтерактивні підручники мені подобаються більше за книжки»
У мене ніколи не було ідеї написати книжку, однак уже кілька років я створюю статті на математичну тематику для свого сайту Words and Buttons Online — це інтерактивний підручник для розробників.
Інтерактивні підручники мені подобаються більше за книжки. Звучить дивно, але, здається, формат книжки вже застарів для читача. Водночас він залишається ідеальним для письменника — допомагає сконцентруватися, довго працювати над темою, лініїзувати інформацію. Проте коли сам берешся за вивчення нової теми, значно зручніше читати не товстий підручник, у якому забуваєш кожні 50 попередніх сторінок, а інтерактивний посібник, де в один клік можна повернутися до потрібної теми.
Отже, я ніколи не хотів писати книжку, але у 2021 році на мене вийшли з американського видавництва Manning і запропонували поспілкуватися. Дивно, але знайшли мене не завдяки моєму сайту. Як саме вони дізналися про моє існування — досі загадка. Про Words and Buttons Online я розповів видавцю вже під час особистого спілкування. Той мені повідомив, наскільки успішно в них продається єдине видання з математики для програмістів, що є в їхньому асортименті. Тоді я зрозумів, що насправді все життя мріяв написати книжку і взагалі жити без цього не можу [сміється]. Для мене було неочікуваним, що таку літературу продовжують читати. Ну про які технічні книжки може йтися у XXI столітті?
Писати я розпочав у червні 2021 року, а віддати рукопис мав у вересні 2022 року. Я затримав його на 20 днів, але видавництво увійшло в моє становище, тож мене ніхто не підганяв — як-не-як у країні повномасштабна війна. Найскладнішим стало не саме написання рукопису, а подальша робота над текстом. Коли хтось вичитує твій текст, це неприємно, але спрощує життя. Інша річ — самому вичитувати текст раз за разом, після того, як уже разів сім читав його від «А» до «Я». Око не просто замилюється, а взагалі нічого не бачить. Усі роботи над книжкою завершилися лише на початку квітня 2023 року.
Того ж місяця «Геометрію для програмістів» надрукували й запустили в продаж, і вона вже має певний успіх: деякий час видання перебувало в десятці бестселерів Manning, навіть опинилось на третьому місці. Які гроші вона мені принесе — поки не зрозуміло, залежатиме від продажів.
Моя частка за книжку до початку офіційного старту продажів становить 6500 доларів. З них я вже отримав 5000 доларів авансу двома переказами. Першу частину коштів ще минулого березня скерував профільному підприємству «Укроборонпрому» — «Укрспецекспорту». Другий переказ пішов волонтерській організації «Білі Горвати». Решту отримаю цього літа й також передам на перемогу.
Розуміння, що за отримані гроші я можу донатити, нарешті допомогло збагнути, навіщо я взявся за написання книжки. Ціль сформувалася в лютому 2022 року. На початку повномасштабної війни я думав, що є пріоритетніші справи, ніж робота над рукописом. Наприклад, ми з друзями пропонували допомогу теробороні, хотіли стояти на блокпостах, однак нам сказали, що такої потреби наразі немає. Тож я вирішив дописувати «Геометрію для програмістів», а всі зароблені гроші віддавати на перемогу.
«Прикладною науку робить те, що завдяки їй можна заробити гроші»
Прикладна геометрія відрізняється від інших математичних наук. Це навіть не зовсім математика, а радше те, що виросло з дисципліни «креслення». Власне геометрією я займався досить недовго й потрапив у спеціальність майже випадково, коли в 2005 році досліджував один цікавий алгоритм інтерполяції [інтерполяція — математична функція для знаходження невідомих значень між відомими — ред.], що можна було використовувати для моделювання деформацій. Спершу — з цікавості, потім з нього вийшла перша академічна публікація, а далі якось само пішло. Знайомих математиків у мене не було, довелося все досліджувати самостійно.
Прикладною науку робить те, що завдяки їй можна заробити гроші. Однак де саме проходить межа між прикладною та високою математикою, я не знаю — це полемічне питання. Для мене прикладна геометрія — це про неперервні перетворення, площини, криві, поверхні. Наприклад, будь-яка 3D-модель, яку ми хочемо надрукувати, — це прикладна геометрія, як і десятки алгоритмів, які приводять її до команд принтера, а самі команди — чиста інженерія.
Прикладна геометрія та, власне, математика — це не щось критично необхідне для розробників, це не кисень і не вуглеводи. Без фундаментальних знань у математиці можна бути чудовим фахівцем і прекрасно працювати, однак зі знаннями математики деякі речі можна робити значно швидше й ефективніше: анімації для графічного інтерфейсу, візуалізацію даних, різноманітні перетворення просторової інформації від фотографій до геоінформаційних даних.
Математика — це суперсила з мультиків
У моєму житті були такі історії. Мій батько займався краєзнавством, але професійним істориком не був. В архіви він не їздив, доводилося працювати з документами дуже сумнівної якості — часто колеги й друзі просто надсилали йому фото книжкових сторінок. Читати й додавати їх до робіт було незручно. Адже коли ти робиш знімок розвороту книги, то через наявність корінця сторінки виглядають «вигнутими». Тож я написав програму, яка їх «розгинає» і робить схожими на відсканований документ. Однак працювала вона доволі повільно. Я почав розбиратися, у чому проблема, і знайшов цікаву річ.
Концептуально — нічого складного, проста математика. Там була бібліотека, яка загортала операцію перетворення у функцію, яка замість того, щоб виконувати перетворення, робила перекладання точок в інший масив, який потім масштабувався в ще один масив і так далі. Виходив величезний call stack на 10 функцій. Десь «на дні» цього ланцюга була математика — буквально під усім кодом і функціями залишалась одна-єдина математична функція, яка фактично за все відповідала. Обгортка програми займала у 200 разів більше, ніж математична складова. Я переписав код, викинув обгортку (всі ті функції, які викликаються під «маркою» TransformPoints, але функціонально не роблять жодної корисної роботи, тільки «огортають» математику новими інтерфейсами), лишив тільки самі перетворення, і все почало працювати у 200 разів швидше.
Було так:
PointF[] xy = new PointF[256*ciH*ciW];
m.TransformPoints(xy);
TransformPoints під капотом викликає такий стек:
— System.Drawing.Drawing2D.Matrix.TransformPoints:
— System.Drawing.SafeNativeMethods.Gdip.ConvertPointToMemory,
— System.Drawing.SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF:
— System.Drawing.UnsafeNativeMethods.PtrToStructure:
— System.Drawing.Internal.GPPOINTF.ctor (which is empty, by the way),
— System.RuntimeType.CreateInstanceSlow:
— System.Runtime.InteropServices.Marshal.PtrToStructure.
Стало так:
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
float x = xy[i*W+j][0];
float y = xy[i*W+j][1];
float d_ = 1.0f / (M[2] * x +M[5] * y + M[8]);
xy[i*W+j][0] = (M[0] * x + M[3] * y + M[6]) * d_;
xy[i*W+j][1] = (M[1] * x + M[4] * y + M[7]) * d_;
}
}
Якщо ти знаєш математику — зможеш узяти функцію та спокійно переписати її. Я і зараз періодично цим займаюся. Якщо не знати математики й намагатися її уникнути, виникне громіздке нашарування функцій.
Знання з математики, геометрії необхідні для того, щоб не боятися їх використовувати для розв’язання власних задач. Якщо тобі буде необхідне проєктивне перетворення — ти зробиш саме його, а не переміщення, яке потребуватиме масштабування, а з ним й гомогенних координат, «найстрашнішої речі» в прикладній геометрії. Це страшно тільки вперше.
Довідка
Гомогенні (однорідні) координати — координати, що володіють властивістю, за якої об’єкт, що визначається цими координатами, не змінюється при множенні всіх координат на одне й те ж число, відмінне від нуля. За допомогою однорідних координат навіть координати нескінченно віддалених точок можна представити за допомогою скінченних координат. Формули, записані в однорідних координатах, найчастіше простіші та більш симетричні, ніж їхні вирази в декартових координатах.
Моїм першим місцем роботи була геймдев-компанія Bravo Interactive, тож я можу бути певен, що отримані знання можуть значно спростити життя розробників ігор. Першим моїм завданням було переписати шейдери із шейдерного семплера на шейдерну мову високого програмування. Це складно, особливо якщо не розумієш, що саме написано. Насправді ж це просто геометрія.
На цьому ж місці роботи я стикнувся з гомогенними координатами. Я заліз у код і помітив, що попри те, що в нас 3D-простір, усі координати складаються із чотирьох значень. Я запитав ліда, що саме це означає. Він дуже перелякано попросив нічого не чіпати. Але я розібрався в темі і зрозумів, що гомогенні координати — це крутий концепт.
З одного боку, ми робимо процес трохи складнішим, додаючи четверту координату, але потім вона значно спрощує нам життя. Наприклад, якщо вона дорівнюватиме одиниці, то все працюватиме як завжди — точка є точкою на своєму місці. Якщо ж координата дорівнюватиме нулю, то це буде не просто точка, а нескінченно віддалена точка в просторі.
Так значно простіше запрограмувати, припустимо, віртуальне сонце, коли є необхідність написати шейдер, що визначатиме освітлення певного об’єкта. Моделювати значно простіше, якщо сонце розміщене нескінченно далеко і всі промені йдуть паралельно один одному. Код стає менш громіздким та елегантнішим, адже не треба, наприклад, окремо прописувати віддаленість зірки — достатньо лише цифри 1 чи 0.
Тож знання з прикладної геометрії допомагають писати ефективніший код і не панікувати. Якщо знаєш, із чим маєш справу, ситуація, коли переляканий лід просить нічого не чіпати, ніколи не виникне.
«Головне завдання інженерів — розв’язати задачі, відповідей на які немає в підручниках»
Прикладна геометрія доречна в тих напрямах ІТ, де, власне, є геометрія: CAD (системи автоматизованого проєктування і розрахунку); CAE (здебільшого — підготовка моделей і візуалізація результатів); обробка зображень включно із комп’ютерним баченням; геоінформаційні системи; комп’ютерна графіка — від презентацій до кіно; віртуальна й доповнена реальності.
Сам я зараз працюю з 3D-друком, а там — купа геометрії. Моделі починаються та закінчуються нею. Один із розділів моєї книжки називається «Сплайни». Власне, усі продукти та коди, які ми виробляємо та пишемо, — це сплайни, просто ми про це не думаємо.
Довідка
Сплайн — функція, область визначення якої розбита на шматки, на кожному зі шматків функція є деяким поліномом (многочленом). У реальному світі велика кількість фізичних процесів за самою своєю природою є сплайнами. Наприклад, у механіці це деформація гнучкої пластини чи стержня, зафіксованих в окремих точках; траєкторія руху тіла, якщо сила, що діє на нього змінюється ступінчато (траєкторія штучного космічного об’єкта з активними та інерційними відрізками руху, траєкторія руху літака при ступінчатій зміні тяги двигунів та зміні профілю крила тощо).
Кожна літера цього тексту складається зі сплайнів Безьє. Кожна технічна поверхня, складніша за еліпсоїд, — наприклад, вигин комп’ютерної мишки, капот машини чи крило літака — це неуніформний раціональний базисний сплайн.
Майже кожен розділ моєї книжки завершується інженерією. Спочатку я розповідаю про те, як працює математика, а потім пропоную якусь задачку, у якій треба придумувати й вигадувати, займатися інноваціями — не просто йти за підручником. Тут допомагає інженерія. Головне завдання інженерів — розв’язати задачі, відповідей на які немає в підручниках. Інакше всіх інженерів давно би замінили бібліотекарі. Вони мають пробувати, помилятися, міряти й мріяти, вигадувати, винаходити, відкривати.
Читайте також блог Олександра КаленюкаСеред задач, які я прописав, — з’єднати точки на площині красивим гладким контуром, який би складався тільки з прямих і дуг. Як побудувати спряжені дуги так, щоб зберегти гладкість кривої — це математика, а як описати кожен конкретний контур так, щоб було красиво — це вже інженерія.
Я хотів, щоб мою книжку могли прочитати люди без особливих навичок, одразу після школи. Але зібравши фідбек, зрозумів, що ця ідея не зовсім працює. Непідготовлений читач, звісно, може подужати видання, але це буде складно. Коли я розумію, що не можу повноцінно описати якусь тему — надаю посилання на відповідний інтерактивний підручник.
Спеціальна підготовка допомагає зрозуміти книжку, як і під час будь-якого навчання. Коли ми з видавцем працювали над нею, то зрозуміли, що в математичній освіті більше стресу, ніж потрібно. Звісно, він має бути в невеликих кількостях, адже навчання — це робота, однак іноді людей це зупиняє, вони не хочуть читати, адже впевнені, що нічого не зрозуміють. Але це нормально! Я написав книжку, втім досі не все розумію в прикладній геометрії. Адже завжди можна перечитати навчальний матеріал на складну тему, а потім піти шукати нову інформацію та розширювати свої знання.