二維空間點到直線垂足計算公式推導及Java實現——學習筆記
阿新 • • 發佈:2019-01-09
二維空間點到直線垂足計算公式推導及Java實現
前言
簡單的公式推導,大概是高中程度的知識了。不管以前學的好不好,很久不用的東西,一上手還是有點懵的。推導一遍也是為了加深記憶。
公式推導
首先我們知道直線上兩點p1
,p2
:
和直線外一點p3
:
現在我們要求p3
在直線p1p2
上的垂足p4
:
可知直線p1p2
垂直於直線p3p4
,根據向量垂直的關係我們可以知道:
同時由於p1
,p2
,p4
三點共線,可假設係數u
使得:
將式子(2)帶入(1)中,可以解得:
再將求得的u
帶回(2)中,就得到了垂足。
程式碼實現
private Point getFoot (Point p1,Point p2,Point p3){
Point foot=new Point();
float dx=p1.x-p2.x;
float dy=p1.y-p2.y;
float u=(p3.x-p1.x)*dx+(p3.y-p1.y)*dy;
u/=dx*dx+dy*dy;
foot.x=(int)(p1.x+u*dx);
foot.y=(int)(p1.y+u*dy);
return foot;
}
程式碼很簡單,不解釋了,參照上面推導的式子(2)和式子(3)
畫蛇添足
這裡多提一點。實際運用中,有的時候需要的只是把點對映在一條線段上,這時會出現一種情況,就是我們計算得到的垂足p4
線上段p1p2
的延長線上而不是落在p1
、p2
之間,此時我們需要把p4
對映到線段的兩個端點(即p1
或p2
)上。針對此情況修改程式碼:
private Point getFoot(Point p1,Point p2,Point p3){
Point foot=new Point();
float dx=p1.x-p2.x;
float dy=p1.y-p2.y;
float u=(p3.x-p1.x)*dx+(p3.y-p1.y)*dy;
u/=dx*dx+dy*dy;
foot.x=(int)(p1.x+u*dx);
foot.y=(int)(p1.y+u*dy);
float d=Math.abs((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.x-p2.y));
float d1=Math.abs((p1.x-foot.x)*(p1.x-foot.x)+(p1.y-foot.y)*(p1.x-foot.y));
float d2=Math.abs((p2.x-foot.x)*(p2.x-foot.x)+(p2.y-foot.y)*(p2.x-foot.y));
if(d1>d||d2>d){
if (d1>d2) return p2;
else return p1;
}
return foot;
}