import java.awt.geom.Point2D;
import java.util.List;
/**
* TestCUtil
*/
public class TestCUtil {
/**
* 地球半径
*/
private static double earth = 6378138.0;
/**
*
* @param d d
* @return double
*/
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* 计算是否在圆上(单位/千米)
* @param radius 半径
* @param lat1 纬度
* @param lng1 经度
* @param lat2 纬度
* @param lng2 经度
* @return boolean
*/
public static boolean isInCircle(double radius, double lat1, double lng1, double lat2, double lng2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * Math.asin(Math.sqrt(Math.pow(
Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * earth;
s = (double) Math.round(s * 10000) / 10000;
if (s > radius) {
//不在圆上
return false;
}
return true;
}
/**
* 判断点是否在多边形内
* @param polygon 多边形
* @param point 检测点
* @return 点在多边形内返回true,否则返回false
*/
public static boolean isPtInPoly(List<Point2D.Double> polygon, Point2D.Double point) {
int n = polygon.size();
boolean boundOrVertex = true;//如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
int intersectCount = 0;//cross points count of x--交叉点计数X
double precision = 2e-10;//浮点类型计算时候与0比较时候的容差
Point2D.Double p1;
Point2D.Double p2;
Point2D.Double p = point;//当前点
p1 = polygon.get(0);//left vertex--左顶点
for (int i = 1; i <= n; ++i) {
//check all rays--检查所有射线
if (p.equals(p1)) {
return boundOrVertex;//p is an vertex--p是一个顶点
}
p2 = polygon.get(i % n);//right vertex--右顶点
if (p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)) {
//ray is outside of our interests--射线不在我们的兴趣范围之内
p1 = p2;
continue;//next ray left point--下一条射线的左边点
}
if (p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)) {
//ray is crossing over by the algorithm(common part of)--射线被算法穿越(常见的一部分)
if (p.y <= Math.max(p1.y, p2.y)) {
//x is before of ray--x在射线之前
if (p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)) {
//overlies on a horizontal ray--在一条水平射线上
return boundOrVertex;
}
if (p1.y == p2.y) {
//ray is vertical--射线是垂直的
if (p1.y == p.y) {
//overlies on a vertical ray--覆盖在垂直光线上
return boundOrVertex;
} else {
//before ray--射线之前
++intersectCount;
}
} else {
//cross point on the left side--左边的交叉点
double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;//cross point of y--y的交叉点
if (Math.abs(p.y - xinters) < precision) {
//overlies on a ray--覆盖在射线
return boundOrVertex;
}
if (p.y < xinters) {
//before ray--射线之前
++intersectCount;
}
}
}
} else {
//special case when ray is crossing through the vertex--特殊情况下,当射线穿过顶点
if (p.x == p2.x && p.y <= p2.y) {
//p crossing over p2--p交叉p2
Point2D.Double p3 = polygon.get((i + 1) % n);//next vertex--下一个顶点
if (p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)) {
//p.x lies between p1.x & p3.x--p.x在p1.x和p3.x之间
++intersectCount;
} else {
intersectCount += 2;
}
}
}
p1 = p2;//next ray left point--下一条射线的左边点
}
if (intersectCount % 2 == 0) {
//偶数在多边形外
return false;
}
return true;
}
/**
* testc
* @param c c
* @return 返回值
*/
public String testc(String c) {
return c + "c";
}
}
电子围栏算法工具类-判断点与圆形,多边形关系
于 2023-04-15 10:39:53 首次发布