第一道点在多边形内的判断题,一开始以为是凸的。其实题意很简单的啦,最后转化为判断一个点是否在一个多边形内。
如果只是简单的凸多边形的话,我们可以枚举每条边算下叉积就可以知道某个点是不是在范围内了。但对于更一般的多边形,要采用的方法可能就要复杂一些,其中一种是叫做射线法的东西,在该点上画一条射线,如果射线与多边形偶数次相交,则说明点在多边形外,否则在多边形内。实践中可以取水平的一条,至于怎么判断就要看下代码了,判断的过程中如何发现点已经在多边形上了则直接返回。
计算几何做的少,则是算是补充了一个盲区吧。
#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 ", ans); } return 0; }