package com.xx.common.core.utils.geography;
import com.alibaba.fastjson2.JSON;
import com.xx.common.core.baseweb.domain.Point;
import java.util.Arrays;
import java.util.List;
/**
* @Description 射线法 判断点和面的关系
* @Date 2022-11-04 15:55
* @Author xie
*/
public class RayMethod {
public static boolean ray(Point p, List<Point> poly) {
double nx = p.getLon(); double ny = p.getLat();
//计算射线穿过多边形的点的数目
int cnt = 0;
int len = poly.size();
for (int i = 0, j = len - 1; i < len; j = i, ++i) {
double bx = poly.get(i).getLon();
double by = poly.get(i).getLat();
double ux = poly.get(j).getLon();
double uy = poly.get(j).getLat();
//点与多边形顶点重合
if ((nx == bx && ny == by) || (nx == ux && nx == uy)) {
return true;
}
if ((by < ny && uy >= ny) || (by >= ny && uy < ny)) {
//边上与点的坐标y相同的x坐标
double x = bx + (ny - by) * (ux - bx) / (uy - by);
//点在多边形的边上
if (x == nx) {
return true;
}
if (x > nx) {
cnt += 1;
}
}
}
if (cnt % 2 == 1) {
return true;
} else {
return false;
}
}
public static boolean rayArrayPoint(double[] p, List<double[]> poly) {
double nx = p[0]; double ny = p[1];
//计算射线穿过多边形的点的数目
int cnt = 0;
int len = poly.size();
for (int i = 0, j = len - 1; i < len; j = i, ++i) {
double bx = poly.get(i)[0];
double by = poly.get(i)[1];
double ux = poly.get(j)[0];
double uy = poly.get(j)[1];
//点与多边形顶点重合
if ((nx == bx && ny == by) || (nx == ux && nx == uy)) {
return true;
}
if ((by < ny && uy >= ny) || (by >= ny && uy < ny)) {
//边上与点的坐标y相同的x坐标
double x = bx + (ny - by) * (ux - bx) / (uy - by);
//点在多边形的边上
if (x == nx) {
return true;
}
if (x > nx) {
cnt += 1;
}
}
}
if (cnt % 2 == 1) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
Point p = new Point(116.756051906321, 43.084293983401146);
Point pot1 = new Point(116.75602598549472, 43.084279337427155);
Point pot2 = new Point(116.75603896966804, 43.08427934803498);
Point pot3 = new Point(116.75603892382017, 43.08429398162957);
Point pot4 = new Point(116.75602594131935, 43.084293979858);
List<Point> poly = Arrays.asList(pot1, pot2, pot3, pot4);
boolean flag = ray(p, poly);
if (flag == true) {
System.out.println("点在多边形内");
} else {
System.out.println("点不在多边形内");
}
double[] p1 = {116.756051906321, 43.084293983401146};
String json = "[[116.75602598549472,43.084279337427155],[116.75603896966804,43.08427934803498],[116.75603892382017,43.08429398162957],[116.75602594131935,43.084293979858]]";
List<double[]> poly1 = JSON.parseArray(json, double[].class);
boolean flag1 = rayArrayPoint(p1, poly1);
if (flag1 == true) {
System.out.println("1点在多边形内");
} else {
System.out.println("1点不在多边形内");
}
}
}
package com.xx.common.core.baseweb.domain;
import lombok.Builder;
import lombok.Data;
/**
* 内部类
* 位置点(经纬度)
* @author xie
*/
@Data
@Builder
public class Point {
private static final long serialVersionUID = 1L;
/**
* 经度
*/
double lon;
/**
* 纬度
*/
double lat;
public Point() {
}
public Point(double lon, double lat) {
this.lon = lon;
this.lat = lat;
}
@Override
public String toString() {
return "Point{" +
"lon=" + lon +
", lat=" + lat +
'}';
}
}
标签:ny,java,Point,double,poly,nx,射线,点和面,uy From: https://www.cnblogs.com/mask-xiexie/p/16877712.html