2008-09-25 14 views
36

Tôi có một dòng mà tôi vẽ trong một cửa sổ và tôi cho phép người dùng kéo nó xung quanh. Vì vậy, dòng của tôi được xác định bởi hai điểm: (x1, y1) và (x2, y2). Nhưng bây giờ tôi muốn vẽ "mũ" ở cuối dòng, tức là các đường thẳng vuông góc ở mỗi điểm cuối của tôi. Các mũ phải dài N pixel.Làm thế nào để bạn tìm thấy một điểm tại một khoảng cách vuông góc nhất định từ một dòng?

Vì vậy, để vẽ đường "mũ" ở điểm cuối (x1, y1), tôi cần phải tìm hai điểm tạo thành đường thẳng vuông góc và mỗi điểm của nó là N/2 pixel cách điểm (x1 , y1). Vì vậy, làm thế nào để bạn tính toán một điểm (x3, y3) cho nó cần phải ở một khoảng cách vuông góc N/2 đi từ điểm kết thúc (x1, y1) của một dòng đã biết, tức là dòng được xác định bởi (x1, 1, 1, 1). , y1) và (x2, y2)?

+0

Để biết giải pháp chi tiết, [xem tại đây] (http://stackoverflow.com/a/17195324/183120). – legends2k

Trả lời

72

Bạn cần tính toán một vector đơn vị vuông góc với đoạn đường. Tránh tính toán độ dốc vì điều đó có thể dẫn đến chia cho 0 lỗi.

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

Tôi tiếp tục nghĩ rằng phải có một cách để tránh sqrt khó chịu trong đó, có thể bằng cách sử dụng Line của Breshenham, nhưng tôi không thể nghĩ ra nó. –

+2

Tôi nghĩ rằng bạn có một dấu hiệu lỗi trong tính toán của bạn hoặc điểm 3 và 4. Sử dụng (+ - - +) hoặc (- + + -) trong bốn dòng cuối cùng, không? – dmckee

+6

Cảm ơn, công trình này tuyệt vời! – AZDean

5

Bạn chỉ cần đánh giá versor trực giao và nhân với 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

Nếu bạn muốn tránh một sqrt, làm như sau:

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

Kể từ khi các vectơ từ 2 đến 1 và 1 đến 3 là vuông góc, sản phẩm chấm của chúng là 0.

Điều này khiến bạn có hai ẩn số: x từ 1 đến 3 (x1 3) và y từ 1 đến 3 (y13)

Sử dụng định lý Pythagore để có phương trình khác cho những ẩn số đó.

Giải quyết cho từng không xác định bằng cách thay thế ...

Điều này đòi hỏi bình phương và không đáng kể, vì vậy bạn mất dấu hiệu liên quan đến phương trình của bạn.

Để xác định dấu hiệu, xem xét:

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 

biết: Điểm 1: x1, y1

biết: Điểm 2: x2, y2

x21 = x1 - x2 
y21 = y1 - y2 

biết: khoảng cách | 1 -> 3 | : Lý Pythagore

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

Known:: N/2

phương trình một góc 2-1-3: góc vuông

vectơ 2-> 1 và 1-> 3 vuông góc

2-> 1 dot 1-> 3 là 0

phương trình b: dot sản phẩm = 0

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

tỷ lệ b/w X13 và y13:

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

x13 = -phi*y13 

phương trình a: giải quyết cho y13 với tỷ lệ

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 

phương trình a: giải quyết cho X13 với tỷ lệ

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 

ngưng tụ

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 

Tôi thường không làm điều này, nhưng tôi đã giải quyết nó tại nơi làm việc và nghĩ rằng giải thích nó triệt để sẽ giúp tôi củng cố kiến ​​thức của mình.