ClosestPoint.java
2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.bsth.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.bsth.util.TransGPS.Location;
public class ClosestPoint {
public static Location getVerticalPoint(Location loc1, Location loc2, Location loc3) {
// 第一步:求得直线方程相关参数y=kx+b | kx-y+b=0
double k = (loc1.getLat() - loc2.getLat()) * 1.0 / (loc1.getLng() - loc2.getLng());// 坐标直线斜率k
double b = loc1.getLat() - k * loc1.getLng();// 坐标直线b
// 第一种: 设直线方程为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))
Location loc4 = TransGPS.LocationMake(((-1) * (-1) * loc3.getLng() - k * (-1) * loc3.getLat() - k * b) / (k * k + (-1) * (-1)),
(k * k * loc3.getLat() - k * (-1) * loc3.getLng() - (-1) * b) / (k * k + (-1) * (-1)));
return loc4;
}
// 获取两点间距离
static double GetPointDistance(Location p1, Location p2) {
return Math.sqrt((p1.getLng() - p2.getLng()) * (p1.getLng() - p2.getLng()) + (p1.getLat() - p2.getLat()) * (p1.getLat() - p2.getLat()));
}
// 求点到线段距离的最近点
static Map<Double, List<Location>> GetNearestDistance(Location PA, Location PB, Location P3) {
Map<Double, List<Location>> point = new HashMap<>();
List<Location> locations = new ArrayList<>();
locations.add(PA);
locations.add(PB);
// 点在线段上
double a, b, c;
a = GetPointDistance(PB, P3);
if (a <= 0.000000001) {
locations.add(P3);
point.put(a, locations);
return point;
}
b = GetPointDistance(PA, P3);
if (b <= 0.000000001) {
locations.add(P3);
point.put(b, locations);
return point;
}
c = GetPointDistance(PA, PB);
if (c <= 0.000000001) {
locations.add(PA);
point.put(b, locations);// 如果PA和PB坐标相同,则退出函数,并返回距离
return point;
}
// 点和线段组成钝角三角形
if (a * a >= b * b + c * c) {
locations.add(PA);
point.put(b, locations);
return point;// 如果是钝角返回b
}
if (b * b >= a * a + c * c) {
locations.add(PB);
point.put(a, locations);// 如果是钝角返回a
return point;
}
// 点和线段组成锐角三角形
double l = (a + b + c) / 2; // 周长的一半
double s = Math.sqrt(l * (l - a) * (l - b) * (l - c)); // 海伦公式求面积,也可以用矢量求
Location location = getVerticalPoint(PA, PB, P3);
locations.add(location);
point.put(2 * s / c, locations);
return point;
}
}