|
|
  |
Как нарисовать стрелку в С++?, Рисование в Image |
|
|
|
May 12 2009, 11:02
|
Группа: Новичок
Сообщений: 6
Регистрация: 12-05-09
Пользователь №: 48 956

|
Есть x1,y1 начало линии и x2,y2 конец линии. Нарисовать в конце линии две линии образующие крылья стрелки. Координаты x1,y1,x2,y2 будут задаваться произвольно, направление крыльев стрелки должно меняться автоматически. Стрелка должна отображатся в Image
|
|
|
|
|
May 12 2009, 11:23
|
Группа: Новичок
Сообщений: 6
Регистрация: 12-05-09
Пользователь №: 48 956

|
Цитата(Methane @ May 12 2009, 15:14)  что такое sin и cos знаем? Знаю но как их применить?
|
|
|
|
|
May 12 2009, 11:26
|

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

|
Цитата(skyfoxx @ May 12 2009, 14:23)  Знаю но как их применить? Вы знаете координаты начала и конца. Считаете угол наклона линии. Потом прикидываете на какой угол у вас должны быть развернуты углы стрелки. Потом находите точки, конца стрелки. Проводите линии. Нарисуйте на бумажке, и распишите углы. Сразу станет ясно.
|
|
|
|
|
May 12 2009, 11:55
|
Группа: Новичок
Сообщений: 6
Регистрация: 12-05-09
Пользователь №: 48 956

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

Знающий
   
Группа: Свой
Сообщений: 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).
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
May 12 2009, 13:18
|

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

|
Цитата(Methane @ May 12 2009, 17:04)  Уж если мой не удобный и не эффективный, то как назвать ваш метод я не знаю. К примеру размер стрелки в полярных координатах должен быть значительно больше реальной стрелки. Не очень понял, почему должен быть больше ? Можно хранить 1:1, причём, учитывая всё же, что это стрелка, можно хранить полярные координаты только рисуемых точек, что сильно сократит объём массива. Цитата(Methane @ May 12 2009, 17:04)  Или вводить интерполяцию попикселям, что скажется на качестве. Интерполяция тут не нужна, а для масштабирования стрелки достаточно умножить полярную координату R для каждой точки на нужный коэффициент.
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
May 12 2009, 13:26
|

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

|
Цитата(Demeny @ May 12 2009, 16:18)  Не очень понял, почему должен быть больше ? Можно хранить 1:1, причём, учитывая всё же, что это стрелка, можно хранить полярные координаты только рисуемых точек, что сильно сократит объём массива. Пропущенные пиксели будут. Цитата Интерполяция тут не нужна, а для масштабирования стрелки достаточно умножить полярную координату R для каждой точки на нужный коэффициент. Аднозначно будут. Тем более, я предлагал через тригонометрию посчитать две точки, вы предлагаете ВСЕ.
|
|
|
|
|
May 12 2009, 13:56
|
Группа: Новичок
Сообщений: 6
Регистрация: 12-05-09
Пользователь №: 48 956

|
Цитата(Methane @ May 12 2009, 17:26)  Пропущенные пиксели будут.
Аднозначно будут. Тем более, я предлагал через тригонометрию посчитать две точки, вы предлагаете ВСЕ. Думаю первый способ проще , ну плиииииииииззз киньте кость я в смысле по какой формуле можно енто дело расчетать?
|
|
|
|
|
May 12 2009, 14:13
|

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

|
Цитата(skyfoxx @ May 12 2009, 16:56)  плиииииииииззз киньте кость я в смысле по какой формуле можно енто дело расчетать? Если в двух словах, то: 1. Находите точку на Вашей линии, отстоящую от конца линии на длину стрелки. 2. Поворачиваете её вокруг точки конца линии на угол "развода" линий стрелки. 3. Проводите линию от этой точки до конца линии 4. Повторяете п.2 и 3, но с поворотом в другую сторону
|
|
|
|
|
May 12 2009, 17:41
|

Профессионал
    
Группа: Участник
Сообщений: 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
|
|
|
|
|
May 13 2009, 05:25
|
Группа: Новичок
Сообщений: 6
Регистрация: 12-05-09
Пользователь №: 48 956

|
Всем спасиб разобрался
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|