2012-04-24 21 views
15

मैं किसी दिए गए बिंदु से लंबवत किसी दिए गए रेखा पर एक बिंदु की गणना करना चाहता हूं।किसी दिए गए बिंदु से एक रेखा खंड पर लंबवत

मेरे पास एक लाइन सेगमेंट एबी है और एक बिंदु सी बाहरी लाइन सेगमेंट है। मैं एबी पर एक बिंदु डी की गणना करना चाहता हूं जैसे कि सीडी एबी के लिए लंबवत है।

Find point D

मैं बिंदु डी

यह this को काफी समान खोजने के लिए है, लेकिन मैं विचार करने के लिए जेड भी समन्वय करने के लिए के रूप में यह 3 डी अंतरिक्ष में सही ढंग से प्रदर्शित नहीं करता है चाहता हूँ।

+0

एक * प्रोग्रामिंग * सवाल है, यह [math.se] (पर जहां यह लगभग निश्चित रूप से पहले से ही दोहराया गया है बेहतर होगा के अभाव में) – AakashM

+1

http://stackoverflow.com/questions/1811549/perpendicular-on-a-line-from-a-given-point – jdbertron

+1

यह निर्दिष्ट करना अच्छा होगा कि आप कौन सी भाषा चाहते हैं। – ThomasW

उत्तर

14

सबूत: प्वाइंट डी AB पर लम्ब एक लाइन सीडी पर है, और निश्चित रूप से विकास एबी के अंतर्गत आता है। दो वैक्टर सीडी.एबी = 0 के डॉट उत्पाद को लिखें, और तथ्य डी व्यक्त करें एबी से डी = ए + टी (बी-ए) के रूप में।

हम 3 समीकरणों के साथ अंत:

Dx=Ax+t(Bx-Ax) 
Dy=Ay+t(By-Ay) 
(Dx-Cx)(Bx-Ax)+(Dy-Cy)(By-Ay)=0 

Subtitute पहले दो तिहाई से एक में समीकरण देता है:

(Ax+t(Bx-Ax)-Cx)(Bx-Ax)+(Ay+t(By-Ay)-Cy)(By-Ay)=0 

टी के लिए हल करने के लिए वितरित किया जा रहा देता है:

(Ax-Cx)(Bx-Ax)+t(Bx-Ax)(Bx-Ax)+(Ay-Cy)(By-Ay)+t(By-Ay)(By-Ay)=0 

जो देता है:

t= -[(Ax-Cx)(Bx-Ax)+(Ay-Cy)(By-Ay)]/[(Bx-Ax)^2+(By-Ay)^2] 

नकारात्मक संकेत से छुटकारा पाने:

t=[(Cx-Ax)(Bx-Ax)+(Cy-Ay)(By-Ay)]/[(Bx-Ax)^2+(By-Ay)^2] 

एक बार जब आप टी है, तो आप बाहर डी के लिए निर्देशांक पहले दो समीकरणों से लगा सकते हैं।

Dx=Ax+t(Bx-Ax) 
Dy=Ay+t(By-Ay) 
+2

यह मूल प्रश्न के जेड घटक को अनदेखा करता है। – Stephen

0

जब से तुम यह कहते हुए नहीं कर रहे हैं कि कौन सी भाषा का उपयोग कर रहे है, मैं तुम्हें एक सामान्य जवाब देंगे:

बस एक पाश अपने एबी सेगमेंट में सभी बिंदुओं के माध्यम से गुजर है, करने के लिए "एक खंड आकर्षित" उनमें से सी, सी से डी और ए से डी तक दूरी प्राप्त करें, और पिथगोरस प्रमेय लागू करें। यदि एडी^2 + सीडी^2 = एसी^2, तो आपको अपना पॉइंट मिल गया है।

इसके अलावा, आप सबसे कम तरफ (एडी और बीडी पक्षों पर विचार करके) लूप शुरू करके अपना कोड अनुकूलित कर सकते हैं, क्योंकि आप पहले उस बिंदु को पा सकते हैं।

4

कहा जाता है इस के लिए एक सरल बंद फ़ॉर्म समाधान वेक्टर डॉट उत्पाद का उपयोग (कोई छोरों या अनुमानों की आवश्यकता होती है) है।

अपने अंक वैक्टर के रूप में कल्पना करें जहां बिंदु ए मूल (0,0) पर है और अन्य सभी बिंदुओं से इसका संदर्भ दिया जाता है (आप प्रत्येक बिंदु से बिंदु ए को घटाकर आसानी से अपने अंक को इस संदर्भ फ्रेम में बदल सकते हैं)।

// Per wikipedia this is more efficient than the standard (A . Bhat) * Bhat 
Vector projection = Vector.DotProduct(A, B)/Vector.DotProduct(B, B) * B 

परिणाम वेक्टर इंगित एक जोड़कर मूल समन्वय प्रणाली को वापस तब्दील किया जा सकता:

