二维空间点到直线垂足计算公式推导及Java实现——学习笔记

二维空间点到直线垂足计算公式推导及Java实现

前言

简单的公式推导,大概是高中程度的知识了。不管以前学的好不好,很久不用的东西,一上手还是有点懵的。推导一遍也是为了加深记忆。

公式推导

首先我们知道直线上两点p1,p2
p 1 : ( x 1 , y 1 ) p_1:(x_1,y_1) p 2 : ( x 2 , y 2 ) p_2:(x_2,y_2)
和直线外一点p3
p 3 : ( x 3 , y 3 ) p_3:(x_3,y_3)
现在我们要求p3在直线p1p2上的垂足p4
p 4 : ( x 4 , y 4 ) p_4:(x_4,y_4)
可知直线p1p2垂直于直线p3p4,根据向量垂直的关系我们可以知道:
( x 1 x 2 ) ( x 3 x 4 ) + ( y 1 y 2 ) ( y 3 y 4 ) = 0 ( 1 ) (x_1-x_2)(x_3-x_4)+(y_1-y_2)(y_3-y_4)=0\quad\quad(1)
同时由于p1,p2,p4三点共线,可假设系数u使得:
{ x 4 = x 1 + u ( x 1 x 2 ) y 4 = y 1 + u ( y 1 y 2 ) ( 2 ) \begin{cases} \quad x_4=x_1+u(x_1-x_2)\\ \quad y_4=y_1+u(y_1-y_2) \end{cases}\quad\quad\quad(2)
将式子(2)带入(1)中,可以解得:
u = ( x 1 x 2 ) ( x 3 x 1 ) + ( y 1 y 2 ) ( y 3 y 1 ) ( x 1 x 2 ) 2 + ( y 1 y 2 ) 2 ( 3 ) u=\frac{(x_1-x_2)(x_3-x_1)+(y_1-y_2)(y_3-y_1)} {(x_1-x_2)^2+(y_1-y_2)^2}\quad(3)
再将求得的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的延长线上而不是落在p1p2之间,此时我们需要把p4映射到线段的两个端点(即p1p2)上。针对此情况修改代码:

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;
    }
发布了63 篇原创文章 · 获赞 73 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/jjwwwww/article/details/83830981
今日推荐