Skip to content

GyverLibs/GVector

Repository files navigation

latest PIO Foo Foo Foo

Foo

GVector

Библиотека для работы с 2-х мерными векторами

Совместимость

Совместима со всеми Arduino платформами (используются Arduino-функции)

Содержание

Использование

Класс GVector

Конструктор и доступ

float x = 0;
float y = 0;

// доступ как vector[0] vector[1]
float& operator[](uint8_t i);

constexpr GVector();
constexpr GVector(float x, float y);

Фабрики

// создать из угла (единичный)
static GVector fromAngle(float rad);

// создать из полярных координат
static GVector fromPolar(float rad, float mag);

// создать нулевой
static GVector fromZero();

Статические методы

// из радиан в градусы
static float toDeg(float rad);

// из градусов в радианы
static float toRad(float deg);

// кратчайший угол поворота из from в to (радианы)
static float shortAngle(float from, float to);

// кратчайший угол поворота из from в to (градусы)
static int shortAngleDeg(int from, int to);

// угол между
static float angleBetween(const GVector& a, const GVector& b);

// расстояние между в квадрате
static float distSq(const GVector& a, const GVector& b);

// расстояние между
static float dist(const GVector& a, const GVector& b);

// скалярное произведение (== 0 - перпендикулярны, > 0 в одну сторону, < 0 в противоположные)
static float dot(const GVector& a, const GVector& b);

// векторное произведение (< 0 — по часовой, > 0 против часовой)
static float cross(const GVector& a, const GVector& b);

// векторная проекция на другой вектор
static GVector project(const GVector& a, const GVector& b);

// проекция точки P на линию AB
static GVector projectPoint(const GVector& A, const GVector& B, const GVector& P);

// расстояние (перпендикуляр) от точки P до линии AB
static float distToLine(const GVector& A, const GVector& B, const GVector& P);

// сложить
static GVector add(const GVector& v1, const GVector& v2);
static GVector add(const GVector& v1, float s);

// вычесть
static GVector sub(const GVector& v1, const GVector& v2);
static GVector sub(const GVector& v1, float s);

// умножить
static GVector mul(const GVector& v1, const GVector& v2);
static GVector mul(const GVector& v1, float s);

// разделить
static GVector div(const GVector& v1, const GVector& v2);
static GVector div(const GVector& v1, float s);

Арифметика

// ================ ADD ================
GVector& add(float v);
GVector& operator+=(float v);
GVector operator+(float v);

GVector& add(const GVector& v);
GVector& operator+=(const GVector& v);
GVector operator+(const GVector& v);

// ================ SUB ================
GVector& sub(float v);
GVector& operator-=(float v);
GVector operator-(float v);

GVector& sub(const GVector& v);
GVector& operator-=(const GVector& v);
GVector operator-(const GVector& v);

GVector operator-();

// ================ MUL ================
GVector& mul(float v);
GVector& operator*=(float v);
GVector operator*(float v);

GVector& mul(const GVector& v);
GVector& operator*=(const GVector& v);
GVector operator*(const GVector& v);

// ================ DIV ================
GVector& div(float v);
GVector& operator/=(float v);
GVector operator/(float v);

GVector& div(const GVector& v);
GVector& operator/=(const GVector& v);
GVector operator/(const GVector& v);

Сравнение

// проверка равенства с учетом epsilon
bool equals(const GVector& v, float tolerance = 1e-6f);

bool operator==(const GVector& v);

bool operator!=(const GVector& v);

// проверка на нулевую длину
operator bool();

Получение

// создать копию
GVector copy();

// длина в квадрате
float magSq();

// длина
float mag();

// скалярное произведение (== 0 - перпендикулярны, > 0 в одну сторону, < 0 в противоположные)
float dot(const GVector& v);

// векторное произведение (поворот к v: < 0 — по часовой, > 0 против часовой)
float cross(const GVector& v);

// сравнение по направлению с угловой толерантностью
bool isParallelTo(const GVector& v, float tolerance = 1e-6f);

// угол между
float angleBetween(const GVector& v);

// нормаль
GVector normal();

// нормализованная копия
GVector normalized();

// длина проекции на вектор
float projectMag(const GVector& v);

// векторная проекция на другой вектор
GVector project(const GVector& v);

// проекция точки на линию AB
GVector projectPoint(const GVector& A, const GVector& B);

// расстояние (перпендикуляр) до линии AB
float distToLine(const GVector& A, const GVector& B);

// расстояние в квадрате
float distSq(const GVector& v);

// расстояние до
float dist(const GVector& v);

// текущий угол между вектором и осью X
float heading();

// текущий угол между вектором и осью X
float headingDeg();

// проверка на ноль или epsilon
bool isZero(float epsilon = 1e-6f);

Модификация

// установить
inline GVector& set(float x, float y);

// установить в 0
GVector& setZero();

// повернуть на угол
GVector& rotate(float rad);

