首页 > 其他分享 >[AIZU ONLINE JUDGE] 计算几何 CGL_3_C (射线法判断一点是否在多边形内部)

[AIZU ONLINE JUDGE] 计算几何 CGL_3_C (射线法判断一点是否在多边形内部)

时间:2024-07-17 20:27:57浏览次数:17  
标签:return CGL Point double points ONLINE JUDGE 多边形 polygon

Polygon-Point-Containment

For a given polygon g and target points t, print "2" if g contains t, "1" if t is on a segment of g, "0" otherwise.

g is represented by a sequence of points p1, p2,..., pn where line segments connecting pi and pi+1 (1 ≤ i ≤ n−1) are sides of the polygon. The line segment connecting pn and p1 is also a side of the polygon.

Note that the polygon is not necessarily convex.

Input

The entire input looks like:

g (the sequence of the points of the polygon)
q (the number of queris = the number of target points)
1st query
2nd query
:
qth query

g is given by coordinates of the points p1,..., pn in the following format:

n
x1 y1 
x2 y2
:
xn yn

The first integer n is the number of points. The coordinate of a point pi is given by two integers xi and yi. The coordinates of points are given in the order of counter-clockwise visit of them.

Each query consists of the coordinate of a target point t. The coordinate is given by two intgers x and y.

Output

For each query, print "2", "1" or "0".

Constraints

  • 3 ≤ n ≤ 100
  • 1 ≤ q ≤ 1000
  • -10000 ≤ xiyi ≤ 10000
  • No point of the polygon will occur more than once.
  • Two sides of the polygon can intersect only at a common endpoint.

Sample Input

4
0 0
3 1
2 3
0 3
3
2 1
0 2
3 2

Sample Output

2
1
0

题意:

存在一多边形g(凹凸不确定),给定g每个点的横纵坐标,再询问n个点与多边形的位置关系,如果点在多边形内部输出2,如果点在多边形的边上则输出1,如果在多边形外则输出0;

题解:

针对本题我们可以利用射线法来判断点与多边形的位置关系:

简而言之,就是从该点向任意方向发射一条射线,看这条射线与多边形的边相交多少次,如果为奇数次,那么该点在多边形内部,如果是偶数次,在该点在多边形的外部

然而这里有很多需要注意的细节边界问题,譬如假设该射线与多边形的一条边重合,亦或者是射线刚好交到多边形的一个顶点怎么办??

针对这种问题主要有两种解决方案:

一种是OI选手常用的但是精度可能略低的方法,随机一个角度。因为角度是无限多的,而多边形的边是有限条,所以总存在一个角度的射线既不与边重合,也不和点相交。

另一种就是背一个分类讨论好的,不会错的板子我就是后者)

so板子如下:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>

using namespace std;

const int N = 110;
const double eps = 1e-10;
const double PI = acos(-1);

int n, m;

int dcmp(double x)  // 计算几何里面判断 符号,或者0的函数 (确保精度)
{
	if (fabs(x) <= eps) return 0;
	if(x > 0) return 1;
	return -1;
}

struct Point
{
	double x, y;
	
	Point(double x = 0, double y = 0) : x(x), y(y) { }  // 结构体内构造函数

	Point operator- (const Point& t)  // 重载,方便向量运算
	{
		return Point(x - t.x, y - t.y); 
	}
	double operator^ (const Point& t)  //重载一下叉乘运算
	{
		return x * t.y - t.x * y;
	}
}p[N];

typedef Point Vector;   // 向量
Point P;

double dot(Vector A, Vector B)  // 点乘
{
	return A.x * B.x + A.y * B.y;
}

bool On_segment(Point A, Point B, Point P)  // 判断点在线段上的函数
{
    // 叉乘 == 0 表示 向量 P-A 和 P-B 共线   点乘小于等于 0 表示 点落在线段上,而不是一侧
	return dcmp((P - A) ^ (P - B)) == 0 && dcmp(dot(A - P, B - P)) <= 0;
}

int In_Polygon(Point P) 
{
	bool flag = 0;
	Point P1, P2;
	for (int i = 1, j = n; i <= n; j = i++)  // (两邻点确定一条边)遍历多边形的所有边
	{
		P1 = p[i];
		P2 = p[j];
		if (On_segment(P1, P2, P)) return 1;  // 如果点在边上 返回 1

		//前一个判断min(P1.y,P2.y)<P.y<=max(P1.y,P2.y)
		//后一个判断被测点 在 射线与边交点 的左边
		if ((dcmp(P1.y - P.y) > 0 != dcmp(P2.y - P.y) > 0) && dcmp(P.x - (P.y - P1.y) * (P1.x - P2.x) / (P1.y - P2.y) - P1.x) < 0)
		{
			flag = !flag;
		}
	}
	if (flag) return 2;
	else return 0;
}

