二维空间点到直线垂足计算公式推导及Java实现——学习笔记
程序员文章站
2022-04-02 21:27:13
...
前言
简单的公式推导,大概是高中程度的知识了。不管以前学的好不好,很久不用的东西,一上手还是有点懵的。推导一遍也是为了加深记忆。
公式推导
首先我们知道直线上两点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
上,此时我们需要把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;
}