// повернуть по направлению вектора
GVector& rotateTo(const GVector& target);

// повернуть на +90°
GVector& rotate90CCW();

// повернуть на -90°
GVector& rotate90CW();

// повернуть на 180 (отразить вдоль себя)
GVector& rotate180();

// отразить по оси Х
GVector& reflectX();

// отразить по оси Y
GVector& reflectY();

// отразить по нормали (должна быть нормализована)
GVector& reflect(const GVector& normal);

// нормализовать
GVector& normalize();

// установить длину
GVector& setMag(float v);

// ограничить длину сверху
GVector& limit(float mag);

// ограничить длину в диапазоне
GVector& clamp(float minm, float maxm);

// установить направление
GVector& setHeading(float rad);

// установить направление
GVector& setHeadingDeg(int deg);

// интерполировать текущий вектор к v, где t — коэффициент от 0.0 до 1.0.
GVector& lerp(const GVector& v, float t);

Матрица

// умножить на матрицу
static GVector mul(const GVector& v, const GMatrix& mx);
GVector operator*(const GMatrix& mx);

GVector& apply(const GMatrix& mx);
GVector& operator*=(const GMatrix& mx);

Класс GMatrix

Конструктор и доступ

GMatrix();

// доступ как matrix[0][0]
float* operator[](uint8_t i);

Фабрики

// единичная матрица
static GMatrix identity();

// матрица поворота
static GMatrix rotation(float rad);

// матрица сдвига
static GMatrix translation(float dx, float dy);

// матрица масштабирования
static GMatrix scaling(float sx, float sy);

// матрица масштабирования
static GMatrix scaling(float sxy);

Получение

// умножение на другую матрицу
GMatrix operator*(const GMatrix& other);

// обратная матрица
GMatrix inverted();

// транспонированная матрица
GMatrix transposed();

Декомпозиция

struct Decomposed {
    float angle;   // угол в радианах
    float sx, sy;  // масштабы по осям
    float tx, ty;  // сдвиг по осям
};

// разложить на составляющие
Decomposed decompose();

Изменение

// умножить на другую матрицу
GMatrix& mul(const GMatrix& other);
GMatrix& operator*=(const GMatrix& other);

// сделать единичной
GMatrix& reset();

// повернуть
GMatrix& rotate(float rad);

// переместить
GMatrix& translate(float dx, float dy);

// масштабировать
GMatrix& scale(float sx, float sy);
GMatrix& scale(float sxy);

// транспонировать
GMatrix& transpose();

// инвертировать
GMatrix& invert();

Примеры

Движение с отскоком

int w = 200, h = 100;
GVector pos(w / 2, h / 2);
GVector vel(3, 2);

void loop() {
    pos += vel;
    if (pos.x >= w || pos.x < 0) {
        pos.x = constrain(pos.x, 0, w - 1);
        vel.reflectY();
    }
    if (pos.y >= h || pos.y < 0) {
        pos.y = constrain(pos.y, 0, h - 1);
        vel.reflectX();
    }
    delay(30);
}

Расстояние между точками

GVector A(10, 20);
GVector B(30, 40);
GVector AB = B - A;
float dist = AB.mag();

Смещение, поворот и масштаб прямоугольника

// координаты углов
GVector corners[] = {
    GVector(0, 0),
    GVector(10, 0),
    GVector(10, 5),
    GVector(0, 5),
};

// создаём матрицу. Применяется в обратном порядке!
GMatrix transform = GMatrix::translation(x, y).rotate(PI / 4).scale(5);

// применяем к точкам
for (int i = 0; i < 4; i++) corners[i].apply(transform);

Версии

  • v1.0

Установка

  • Библиотеку можно найти по названию GVector и установить через менеджер библиотек в:
    • Arduino IDE
    • Arduino IDE v2
    • PlatformIO
  • Скачать библиотеку .zip архивом для ручной установки:
    • Распаковать и положить в C:\Program Files (x86)\Arduino\libraries (Windows x64)
    • Распаковать и положить в C:\Program Files\Arduino\libraries (Windows x32)
    • Распаковать и положить в Документы/Arduino/libraries/
    • (Arduino IDE) автоматическая установка из .zip: Скетч/Подключить библиотеку/Добавить .ZIP библиотеку… и указать скачанный архив
  • Читай более подробную инструкцию по установке библиотек здесь

Обновление

  • Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
  • Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
  • Вручную: удалить папку со старой версией, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!

Баги и обратная связь

При нахождении багов создавайте Issue, а лучше сразу пишите на почту alex@alexgyver.ru
Библиотека открыта для доработки и ваших Pull Request'ов!

При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:

  • Версия библиотеки
  • Какой используется МК
  • Версия SDK (для ESP)
  • Версия Arduino IDE
  • Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
  • Какой код загружался, какая работа от него ожидалась и как он работает в реальности
  • В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код

About

Библиотека для работы с 2-х мерными векторами

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages