1、我是使用的数组记录点的坐标,索引0为x坐标,1为y坐标
2、也可以使用结构体来记录点x,y,再用List管理点集合。
java">import java.util.Arrays;
import java.util.Objects;/*** @Author 宇颀休闲* @Date 2024/11/10 11:03* @Description*/public class PointInOrOuter {/*** 判断点是否在顶点上* @param boundaryPoints*/public static Boolean isVertex(double[][] boundaryPoints, double[] point){for (double[] boundaryPoint : boundaryPoints) {if (Objects.equals(boundaryPoint[0], point[0]) && Objects.equals(boundaryPoint[1], point[1])) {return true;}}return false;}/*** 用光影法解决点是否在多边形内的问题* @param boundaryPoints* @param point* @return*/public static Boolean isInside(double[][] boundaryPoints, double[] point) {//交点数量int crossCount = 0;//结果Boolean result = true;//精度double precision = 0.0000001;//1、如果测试点刚好在多边形的顶点,直接返回trueBoolean vertex = isVertex(boundaryPoints, point);if (vertex){System.out.println(Arrays.toString(point) + "在顶点上");return result;}double[] p1 = boundaryPoints[0];int length = boundaryPoints.length;for (int i = 1; i <= length; i++) {double[] p2 = boundaryPoints[i % length];//2、判断点是否在两个点的x坐标围成的区域内if (point[0] < Math.min(p1[0], p2[0]) || point[0] > Math.max(p1[0], p2[0])) {//不在区域内p1 = p2;continue;}if (point[0] > Math.min(p1[0], p2[0]) && point[0] < Math.max(p1[0], p2[0])) {//在区域内//提交的这里错了,应该是math.max,而不是math.minif (point[1] <= Math.max(p1[1], p2[1])) {//两点连成的线与y轴平行if (p1[0] == p2[0] && point[1] >= Math.min(p1[1], p2[1])) {//在线上return result;}//两点连成的线与x轴平行if (p1[1] == p2[1]) {if (point[1] == p1[1]) {//在线上return result;}else {//在矩形内部++crossCount;}}else {//计算交点double k = (p2[1] - p1[1]) / (p2[0] - p1[0]);//斜率double x0 = k * (point[0] - p1[0]) + point[1];//交点x坐标if (Math.abs(point[1] - x0) < precision) {//在线上return result;}if (point[1] < x0) {//在线内部++crossCount;}}}}else {//必定与其中一个点的x坐标相同if (point[0] == p2[0] && point[1] <= p2[1]) {//下一个点double[] p3 = boundaryPoints[(i + 1) % length];//在p1,p3之间if (point[0] >= Math.min(p1[0], p3[0]) && point[0] <= Math.max(p1[0], p3[0])) {++crossCount;}else {//不在内部crossCount += 2;}}}p1 = p2;}System.out.println(Arrays.toString(point) + ", crossCount = " + crossCount);//如果交点数量为奇数,则点在多边形内,否则在多边形外if (crossCount % 2 == 1) {result = true;} else {result = false;}return result;}public static void main(String[] args) {//多边形的各个坐标double[][] boundaryPoints = {{1, 1}, {3, 2}, {4, 2}, {4, 4}, {3, 3}};//测试坐标double[][] testPoints = {{2, 2}, {4, 3}, {4, 5}, {4, 2}, {3, 2.5}, {1, 2}, {2, 3}};//判断点是否在多边形内Boolean[] resultList = new Boolean[testPoints.length];for (int i = 0; i < testPoints.length; i++) {Boolean result = isInside(boundaryPoints, testPoints[i]);resultList[i] = result;}//打印结果System.out.println("resultList = " + Arrays.toString(resultList));
//下面是读取文件的例子,读取点坐标,再根据测试点判断
// //多边形的各个坐标
// JsonReader jsonReader = new JsonReader();
// double[][] boundaryPoints = jsonReader.readJsonFile("latlon.json");
// //测试坐标
// double[][] testPoints = {{119.037089, 32.259867}, {118.821489, 32.077388}, {118.80657099, 32.0353893}, {118.894173, 32.077862}};
// //判断点是否在多边形内
// Boolean[] resultList = new Boolean[testPoints.length];
// for (int i = 0; i < testPoints.length; i++) {
// Boolean result = isInside(boundaryPoints, testPoints[i]);
// resultList[i] = result;
// }
// //打印结果
// System.out.println("\n\n最终结果=" + Arrays.toString(resultList));// Integer a = 128;
// Integer b = 128;
// System.out.println(a.intValue() == b.intValue());
// System.out.println();}}