Domanda

Ho una linea che disegno in una finestra e lascio trascinare l'utente. Quindi, la mia linea è definita da due punti: (x1, y1) e (x2, y2). Ma ora vorrei disegnare " maiusc " alla fine della mia linea, cioè brevi linee perpendicolari a ciascuno dei miei punti finali. I tappi devono essere lunghi N pixel.

Pertanto, per disegnare il mio "cap" linea al punto finale (x1, y1), devo trovare due punti che formano una linea perpendicolare e dove ciascuno dei suoi punti è N / 2 pixel di distanza dal punto (x1, y1).

Quindi, come si calcola un punto (x3, y3) dato che deve trovarsi ad una distanza perpendicolare N / 2 dal punto finale (x1, y1) di una linea nota, cioè la linea definita da (x1, y1) e (x2, y2)?

È stato utile?

Soluzione

Devi calcolare un vettore unitario perpendicolare al segmento di linea. Evita di calcolare la pendenza perché ciò può portare a dividere per zero errori.

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

Altri suggerimenti

Devi solo valutare il versore ortogonale e moltiplicarlo per 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

Poiché i vettori da 2 a 1 e da 1 a 3 sono perpendicolari, il loro punto è pari a 0.

Questo ti lascia con due incognite: x da 1 a 3 (x13) e y da 1 a 3 (y13)

Usa il teorema di Pitagora per ottenere un'altra equazione per quegli incogniti.

Risolvi per ogni sconosciuto per sostituzione ...

Ciò richiede la quadratura e la non divisione, quindi perdi il segno associato alle tue equazioni.

Per determinare il segno, considerare:

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

Noto: punto 1: x1, y1

Conosciuto: punto 2: x2, y2

x21 = x1 - x2
y21 = y1 - y2

Noto: distanza | 1- > 3 | : N / 2

equazione a: teorema di Pitagora

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

Noto: angolo 2-1-3: angolo retto

i vettori 2- > 1 e 1- > 3 sono perpendicolari

2- > 1 punto 1- > 3 è 0

equazione b: punto prodotto = 0

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

rapporto b / n x13 e y13:

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

x13 = -phi*y13

equazione a: risolto per y13 con rapporto

  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

equazione a: risolto per x13 con rapporto

  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

condensare

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

Normalmente non lo farei, ma l'ho risolto al lavoro e ho pensato che spiegarlo a fondo mi avrebbe aiutato a consolidare le mie conoscenze.

Se si desidera evitare un sqrt, procedere come segue:

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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top