Как вы находите точку на заданном перпендикулярном расстоянии от линии? - PullRequest
42 голосов
/ 25 сентября 2008

У меня есть линия, которую я рисую в окне, и я позволяю пользователю перетаскивать ее. Итак, моя линия определяется двумя точками: (x1, y1) и (x2, y2). Но теперь я хотел бы нарисовать «шапки» в конце моей линии, то есть короткие перпендикулярные линии в каждой из моих конечных точек. Длина заглавных букв должна составлять N пикселей.

Таким образом, чтобы нарисовать линию «колпачка» в конечной точке (x1, y1), мне нужно найти две точки, которые образуют перпендикулярную линию и где каждая из ее точек находится на N / 2 пикселя от точки (x1 y1).

Итак, как рассчитать точку (x3, y3), учитывая, что она должна находиться на перпендикулярном расстоянии N / 2 от конечной точки (x1, y1) известной линии, то есть линии, определенной (x1, у1) и (х2, у2)?

Ответы [ 4 ]

80 голосов
/ 25 сентября 2008

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

dx = x1-x2
dy = y1-y2
dist = sqrt(dx*dx + dy*dy)
dx /= dist
dy /= dist
x3 = x1 + (N/2)*dy
y3 = y1 - (N/2)*dx
x4 = x1 - (N/2)*dy
y4 = y1 + (N/2)*dx
5 голосов
/ 25 сентября 2008

Вы просто оцениваете ортогональный версор и умножаете на N / 2

vx = x2-x1
vy = y2-y1
len = sqrt( vx*vx + vy*vy )
ux = -vy/len
uy = vx/len

x3 = x1 + N/2 * ux
Y3 = y1 + N/2 * uy

x4 = x1 - N/2 * ux
Y4 = y1 - N/2 * uy
3 голосов
/ 26 марта 2011

Поскольку векторы от 2 до 1 и от 1 до 3 перпендикулярны, их точечное произведение равно 0.

Это оставляет вас с двумя неизвестными: х от 1 до 3 (х13) и у от 1 до 3 (у13)

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

Решите для каждого неизвестного путем подстановки ...

Это требует возведения в квадрат и разведения, поэтому вы теряете знак, связанный с вашими уравнениями.

Чтобы определить знак, рассмотрим:

while x21 is negative, y13 will be positive
while x21 is positive, y13 will be negative
while y21 is positive, x13 will be positive
while y21 is negative, x13 will be negative

Известно: точка 1: x1, y1

Известно: точка 2: x2, y2

x21 = x1 - x2
y21 = y1 - y2

Известно: расстояние | 1-> 3 | : N / 2

уравнение а: теорема Пифагора

x13^2 + y13^2 = |1->3|^2
x13^2 + y13^2 = (N/2)^2

Известно: угол 2-1-3: прямой угол

векторы 2-> 1 и 1-> 3 перпендикулярны

2-> 1 точка 1-> 3 равно 0

уравнение b: скалярное произведение = 0

x21*x13 + y21*y13 = 2->1 dot 1->3
x21*x13 + y21*y13 = 0

Соотношение ч / б x13 и y13:

x21*x13 = -y21*y13
x13 = -(y21/x21)y13

x13 = -phi*y13

уравнение a: решено для y13 с соотношением

  plug x13 into a
phi^2*y13^2 + y13^2 = |1->3|^2

  factor out y13
y13^2 * (phi^2 + 1) = 

  plug in phi
y13^2 * (y21^2/x21^2 + 1) = 

  multiply both sides by x21^2
y13^2 * (y21^2 + x21^2) = |1->3|^2 * x21^2

  plug in Pythagorean theorem of 2->1
y13^2 * |2->1|^2 = |1->3|^2 * x21^2

  take square root of both sides
y13 * |2->1| = |1->3| * x21

  divide both sides by the length of 1->2
y13 = (|1->3|/|2->1|) *x21

  lets call the ratio of 1->3 to 2->1 lengths psi
y13 = psi * x21

  check the signs
    when x21 is negative, y13 will be positive
    when x21 is positive, y13 will be negative

y13 = -psi * x21

уравнение a: решено для x13 с отношением

  plug y13 into a
x13^2 + x13^2/phi^2 = |1->3|^2

  factor out x13
x13^2 * (1 + 1/phi^2) = 

  plug in phi
x13^2 * (1 + x21^2/y21^2) = 

  multiply both sides by y21^2
x13^2 * (y21^2 + x21^2) = |1->3|^2 * y21^2

  plug in Pythagorean theorem of 2->1
x13^2 * |2->1|^2 = |1->3|^2 * y21^2

  take square root of both sides
x13 * |2->1| = |1->3| * y21

  divide both sides by the length of 2->1
x13 = (|1->3|/|2->1|) *y21

  lets call the ratio of |1->3| to |2->1| psi
x13 = psi * y21

  check the signs
    when y21 is negative, x13 will be negative
    when y21 is positive, x13 will be negative

x13 = psi * y21

сгущаться

x21 = x1 - x2
y21 = y1 - y2

|2->1| = sqrt( x21^2 + y^21^2 )
|1->3| = N/2

psi = |1->3|/|2->1|

y13 = -psi * x21
x13 =  psi * y21

Обычно я бы этого не делал, но я решил это на работе и подумал, что подробное объяснение поможет мне закрепить свои знания.

1 голос
/ 25 сентября 2008

Если вы хотите избежать sqrt, сделайте следующее:

in: line_length, cap_length, rotation, position of line centre

define points:
  tl (-line_length/2, cap_length)
  tr (line_length/2, cap_length)
  bl (-line_length/2, -cap_length)
  br (line_length/2, -cap_length)

rotate the four points by 'rotation'
offset four points by 'position'

drawline (midpoint tl,bl to midpoint tr,br)
drawline (tl to bl)
drawline (tr to br)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...