इस संदर्भ फ्रेम बिंदु डी में बस वेक्टर बी पर बिंदु सी के vector projection जो के रूप में व्यक्त किया जाता है यह। एक्स असली के लिए,

एम (x) = ए + एक्स * (बी ए):

3

रेखा AB पर एक बिंदु से parametrized जा सकता है।

आप चाहते डी = एम (x) ऐसे कि डीसी और एबी ओर्थोगोनल हैं:

डॉट (बी-ए, सी एम (x)) = 0।

यही कारण है: बिंदु (बीए, cax * (BA)) = 0, या डॉट (बीए, सीए) = एक्स * बिंदु (बीए, बीए), दे रही है:

एक्स = बिंदु (बीए, सीए)/डॉट (बीए, बीए) जिसे परिभाषित किया गया है जब तक ए = बी।

14
function getSpPoint(A,B,C){ 
    var x1=A.x, y1=A.y, x2=B.x, y2=B.y, x3=C.x, y3=C.y; 
    var px = x2-x1, py = y2-y1, dAB = px*px + py*py; 
    var u = ((x3 - x1) * px + (y3 - y1) * py)/dAB; 
    var x = x1 + u * px, y = y1 + u * py; 
    return {x:x, y:y}; //this is D 
} 

question

+4

एक अच्छा देखना अच्छा लगेगा आपने जो किया उसके बारे में थोड़ा सा स्पष्टीकरण। –

+0

हाय। मैंने ए, बी और डी को इंगित किया है और मैं बिंदु सी के एक्स और वाई निर्देशांक की गणना करना चाहता हूं। क्या मैं आपके फ़ंक्शन का उपयोग कर सकता हूं? यदि नहीं, तो कृपया मुझे संशोधन बताएं। –

+0

@MeanCoder बिंदु सी में अनगिनत संभावनाएं हैं यदि केवल बिंदु ए, बी, डी पता है। – cuixiping

1

यहाँ मैं परिवर्तित कर दिया है matlab कोड के लिए "cuixiping" से कोड जवाब दे दिया।

function Pr=getSpPoint(Line,Point) 
% getSpPoint(): find Perpendicular on a line segment from a given point 
x1=Line(1,1); 
y1=Line(1,2); 
x2=Line(2,1); 
y2=Line(2,1); 
x3=Point(1,1); 
y3=Point(1,2); 

px = x2-x1; 
py = y2-y1; 
dAB = px*px + py*py; 

u = ((x3 - x1) * px + (y3 - y1) * py)/dAB; 
x = x1 + u * px; 
y = y1 + u * py; 

Pr=[x,y]; 

end 
0

मुझे यह जवाब नहीं मिला, लेकिन रॉन वॉरहोलिक ने वेक्टर प्रोजेक्शन के साथ एक अच्छा सुझाव दिया था। एसीडी केवल एक सही त्रिकोण है।

  1. वेक्टर एसी यानी बनाएँ (Cx - कुल्हाड़ी, Cy - एय)
  2. वेक्टर एबी यानी बनाएँ (Bx - एक्स, द्वारा - एय) एसी और एबी के
  3. डॉट उत्पाद के बराबर है वैक्टर के बीच कोण के कोसाइन। i.e cos (theta) = एसीएक्स * एबीएक्स + एसी * एबीआई।
  4. एक वेक्टर की लम्बाई sqrt (एक्स * x + y * वाई)
  5. ई की लंबाई = cos (थीटा) * लंबाई (एसी)
  6. मानक के अनुसार एबी यानी (abx/लंबाई (एबी) है, Aby/लंबाई (एबी))
  7. डी = ए + एनएबी * लंबाई (ई)
0

यहाँ एक अजगर this thread से कोरी OGBURN के उत्तर के आधार पर कार्यान्वयन है।
यह बिंदु qp1 और p2 द्वारा परिभाषित रेखा खंड बिंदु r में जिसके परिणामस्वरूप पर परियोजनाओं।
यह अशक्त वापस आ जाएगी अगर r रेखा खंड अवधि से बाहर है:

def is_point_on_line(p1, p2, q): 

    if (p1[0] == p2[0]) and (p1[1] == p2[1]): 
     p1[0] -= 0.00001 

    U = ((q[0] - p1[0]) * (p2[0] - p1[0])) + ((q[1] - p1[1]) * (p2[1] - p1[1])) 
    Udenom = math.pow(p2[0] - p1[0], 2) + math.pow(p2[1] - p1[1], 2) 
    U /= Udenom 

    r = [0, 0] 
    r[0] = p1[0] + (U * (p2[0] - p1[0])) 
    r[1] = p1[1] + (U * (p2[1] - p1[1])) 

    minx = min(p1[0], p2[0]) 
    maxx = max(p1[0], p2[0]) 
    miny = min(p1[1], p2[1]) 
    maxy = max(p1[1], p2[1]) 

    is_valid = (minx <= r[0] <= maxx) and (miny <= r[1] <= maxy) 

    if is_valid: 
     return r 
    else: 
     return None 
संबंधित मुद्दे