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 +
'}';
}
}
原文地址:http://www.cnblogs.com/mask-xiexie/p/16877712.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性