ZOJ3720 Magnet Darts(点在多边形内)

第一道点在多边形内的判断题,一开始以为是凸的。其实题意很简单的啦,最后转化为判断一个点是否在一个多边形内。

如果只是简单的凸多边形的话,我们可以枚举每条边算下叉积就可以知道某个点是不是在范围内了。但对于更一般的多边形,要采用的方法可能就要复杂一些,其中一种是叫做射线法的东西,在该点上画一条射线,如果射线与多边形偶数次相交,则说明点在多边形外,否则在多边形内。实践中可以取水平的一条,至于怎么判断就要看下代码了,判断的过程中如何发现点已经在多边形上了则直接返回。

计算几何做的少,则是算是补充了一个盲区吧。

#pragma warning(disable:4996)

#include<iostream>

#include<cstring>

#include<cstdio>

#include<algorithm>

#include<cmath>

#define ll long long

#define mod 1000000007

#define maxn 1000000

#define eps 1e-6

using namespace std;



struct Point

{

	int x, y;

	Point(int xi, int yi) :x(xi), y(yi){}

	Point(){}

	int dot(const Point &b){

		return x*b.x + y*b.y;

	}

	int det(const Point &b){

		return x*b.y - y*b.x;

	}

	Point operator - (const Point &b){

		return Point(x - b.x, y - b.y);

	}

}p[25];



int dcmp(double x){

	return (x > eps) - (x < -eps);

}



int n;

double A, B;

double lx, rx, ly, ry;



bool onLine(Point x, Point aa, Point bb)

{

	return (bb - aa).det(x-aa) == 0 && (bb - x).dot(aa - x) <= 0;

}



bool inside(Point x)

{

	int ret = 0;

	for (int i = 0; i < n; i++){

		if (onLine(x, p[i], p[(i + 1) % n])) return true;

		int k = (p[(i + 1) % n] - p[i]).det(x - p[i]);

		int d1 = x.y - p[i].y;

		int d2 = x.y - p[(i + 1) % n].y;

		if (k > 0 && d1 >= 0 && d2 < 0) ret++;

		if (k < 0 && d2 >= 0 && d1 < 0) ret--;

	}

	return ret != 0;

}



int main()

{

	while (cin>>lx>>ly>>rx>>ry){

		scanf("%d%lf%lf", &n, &A, &B);

		for (int i = 0; i < n; i++){

			scanf("%d%d", &p[i].x, &p[i].y);

		}

		p[n].x = p[0].x; p[n].y = p[0].y;

		double ans = 0;

		int llx = ceil(lx), rrx = floor(rx);

		int lly = ceil(ly), rry = floor(ry);



		for (int i = llx; i <= rrx; i++){

			for (int j = lly; j <= rry; j++){

				if (inside(Point(i, j))){

					double h = min(i + 0.5, rx) - max(i - 0.5, lx);

					double w = min(j + 0.5, ry) - max(j - 0.5, ly);

					ans += (A*i + B*j)*h*w;

				}

			}

		}

		ans /= (double)(rx - lx)*(ry - ly);

		printf("%.3lf\n", ans);

	}

	return 0;

}

 

你可能感兴趣的:(net)