2011-12-18 5 views
3

Я разрабатываю графическое приложение. В окне приложения есть вершины, соединенные ребрами. Пользователь может перемещать вершину, и по мере того, как он делает, край также перемещается. У меня возникает проблема, чтобы найти шаблон для рисования стрелки, представляющей направление ребра, в зависимости от обеих вершинных позиций.Алгоритм для рисования направления края

Вот пример.

Допустим, что вершина имеет width/height = 20px; Край отрисован от центра Вершины1 до центра Вертекса2.

Vertex1.position = new Point(0,0); 
Vertex2.position = new Point(100,0); 
Edge.point1 = new Point(10,10); 
Edge.point2 = new Point(110,10); 
//Arrow representing direction from Vertex1 to Vertex2 
Arrow.point1 = new Point(100,10); 
Arrow.point2 = new Point(90,20); 
Arrow.point3 = new Point(90,0); 

Вопрос: Знание положения начала/конца края, как рассчитать точки стрелки?

+0

1) Определите точки стрелки в радиальных терминах (угол/расстояние) относительно точки (сверху), 2) вычислите угол вектора, соединяющего ваши вершины (угол с осью x или y, не имеет значения), 3) В зависимости от того, какой угол вы взяли, добавьте или вычтите из него свои углы стрелочной точки, 4) Используя sin и cos, вычислите x и y смещены от верхней точки стрелки для каждой из стрелок (слева направо), 5) добавьте эти значения в верхней точке стрелки – neeKo

ответ

3

Скажем, начальная точка края имеет координаты (ax, ay), конечная точка (bx, by), вершина имеет радиус w, ваша стрела имеет длину его указателя l и угол между стрелками ребрах alpha Тогда в псевдокоде:

ex := (bx - ax) 
ey := (by - ay) 
ex := ex/sqrt(ex^2 + ey^2) 
ey := ey/sqrt(ex^2 + ey^2) 

Первая точка стрелки:

a1x := bx - w * ex 
a1y := by - w * ey 

Вторая точка стрелки:

a2x := bx - (w + l) * ex + l * tg(alpha/2) * ey 
a2y := by - (w + l) * ey - l * tg(alpha/2) * ex 

Третья точка стрелки:

a3x := bx - (w + l) * ex - l * tg(alpha/2) * ey 
a3y := by - (w + l) * ey + l * tg(alpha/2) * ex 

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

+0

Спасибо, отличный ответ. – Zaphood

0

EDIT: Вы не указали свой тип приложения. Если вы используете WinForms this, может оказаться полезным. Here - статья MSDN о LineCap.

Смежные вопросы