int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> p[i].x >> p[i].y;

	cin >> m;
	for(int i = 1; i <= m; i++) 
	{
		cin >> P.x >> P.y;
		cout << In_Polygon(P) <<endl;
	}

	return 0;
}





标签:return,CGL,Point,double,points,ONLINE,JUDGE,多边形,polygon
From: https://blog.csdn.net/zeisenphael/article/details/140504293

相关文章

  • Regularized Stochastic Learning and Online Optimization
    目录概符号说明MotivationFOBOS(Forward-BackwardSplitting)RDA(RegularizedDualAveraging)FTRL-Proximal(FollowTheRegularizedLeader)FOBOS,RDA,FTRL-Proximal的统一表示[1]DuchiJ.andSingerY.EfficientLearningusingForward-BackwardSplitting.NeurIP......
  • jdk动态代理与cglib动态代理
    最近在用java实现redis,在使用动态代理时遇到了一点问题,即使用jdk动态代理(Invocationhandler)时,如果代理对象是一个接口的实现类,那么此时动态代理获取到的method对象是接口中的,而不是实现类的,现象是:我在实现类中对接口方法上新增了注解,但是此刻method反射获取不到注解信息,于是大概......
  • OpenJudge | 矩阵交换行
    总时间限制:1000ms内存限制:65536kB描述编写一个函数,输入参数是55的二维数组,和n,m两个行下标。功能:判断n,m是否在数组范围内,如果不在,则返回0;如果在范围内,则将n行和m行交换,并返回1。在main函数中,生成一个55的矩阵,输入矩阵数据,并输入n,m的值。调用前面的函数。如果返回值......
  • OpenJudge | 最高的分数
    目录描述输入输出样例输入样例输出思路方法一方法二CodeCC++总时间限制:1000ms内存限制:65536kB描述孙老师讲授的《计算概论》这门课期中考试刚刚结束,他想知道考试中取得的最高分数。因为人数比较多,他觉得这件事情交给计算机来做比较方便。你能帮孙老师解决......
  • 大厂面试必备系列:一文彻底搞懂 Cglib 代理
    前言大家在面试中经常被问到Cglib和JDK动态代理有啥区别?然后每次回答都是Cglib通过创建目标类的子类来实现代理。这个回答当然是对的,但是太敷衍了,没得加分,今天我带大家深入了解下。最佳实践直接上案例案例地址:https://github.com/zhuangjiaju/easytools/blob/ma......
  • Nonlinear econometrics for finance
    NonlineareconometricsforfinanceHOMEWORK2(LIE,NLSandGMM)Problem1(LawofIteratedExpectations.)(6points) Afinancialanalystwantstopredictthereturnonaportfolio.Theportfoliogiveseitherareturnof1or2percentineachperiod.She......
  • [题解]AT_arc079_c [ARC079E] Decrease (Judge ver
    思路首先,对于每一次操作,我们可以先找到最大值,然后对其操作。这样,我们可以得到单次操作时间复杂度\(\Theta(n)\)的代码,因为\(n\)很小,所以这道题时间复杂度的瓶颈在于操作的数量。那么,我们想到每一次找到最大值时,直接将其减到小于\(n\)。但是这样可能有一种问题,就是最大值......
  • HDU-4281 Judges' response(2012 ACM/ICPC Asia Regional Tianjin Online)
    HDU-4281Judges'response(2012ACM/ICPCAsiaRegionalTianjinOnline)状态压缩+01背包+区间dp题意:有n个地点,第一个地点是裁判位置,其他n-1个地点是选手的位置。裁判要给选手解决问题,每个选手都有一个时间表示解决这个选手问题所需要的时间。同样的,裁判也有一个时间,表示这......
  • JDK动态代理和CGLIB动态代理
    Java动态代理是一种在运行时创建代理对象的技术,它允许开发者在不修改目标类代码的情况下,通过代理类对目标类的实例方法进行增强或拦截。动态代理的核心价值在于能够在程序运行阶段动态地生成一个实现了预定义接口的新类,这个新类就是所谓的“代理类”。在Java中,有两种主要的实现方......
  • 重启失败的 pt-online-schema-change 任务
    从PerconaToolkit3.6.0开始,如果pt-online-schema-change被中断,你可以重新恢复它。 要重启任务,需要知道它在哪里失败了。这就是为什么第一个必须使用的选项是-history。它指示pt-online-schema-change将进度存储在历史表中。历史表的默认名称是percona.pt_osc_history......