工作中遇到了点到直线的距离,给出一个点的经纬度,求解这个点到
一条道路的垂直距离。道理表示使用起止点,起止点同样也是经纬度,
PS:好久没有用到高数了,真心觉得自己全部忘记了,公式推导了好久,终于搞定了垂足问题。
//实现的功能:给出某一个点的经纬度和某一条道路的 // 起止经纬度,计算出点到道路上的垂直距离, // 如果垂足不在道路上,则返回点与道路起止点的最小距离 /** * Created by yyk . */ public class PointToLine { static double DEF_PI = 3.14159265359; public static void main(String[] args) { //点到直线的垂足 double[] Point = new double[]{2,2}; int R = 6371; double[] StrLonLat = new double[]{1,1};//StrLonLat EndLonLat表示直线的起止经纬度 double[] EndLonLat = new double[]{1,3}; double[] Pedal = pointtoline(Point, StrLonLat, EndLonLat);//Pedal表示垂足的经纬 //SimpleDateParam dfs=new SimpleDateParam("yyyy-MM-dd HH:mm:ss.SSS"); //long start=dfs.timestamp(); double PtoP = EDistance(Point, Pedal, R);//计算考虑了地球的弧度问题 double PtoStr = EDistance(Point, StrLonLat, R); double PtoEnd = EDistance(Point, EndLonLat, R); double min = MIN(PtoP, PtoStr, PtoEnd);//要求的值 System.out.println("min"+min); // long end=dfs.timestamp(); // long time=start-end; // System.out.println("Time:"+time); }
public static double EDistance(double[] LonLat1, double[] LonLat2, int R) { //将两点经纬度转换为三维直角坐标 double x1 = Math.cos(LonLat1[0] / 180 * DEF_PI); double y1 = Math.sin(LonLat1[0] / 180 * DEF_PI); double z1 = Math.tan(LonLat1[1] / 180 * DEF_PI); double x2 = Math.cos(LonLat2[0] / 180 * DEF_PI); double y2 = Math.sin(LonLat2[0] / 180 * DEF_PI); double z2 = Math.tan(LonLat2[1] / 180 * DEF_PI); //根据直角坐标求两点间的直线距离(即弦长) double L = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2)); //根据弦长求两点间的距离(即弧长) double Eudis = R * DEF_PI * 2 * (Math.asin(0.5 * L / R)) / 180; return Eudis; } public static double[] pointtoline(double[] point, double[] strlonlat, double[] endlonlat) { double A = endlonlat[1] - strlonlat[1]; double B = strlonlat[0] - endlonlat[0]; double C = strlonlat[1] * endlonlat[0] - strlonlat[0] * endlonlat[1]; double[] Pedal = new double[2]; Pedal[0] = (point[0] * B * B - point[1] * A * B-A*C) / (A * A + B * B); Pedal[1] = (point[1]*A*A - A * B * point[0] - B * C) / (A * A + B * B); System.out.println("垂足经度:"+Pedal[0]+"垂足纬度:"+Pedal[1]); return Pedal; } public static double MIN(double pp, double ps, double pe) { double mindis; if (pp < ps && pp < pe) mindis = pp; else if (ps < pe) mindis = ps; else mindis = pe; if(mindis==pp) System.out.println("pedal in lineAB"); else System.out.println("pedal is not in lineAB"); return mindis; } }