Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Рисуем стрелку.


Автор: Elfet 4.12.2006, 16:11
Есть координаты двух точек. На одном конце этого отрезка нужно нарисовать стрелку по заданной длине и ширине (получить координаты двух точек)  smile 
user posted image

Автор: Sartorius 4.12.2006, 16:16
 Если есть возможность использовать GDI+, то там такое уже есть. Если нет - то просто возьми точку на отрезке на нужном расстоянии от конца и поверни относительно него на нужный угол по часовой и в обратном направлении 
Вот на всякий случай оператор поворота на угол А
!cosA    -sinA!     ! x !
!sinA     cosA!  * ! y !

ЗЫ а вообще тема обсуждалась пару недель назад... тока найти чего то не могу

Автор: Elfet 4.12.2006, 17:07
 smile как делать я тоже представляю, но вот не получается ;)

Автор: SoWa 4.12.2006, 20:44
Код

procedure DrawArrow(x0,y0,x1,y1: integer; l,ygol: real);
var
c: TCanvas;
alpha, beta: real;
xk1,xk2,yk1,yk2: integer;
begin
c:=Form1.Image1.Canvas;

c.Pen.Color:=clblack;
c.MoveTo(x0,y0);
c.LineTo(x1,y1);


if (y1-y0)=0 then
begin
alpha:=0;
end else
alpha:=arctan(abs(x1-x0)/abs(y1-y0));

alpha:=90- RadToDeg(alpha);



{V}if (x1<x0)and(y1<y0) then
begin
beta:=degtoRad(alpha+ygol);

xk1:=trunc(x1-(l*cos(beta-180)));
yk1:=trunc(y1-(l*sin(beta-180)));
c.MoveTo(x1,y1);
c.LineTo(xk1, yk1);

beta:=degtoRad(alpha-ygol);

xk2:=trunc(x1-(l*cos(beta-90)));
yk2:=trunc(y1-(l*sin(beta-90)));
c.MoveTo(x1,y1);
c.LineTo(xk2, yk2);
end;

{V} if (x1> x0)and(y1>y0) then
begin
beta:=degtoRad(alpha+ygol);

xk1:=trunc(x1-(l*cos(beta)));
yk1:=trunc(y1-(l*sin(beta)));
c.MoveTo(x1,y1);
c.LineTo(xk1, yk1);

beta:=degtoRad(alpha-ygol);

xk2:=trunc(x1-(l*cos(beta)));
yk2:=trunc(y1-(l*sin(beta)));
c.MoveTo(x1,y1);
c.LineTo(xk2, yk2);
end;

{V}if (x1< x0)and(y1>y0) then
begin
beta:=degtoRad(alpha+ygol);

xk1:=trunc(x1+(l*cos(beta)));
yk1:=trunc(y1-(l*sin(beta)));
c.MoveTo(x1,y1);
c.LineTo(xk1, yk1);

beta:=degtoRad(alpha-ygol);

xk2:=trunc(x1+abs(l*cos(beta)));
yk2:=trunc(y1+abs(l*sin(beta)));
c.MoveTo(x1,y1);
c.LineTo(xk2, yk2);
end;

if (x1>x0)and(y1<y0) then
begin
beta:=degtoRad(180- (180-(alpha+ygol)));

xk1:=trunc(x1-(l*cos(beta)));
yk1:=trunc(y1+(l*sin(beta)));
c.MoveTo(x1,y1);
c.LineTo(xk1, yk1);

beta:=degtoRad(180-(ygol+(180-alpha)));

xk2:=trunc(x1-(l*cos(beta)));
yk2:=trunc(y1+(l*sin(beta)));
c.MoveTo(x1,y1);
c.LineTo(xk2, yk2);
end;

end;


Извини, на Дельфи.
l- длинна концов стрелки.
С остальным, думаю, проблемм не будет?

СУВ, SoWa.

Автор: Elfet 4.12.2006, 20:58
Немножко тяжело разобраться уже в готовом коде. smile SoWa каким способом ты делал? (если есть Mathematica то там удобно формулы писать и объяснять)

Автор: SoWa 5.12.2006, 05:03
Математикой не умею.
Значит так.
Берем координаты конца стрелки и по синусам/косинусам определяем координаты вершинок отрезков.
Рассматриваются 4 случая, когда вершина стрелки в каждой из четвертей, там значения синусов и косинусов по знакам разные. Все делалось сперва на обрывке бумажки, а потом уж в компе smile 
Удачи!

Автор: Elfet 5.12.2006, 18:14
Можешь выложить бумажку? smile А то так неясно. Или нарисовать где?  smile 

Автор: SoWa 5.12.2006, 18:59
Ууу. Это я два года назад делал smile
Все просто. Берешь точку. По формуле l*sin(x) и l*cos(x) получаешь изменения координат для концов стрелочек. Прибавляешь их с учетом знака(зависит от четверти) к координатам конца отрезка.

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

Автор: Elfet 5.12.2006, 22:20
Суть я тоже понимаю smile Видимо мне алгоритм нужен, раз так форум называется ;) Вот как решается в C#: http://forum.vingrad.ru/topic-123478/kw-%F1%F2%F0%E5%EB%EA%E0/hl/%25D1%2581%25D1%2582%25D1%2580%25D0%25B5%25D0%25BB%25D0%25BA%25D1%2583/index.html

Автор: maxim1000 6.12.2006, 00:36
Цитата(Sartorius @  4.12.2006,  15:16 Найти цитируемый пост)
просто возьми точку на отрезке на нужном расстоянии от конца и поверни относительно него на нужный угол по часовой и в обратном направлении 
Вот на всякий случай оператор поворота на угол А
!cosA    -sinA!     ! x !
!sinA     cosA!  * ! y !


Цитата(Elfet @  4.12.2006,  16:07 Найти цитируемый пост)
как делать я тоже представляю, но вот не получается ;)


Цитата(Elfet @  5.12.2006,  21:20 Найти цитируемый пост)
Видимо мне алгоритм нужен, раз так форум называется ;)


чего-то я ничего не понимаю...
алгоритм описан, если что-то в нём непонятно, то надо сказать что, иначе никто не сможет помочь...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)