点到线段的最近点

第一种: 设直线方程为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; 


然后再判断垂足是否在线段上,如果在线段上则返回垂足;如果不在则计算两端点 

到垂足的距离,选择距离垂足较近的端点返回。

判断垂足是否在线段上方法:已知线段两点的坐标,以及任意点的坐标,利用任意点的坐标到线段两点坐标我距离和,

与线段的长度比较,可以设定某个误差范围,符合条件即成立。

 List<Integer> edgeList=road.getEdgeList();
float k,x,y,x1,y1,x2,y2,px,py;
for(int edgeId:edgeList){
Edge edge=TopologyMap.edgeMap.get(edgeId);
Node fromNode=TopologyMap.nodeMap.get(edge.getFromNodeId());
Node toNode=TopologyMap.nodeMap.get(edge.getToNodeId());
x1=fromNode.getLat();y1=fromNode.getLong();
x2=toNode.getLat();y2=toNode.getLong();
px=GPoint.getLat();py=GPoint.getLong();
//求垂足
if(x1==x2){
x=x1;
y=GPoint.getLong();
}else if(y1==y2){
y=y1;
x=GPoint.getLat();
}else{   //存在斜率k
k=(y2-y1)/(x2-x1);
x= (k*k*x1 + k*(py-y1) + px)/(k*k+1) ;
y=k*(x-x1) + y1; 
}
//判断垂足是否在edge上
float edgeLength=(float)Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
float dist1=(float)Math.sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
float dist2=(float)Math.sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));
float compare=dist1+dist2;
if(compare-edgeLength>0.0004){//不在线段上,则取最近点为端点
 if(dist1<dist2){
 x=x1;y=y1;
 }else{
 x=x2;y=y2;
 }
}
Node pedal=new Node(x,y,edgeId,roadId);



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值