Стрелка позиционируется в конце отрезка. У стрелки есть длина и размах - параметры стрелки.
Вектор направления стрелки - это единичный нуль-вектор из начала отрезка, направленный в сторону его конца.
Длина стрелки откладывается вдоль инвертированного вектора направления, от конца отрезка.
Перпендикуляр в 2D-системе строится через перестановку координат. Перестановка координат вектора направления стрелки позволит получить направление одного плеча размаха, инверсия перпендикуляра - направление другого плеча размаха.
Так получается четыре точки самой стрелки: конец отрезка, точка длины стрелки и две точки размаха стрелки.
Для постройки стрелки требуется всего два вектора-направления. Первый - это arrow_length_direction = Normalize(finish - start), где finish - это конец отрезка, а start - это его начало.
Точка длины стрелки считается так:
, где arrow_length - это длина стрелки.
Второй вектор-направление - это вектор одного плеча стрелки. Он строится как перпендикуляр направления стрелки:
(в 2D-системах перпендикуляр - это перестановка координат единичного вектора). Этот вектор тоже будет нормализованным, т.к. вектор направления стрелки уже нормализован.
После этого, от точки длины стрелки откладываем две точки размаха стрелки:
Кратко так - представь, что ты рисуешь треугольник в начале координат (0, 0). Поверни его вокруг начала координат (матрицей поворота), и затем смести его так, чтобы координаты конца отрезка совпали с координатами вершины треугольника. Для этого просто прибавь dx и dy.