реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Как нарисовать стрелку в С++?, Рисование в Image
skyfoxx
сообщение May 12 2009, 11:02
Сообщение #1





Группа: Новичок
Сообщений: 6
Регистрация: 12-05-09
Пользователь №: 48 956



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

Стрелка должна отображатся в Image smile3046.gif
Go to the top of the page
 
+Quote Post
Methane
сообщение May 12 2009, 11:14
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 615
Регистрация: 12-01-09
Из: США, Главное разведовательное управление
Пользователь №: 43 230



Цитата(skyfoxx @ May 12 2009, 14:02) *
Есть x1,y1 начало линии и x2,y2 конец линии. Нарисовать в конце линии две линии образующие крылья стрелки. Координаты x1,y1,x2,y2 будут задаваться произвольно, направление крыльев стрелки должно меняться автоматически.

что такое sin и cos знаем?
Go to the top of the page
 
+Quote Post
skyfoxx
сообщение May 12 2009, 11:23
Сообщение #3





Группа: Новичок
Сообщений: 6
Регистрация: 12-05-09
Пользователь №: 48 956



Цитата(Methane @ May 12 2009, 15:14) *
что такое sin и cos знаем?


Знаю но как их применить?
Go to the top of the page
 
+Quote Post
Methane
сообщение May 12 2009, 11:26
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 615
Регистрация: 12-01-09
Из: США, Главное разведовательное управление
Пользователь №: 43 230



Цитата(skyfoxx @ May 12 2009, 14:23) *
Знаю но как их применить?

Вы знаете координаты начала и конца.
Считаете угол наклона линии.
Потом прикидываете на какой угол у вас должны быть развернуты углы стрелки.
Потом находите точки, конца стрелки. Проводите линии. Нарисуйте на бумажке, и распишите углы. Сразу станет ясно.
Go to the top of the page
 
+Quote Post
skyfoxx
сообщение May 12 2009, 11:55
Сообщение #5





Группа: Новичок
Сообщений: 6
Регистрация: 12-05-09
Пользователь №: 48 956



Цитата(Methane @ May 12 2009, 15:26) *
Вы знаете координаты начала и конца.
Считаете угол наклона линии.
Потом прикидываете на какой угол у вас должны быть развернуты углы стрелки.
Потом находите точки, конца стрелки. Проводите линии. Нарисуйте на бумажке, и распишите углы. Сразу станет ясно.


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

Цитата(skyfoxx @ May 12 2009, 15:40) *
спасибо rolleyes.gif , но серавно не понял smile3046.gif


Верней понял но не знаю как применить
Go to the top of the page
 
+Quote Post
Demeny
сообщение May 12 2009, 13:00
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(Methane @ May 12 2009, 15:26) *
Вы знаете координаты начала и конца.
Считаете угол наклона линии.
Потом прикидываете на какой угол у вас должны быть развернуты углы стрелки.
Потом находите точки, конца стрелки. Проводите линии. Нарисуйте на бумажке, и распишите углы. Сразу станет ясно.

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


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
Methane
сообщение May 12 2009, 13:04
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 615
Регистрация: 12-01-09
Из: США, Главное разведовательное управление
Пользователь №: 43 230



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

Уж если мой не удобный и не эффективный, то как назвать ваш метод я не знаю. К примеру размер стрелки в полярных координатах должен быть значительно больше реальной стрелки. Или вводить интерполяцию попикселям, что скажется на качестве.
Go to the top of the page
 
+Quote Post
Demeny
сообщение May 12 2009, 13:18
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(Methane @ May 12 2009, 17:04) *
Уж если мой не удобный и не эффективный, то как назвать ваш метод я не знаю. К примеру размер стрелки в полярных координатах должен быть значительно больше реальной стрелки.

Не очень понял, почему должен быть больше ? Можно хранить 1:1, причём, учитывая всё же, что это стрелка, можно хранить полярные координаты только рисуемых точек, что сильно сократит объём массива.
Цитата(Methane @ May 12 2009, 17:04) *
Или вводить интерполяцию попикселям, что скажется на качестве.

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


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
Methane
сообщение May 12 2009, 13:26
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 615
Регистрация: 12-01-09
Из: США, Главное разведовательное управление
Пользователь №: 43 230



Цитата(Demeny @ May 12 2009, 16:18) *
Не очень понял, почему должен быть больше ? Можно хранить 1:1, причём, учитывая всё же, что это стрелка, можно хранить полярные координаты только рисуемых точек, что сильно сократит объём массива.

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

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

Аднозначно будут.
Тем более, я предлагал через тригонометрию посчитать две точки, вы предлагаете ВСЕ.
Go to the top of the page
 
+Quote Post
skyfoxx
сообщение May 12 2009, 13:56
Сообщение #10





Группа: Новичок
Сообщений: 6
Регистрация: 12-05-09
Пользователь №: 48 956



Цитата(Methane @ May 12 2009, 17:26) *
Пропущенные пиксели будут.


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

Думаю первый способ проще , ну плиииииииииззз киньте кость я в смысле по какой формуле можно енто дело расчетать?
Go to the top of the page
 
+Quote Post
Палыч
сообщение May 12 2009, 14:13
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(skyfoxx @ May 12 2009, 16:56) *
плиииииииииззз киньте кость я в смысле по какой формуле можно енто дело расчетать?
Если в двух словах, то:
1. Находите точку на Вашей линии, отстоящую от конца линии на длину стрелки.
2. Поворачиваете её вокруг точки конца линии на угол "развода" линий стрелки.
3. Проводите линию от этой точки до конца линии
4. Повторяете п.2 и 3, но с поворотом в другую сторону
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение May 12 2009, 17:41
Сообщение #12


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Я рисовал в фотошопе стрелку - потом поворачивал её на нужный угол - и записывал. Попробуйте сделать хоть 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 - May 12 2009, 17:43
Go to the top of the page
 
+Quote Post
DpInRock
сообщение May 12 2009, 18:31
Сообщение #13


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Код
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, к примеру, и далее рисуем по одному шагу с уменьшением ширины. Получается нормальная стрелка.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
skyfoxx
сообщение May 13 2009, 05:25
Сообщение #14





Группа: Новичок
Сообщений: 6
Регистрация: 12-05-09
Пользователь №: 48 956



Всем спасиб разобрался smile.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th July 2025 - 00:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01569 секунд с 7
ELECTRONIX ©2004-2016