判断一个点是否在一个平面某个多边形内

判断一个点是否在一个平面内

射线法
判断:若从一点发出的射线穿越过平面内多边形的点的个数为偶数,则点在多边形外,若为奇数,则点在多边形内。
做法:从该点取向右的一条射线,遍历多边形的每一条边,判断射线与边的交点个数(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("点不在多边形内");
			}
		}		
}

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值