判断一个点是否在一个平面内
射线法
判断:若从一点发出的射线穿越过平面内多边形的点的个数为偶数,则点在多边形外,若为奇数,则点在多边形内。
做法:从该点取向右的一条射线,遍历多边形的每一条边,判断射线与边的交点个数(0或1,重合情况另外处理),最后取和,判断奇偶。
那么,如何判断射线与边的交点个数?
1.点就在边上,易于判断
2.点不在边上,射线与边重合,直接判断点不在多边形内
3.比较点与边的端点的y值,若点的y值不在两个端点的y值之间,
那么不再继续,比较下一条边。为什么?我说了,取的是一条水平向右的射线,若点的y在不在两个端点的y值之间,那么必然是没有交点的。
Java代码如下:
import java.util.*;
public class ryamethod{
static class Point{
float x;
float y;
Point(){}
Point(float x, float y){
this.x = x;
this.y = y;
}
}
public static boolean ray(Point p, List<Point> poly) {
float nx = p.x; float ny = p.y;
int cnt = 0; //计算射线穿过多边形的点的数目
int len = poly.size();
for(int i = 0, j = len - 1; i < len; j = i, ++i) {
float bx = poly.get(i).x; float by = poly.get(i).y;
float ux = poly.get(j).x; float uy = poly.get(j).y;
//点与多边形顶点重合
if((nx == bx && ny == by) || (nx == ux && nx == uy)) {
return true;
}
if((by < ny && uy >= ny) || (by >= ny && uy < ny)) {
//边上与点的坐标y相同的x坐标
float 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) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入要判断的点");
float x , y;
x = sc.nextFloat();
y = sc.nextFloat();
Point p = new Point(x, y);
System.out.println("请输入多边形顶点个数:");
int n = sc.nextInt();
System.out.println("请输入多边形的各个顶点:");
List<Point> poly = new ArrayList<>();
for(int i = 0; i < n; ++i) {
x = sc.nextFloat();
y = sc.nextFloat();
Point pot = new Point(x, y);
poly.add(pot);
}
boolean flag = rayCasting(p, poly);
if(flag == true) {
System.out.println("点在多边形内");
}else {
System.out.println("点不在多边形内");
}
}
}