Перейти к содержанию
    

Как нарисовать стрелку в С++?

Есть x1,y1 начало линии и x2,y2 конец линии. Нарисовать в конце линии две линии образующие крылья стрелки. Координаты x1,y1,x2,y2 будут задаваться произвольно, направление крыльев стрелки должно меняться автоматически.

 

Стрелка должна отображатся в Image :smile3046:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть x1,y1 начало линии и x2,y2 конец линии. Нарисовать в конце линии две линии образующие крылья стрелки. Координаты x1,y1,x2,y2 будут задаваться произвольно, направление крыльев стрелки должно меняться автоматически.

что такое sin и cos знаем?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Знаю но как их применить?

Вы знаете координаты начала и конца.

Считаете угол наклона линии.

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы знаете координаты начала и конца.

Считаете угол наклона линии.

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

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

 

спасибо :rolleyes: , но серавно не понял :smile3046:

 

спасибо :rolleyes: , но серавно не понял :smile3046:

 

Верней понял но не знаю как применить

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы знаете координаты начала и конца.

Считаете угол наклона линии.

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

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

Прямой, но неэффективный и неинтересный подход, применимый только для примитивных стрелок. А как быть, если стрелку хочется с непрямыми усами, а хотя бы полукруглыми, наполовину закрашенными ?

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

Для новичков - алгоритм следующий: 1) рисуем в любом графическом редакторе черно-белую стрелку, какую хочется, но направленную строго слева направо, в разрешении, например 8x8 пикселей; 2) затаскиваем массив отрисованных пикселей к себе в программу, причем удобно хранить массив в полярной системе координат с полюсом в точке, на которую указывает стрелка; каждая точка задается парой чисел (R, fi); 3) для того, чтобы вывести эту стрелку на экран достаточно посчитать угол наклона прямой, добавить этот угол ко всем полярным координатам точек и перевести новые полярные координаты в экранные по формулам x=x2+R*cos(fi); y=y2+R*sin(fi).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

удобно хранить массив в полярной системе координат с центром в точке, на которую указывает стрелка; каждая точка задается парой чисел (R, fi); 3) для того, чтобы вывести эту стрелку на экран достаточно посчитать угол наклона прямой, добавить этот угол ко всем полярным координатам точек и перевести новые полярные координаты в экранные по формулам x=x2+R*cos(fi); y=y2+R*sin(fi).

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Не очень понял, почему должен быть больше ? Можно хранить 1:1, причём, учитывая всё же, что это стрелка, можно хранить полярные координаты только рисуемых точек, что сильно сократит объём массива.

Или вводить интерполяцию попикселям, что скажется на качестве.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не очень понял, почему должен быть больше ? Можно хранить 1:1, причём, учитывая всё же, что это стрелка, можно хранить полярные координаты только рисуемых точек, что сильно сократит объём массива.

Пропущенные пиксели будут.

 

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

Аднозначно будут.

Тем более, я предлагал через тригонометрию посчитать две точки, вы предлагаете ВСЕ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пропущенные пиксели будут.

 

 

Аднозначно будут.

Тем более, я предлагал через тригонометрию посчитать две точки, вы предлагаете ВСЕ.

Думаю первый способ проще , ну плиииииииииззз киньте кость я в смысле по какой формуле можно енто дело расчетать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

плиииииииииззз киньте кость я в смысле по какой формуле можно енто дело расчетать?
Если в двух словах, то:

1. Находите точку на Вашей линии, отстоящую от конца линии на длину стрелки.

2. Поворачиваете её вокруг точки конца линии на угол "развода" линий стрелки.

3. Проводите линию от этой точки до конца линии

4. Повторяете п.2 и 3, но с поворотом в другую сторону

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я рисовал в фотошопе стрелку - потом поворачивал её на нужный угол - и записывал. Попробуйте сделать хоть 36 образов стрелки и взяв угол с точностью 10 градусов выбрать нужный имедж для рисованя

 

 

    static UINT ids [12] = 
    {
        IDI_ARROW_0G0, IDI_ARROW_0G1, IDI_ARROW_0G2, IDI_ARROW_0G3, 
        IDI_ARROW_0G4, IDI_ARROW_0G5, IDI_ARROW_0G6, IDI_ARROW_0G7, 
        IDI_ARROW_0G8, IDI_ARROW_0G9, IDI_ARROW_0G10, IDI_ARROW_0G11, 

    };
    for (int i = 0; i < 12; ++ i)
    {
        arrowPoint [i] = AfxGetApp()->LoadIcon(ids [i]);
    }

...

    {
        int iangle = ((m_iAngle - m_iOffset + FULL_CIRCLE)%(FULL_CIRCLE));
        double angle = iangle / 3600 * PI * 2 / 360;

        int yTarget = - (int) (radius * cos(angle) * 0.85);
        int xTarget = (int) (radius * sin(angle) * 0.85);
        int yTarget0 = - (int) (radius * cos(angle) * 0.1);
        int xTarget0 = (int) (radius * sin(angle) * 0.1);

        m_invisibleDc.SelectObject(m_darkRedPen);
        m_invisibleDc.SelectObject(m_darkRedBrush);

        m_invisibleDc.MoveTo(cpt.x + xTarget0, cpt.y + yTarget0);
        VERIFY(m_invisibleDc.LineTo(cpt.x + xTarget, cpt.y + yTarget));

        {
            int zoneAngle = ((iangle + 15 * 3600) / (3600 * 30)) % 12;
            ASSERT(zoneAngle < 12);
            CPoint cp = CPoint(cpt.x + xTarget, cpt.y + yTarget);
            VERIFY(m_invisibleDc.DrawIcon(cp.x + iconXOffset, cp.y + iconYOffset, arrowPoint [zoneAngle]));
        }
    }

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

image1.Canvas.Pen.Width:=1;
image1.Canvas.lineto(20,20);
image1.Canvas.Pen.width:=5;
image1.Canvas.lineto(21,21);
image1.Canvas.Pen.width:=4;
image1.Canvas.lineto(22,22);
image1.Canvas.Pen.width:=3;
image1.Canvas.lineto(23,23);
image1.Canvas.Pen.width:=2;
image1.Canvas.lineto(24,24);
image1.Canvas.Pen.width:=1;
image1.Canvas.lineto(25,25);

 

За пят точек до конца линии устанавливаем ширину линии 5, к примеру, и далее рисуем по одному шагу с уменьшением ширины. Получается нормальная стрелка.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...