您的位置:首页 > 其它

ZOJ3720 Magnet Darts(点在多边形内)

2014-03-30 19:01 267 查看
第一道点在多边形内的判断题,一开始以为是凸的。其实题意很简单的啦,最后转化为判断一个点是否在一个多边形内。

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

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

#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
.x = p[0].x; p
.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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: