点到线段的垂足
一、解析函数求解
第一种: 设直线方程为ax+by+c=0,点坐标为(m,n)
则垂足为((b*b*m-a*b*n-a*c)/(a*a+b*b),(a*a*n-a*b*m-b*c)/(a*a+b*b))
第二种:计算点到线段的最近点
如果该线段平行于X轴(Y轴),则过点point作该线段所在直线的垂线,垂足很容
易求得,然后计算出垂足,如果垂足在线段上则返回垂足,否则返回离垂足近的端
点;
如果该线段不平行于X轴也不平行于Y轴,则斜率存在且不为0。设线段的两端点为
pt1和pt2,斜率为:
k = ( pt2.y - pt1. y ) / (pt2.x - pt1.x );
该直线方程为:
y = k* ( x - pt1.x) + pt1.y
其垂线的斜率为 - 1 / k,
垂线方程为:
y = (-1/k) * (x - point.x) + point.y
联立两直线方程解得:
x = ( k^2 * pt1.x + k * (point.y - pt1.y ) + point.x ) / ( k^2 + 1) y = k * ( x - pt1.x) + pt1.y;
然后再判断垂足是否在线段上,如果在线段上则返回垂足;如果不在则计算两端点 到垂足的距离,选择距离垂足较近的端点返回。
判断点是否在线段上:
(1)先判断夹角是否为0,如果不为0,则肯定不在线段上
(2)如果为0,则在直线上,然后再判断点是否在线段上。
设点为Q,线段为P1P2,判断点Q在该线段上的依据是:
(Q-P1)×(P2-P1) = 0且在以P1,P2为对角项点的矩形内。前者保证Q点在直线P1P2上,后者是保证Q点不在线段P1P2的延长线或反向延长线上。
if(min(P1x,P2x)<=Qx<=max(P1x,P2x)) and (min(P1y,P2y)<=Qy<=max(P1y,P2y))
then return true;
else return false;
二、三角函数求解
根据余弦求解即可。
(1)先计算出点在直线上的投影
(2)再判断计算出的投影点是否在线段上
osg::Vec3 dir = p2 - p1;
dir.normalize();
osg::Vec3 pp1 = P - p1;
float fLength = pp1.normalize();
float fDis = fLength * (dir * pp1);
osg::Vec3 verticalPoint = p1 + dir * fDis;
return verticalPoint;