Escapist Marginalia

User Preferences

Interface language

Theme

vector

Библиотека для работы с евклидовыми векторами, написанная на TypeScript.

Обновлялось

Мотивация#

С университетских времён меня увлекали различные математические визуализации. В то время это выглядело ужасно сложным, не возникало и мысли попробовать сделать что-то самостоятельно. Заметно позже, увлёкшись программированием, натолкнулся на замечательный канал The Coding Train. Лектором канала является Дэниел Шиффман, ведущий увлекательные лекции, посвященные самым различным темам на JavaScript, в том числе и серию испытаний, на которых в режиме реального времени лектор реализовывал идеи, предложенные подписчиками.

Повторяя за лектором, испытание за испытанием, я научился многому. В основном Дэниел на своём канале использует библиотеку p5js. Данная библиотека сама по себе является отличным инструментом для новичков, позволяющей творить в максимально минимальные сроки. Со временем, набравшись опыта и имея стремление пытаться сделать что-то самостоятельно и с желанием понять принцицы работы, решил отойти от использования данной библиотеки. В этом было достаточно много плюсов; например, я изучил Canvas API, и перестал тащить за собой кучу неиспользуемого кода из библиотеки (а сам по себе p5js не маленький - почти целый мегабайт в сжатом виде).

Перестав использовать библиотеку, я потерял доступ к некоторым важным сущностям. Одной из них является P5.Vector, представляющей собой вектор в евклидовом пространстве, реализацию которой представляет p5js “из коробки”. Множество визуализаций используют вектора, что делает код простым и читабельным.

Именно для этих целей и была написана библиотека vector. Изучив имеющиеся альтернативы и собрав всё лучшее воедино, теперь я имею под рукой удобный и многофункциональный инструмент для собственных нужд.

Функционал#

vector представляет собой библиотеку для работы с векторами, написанную на TypeScript.

Попробовать библиотеку в деле можно с помощью npm:

npm i @ericrovell/vector

Далее, необходимо импортировать функцию vector и можно начинать работу:

import { vector } from "@ericrovell/vector";

const v1 = vector(1, 2, 3);
console.log(vector.toString()); // "(1, 2, 3)"

Ввод#

Одним из преимуществ библиотеки является гибкость пользовательского ввода.

Конструктор vector позволяет использовать декартову систему координат тройкой аргументов, объектом или массивом. Помимо декартовой системы координат конструктор поддерживает полярную и цилиндрическую системы координат. Необходимые типы уже включены в пакет:

import type { Cartesian, Polar, Cylindrical } from "@ericrovell/vector";

// Cartesian
vector(1, 2, 3);
vector([ 1, 2, 3]);
vector({ x: 1, y: 2, z: 3} as Cartesian);

// Polar
vector({
	phi: Math.PI,
	theta: Math.PI / 2,
	magnitude: 5
} as Polar);

// Cylindrical
vector({
	phi: Math.PI,
	p: 5,
	z: 8
} as Cylindrical);

Методы#

Все методы, принимающие вектор как аргумент, обладают той же гибкостью и принимают вышеперечисленные типы данных на ввод. Конечно же, можно использовать и другие экземпляры vector:

import { vector } from "@ericrovell/vector";

const v1 = vector(1, 2, 3);
const v2 = vector({ x: -1, y: -2, z: -3 });

console.log(
	v1.add({ x: -1, y: -2, z: -3 }).toString()
); // -> "(0, 0, 0)"

console.log(
	v1.add(v2).toString()
); // -> "(0, 0, 0)"

Иммутабельность#

Библиотека предоставляет возможность работать в функциональном, иммутабельном стиле. Тем не менее, у большей части методов существует и мутабельный “метод-близнец”. В библиотеке используется соглашение, что мутабельные методы используют постфикс self: .add() и .addSelf().

Что я узнал нового#

В процессе работы над библиотекой я узнал множество мелких, тем не менее важных деталей, необходимых для публикации качественного npm пакета.

В процессе работы над библиотекой узнал и применил на практике некоторые символы, с помощью которых можно добавить функционала экземплярам класса. Например, с помощью Symbol.iterator экземляр vector можно использовать в for ... of циклах, а используя Symbol.toPrimitive можно добавить возможность приведения типов. По сути, небольшие мелочи, без которых вполне можно обойтись, однако делающие библиотеку чуть практичнее.

Помимо вышеперечисленного, удалось освежить знания линейной алгебры.