2008-09-25 4 views
36

J'ai une ligne que je dessine dans une fenêtre et je laisse l'utilisateur la faire glisser. Donc, ma ligne est définie par deux points: (x1, y1) et (x2, y2). Mais maintenant je voudrais dessiner des «bouchons» à la fin de ma ligne, c'est-à-dire de courtes lignes perpendiculaires à chacun de mes points d'extrémité. Les majuscules doivent avoir une longueur de N pixels. Ainsi, pour dessiner ma ligne "cap" au point final (x1, y1), j'ai besoin de trouver deux points qui forment une ligne perpendiculaire et où chacun de ses points est N/2 pixels du point (x1 , y1). Comment calcule-t-on un point (x3, y3) étant donné qu'il doit être à une distance perpendiculaire N/2 du point final (x1, y1) d'une ligne connue, ie la ligne définie par (x1 , y1) et (x2, y2)?Comment trouvez-vous un point à une distance perpendiculaire donnée d'une ligne?

+0

Pour une solution détaillée, [voir ici] (http://stackoverflow.com/a/17195324/183120). – legends2k

Répondre

72

Vous devez calculer un vecteur unitaire perpendiculaire au segment de ligne. Évitez de calculer la pente car cela peut conduire à une division par zéro des erreurs.

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 
+1

Je continue à penser qu'il doit y avoir un moyen d'éviter cette mauvaise place, peut-être en utilisant Breshenham's Line, mais je ne peux pas penser à ça. –

+2

Je pense que vous avez une erreur de signe dans vos calculs ou les points 3 et 4. Utilisez (+ - - +) ou (- + + -) dans les quatre dernières lignes, non? – dmckee

+6

Merci, ceci fonctionne super! – AZDean

5

Vous évaluez juste le versor orthogonale et multiplier par 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 
1

Si vous voulez éviter une sqrt, procédez comme suit:

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) 
3

Depuis les vecteurs de 2 à 1 et 1 à 3 sont perpendiculaires, leur produit scalaire est 0.

Cela vous laisse avec deux inconnues: x de 1 à 3 (x1 3), et y de 1 à 3 (y13)

Utilisez le théorème de Pythagore pour obtenir une autre équation pour ces inconnues.

Résoudre pour chaque inconnue par substitution ...

Cela nécessite d'élévation au carré et unsquaring, alors vous perdez le signe associé à vos équations.

Pour déterminer le signe, pensez à:

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 

connu: point 1: x1, y1

connu: le point 2: x2, y2

x21 = x1 - x2 
y21 = y1 - y2 

connu: distance | 1 -> 3 | : N/2

équation: avec un théorème de Pythagore

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

connus: angle 2-1-3: angle droit

vecteurs 2-> 1 et 1-> 3 sont perpendiculaires

2-> 1 dot 1-> 3 est 0

équation b: produit scalaire = 0

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

rapport b/w x13 et y13:

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

x13 = -phi*y13 

équation a: résolu pour Y13 avec un rapport

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 

équation a: résolu pour x13 avec un rapport

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 

pour condenser

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 

Normalement, je ne le ferais pas, mais je l'ai résolu au travail et je pensais qu'en l'expliquant à fond, cela m'aiderait à consolider mes connaissances.

Questions connexes