Как нарисовать стрелку
Лично у меня такая задача возникала не один раз, поэтому придется посвятить ей целый пост.
Итак, даны координаты начала и конца вектора, надо нарисовать стрелку.
Результат будет вот такой:
А теперь к тому, как собственно рисуется стрелка. Чертеж, сделанный в paint (кликабельно):
Повернем точку B вокруг точки A на alpha и на -alpha. Укоротим полученные векторы так, чтобы их длина составляла M (M <= 1) от длины вектора AB. Тогда получим векторы AC и AD.
Соединим точки A и B, B и C, B и D отрезками – стрелка нарисована.
Теперь как это выглядит конкретно на C++ и SFML:
void RotatePoint(double &x, double &y, double ox, double oy, double alpha)
{
double xn, yn;
xn = ox + (x-ox)*cos(alpha) - (y-oy)*sin(alpha);
yn = oy + (x-ox)*sin(alpha) + (y-oy)*cos(alpha);
x = xn;
y = yn;
}
void DecreaseVector(double x1, double y1, double &x_n1, double &y_n1)
{
double dx = (x_n1 - x1)*0.9;
double dy = (y_n1 - y1)*0.9;
x_n1 = x1 + dx;
y_n1 = y1 + dy;
}
void SFMLVizualizer::DrawArrow(int x1, int y1, int x2, int y2, int icolor)
{
int red, green, blue;
blue = icolor%255;
icolor/=255;
green = icolor%255;
icolor/=255;
red = icolor;
sf::Color color = sf::Color(red, green, blue);
int line_width = 1;
w->Draw(sf::Shape::Line(x1, y1, x2, y2, line_width, color));
double x_n1, y_n1, x_n2, y_n2;
x_n1 = x_n2 = x2;
y_n1 = y_n2 = y2;
RotatePoint(x_n1, y_n1, x1, y1, pi/48);
RotatePoint(x_n2, y_n2, x1, y1, -pi/48);
DecreaseVector(x1, y1, x_n1, y_n1);
DecreaseVector(x1, y1, x_n2, y_n2);
w->Draw(sf::Shape::Line(x_n1, y_n1, x2, y2, line_width, color));
w->Draw(sf::Shape::Line(x_n2, y_n2, x2, y2, line_width, color));
}
Такие стрелочки имеют свойство масштабироваться в зависимости от длины вектора. Выглядит очень симпатично, я даже сам не ожидал такого!

