您的位置:首页 > 编程语言 > PHP开发

【计算几何】Exactness of Projectile Hit

2012-03-17 09:44 351 查看
In the problem you are to determine the minimal diameter that may compensate inexactness of
projectile hit in each concrete case. Assume that all the targets are convex polygons. A hit
is the situation when the circle crater that the projectile leaves (the crater diameter equals
to the one of the projectile) covers if only one point of the target.
Input
The first line contains three numbers — coordinates of the hit point of the projectile center
and the number of polygon sides N (3 ≤ N ≤ 100). The next N lines contain the vertices
coordinates in counter-clockwise order. All the coordinates are integers from [−2000,2000].
Output
You are to output the only number which is the minimal diameter of a projectile that will cover
the target rounded with three digits after the decimal point.




Sample Input:
2 -1 8
0 1
1 0
2 0
3 1
3 2
2 3
1 3
0 2

Sample Output
2.000此题考察点到凸多边形的距离,也即:

判断点与凸多边形的位置关系以及点到线段的距离。

判断点与凸多边形的位置关系的方法如下:

假设这个点为P,凸多边形为A1A2...An,(逆时针顺序。)那么依次计算向量PA1与向量PA2, 向量PA2与向量PA3, ..., 向量PAn与向量PA1的外积。若发现一个外积小于零,那么P在凸多边形外,否则P不在凸多边形外。

计算点到线段的距离的方法如下:

假设这个点为S,线段为AB。

如果∠A为钝角(用内积判断),那么距离为SA;

如果∠B为钝角,那么距离为SB;

否则距离为S到AB的垂线段的长度(用法向量可以算)。

Accode:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <complex>

using std::complex;
const char fi[] = "ural1215.in";
const char fo[] = "ural1215.out";
const int maxN = 110;
const double MAX = 1e198;
const double MIN = -MAX;
const double zero = 1e-12;

typedef complex <double> vec;
//这里用复数来代替向量。
vec p[maxN];
vec res[maxN];
vec S;
int n, x, y, top;

void init_file()
{
freopen(fi, "r", stdin);
freopen(fo, "w", stdout);
return;
}

void readdata()
{
scanf("%d%d%d", &x, &y, &n);
S = vec((double)x, (double)y);
for (int i = 0; i < n; ++i)
{
scanf("%d%d", &x, &y);
p[i] = vec((double)x, (double)y);
}
return;
}

template <typename _Tp>
_Tp outer_product(const complex <_Tp> a,
const complex <_Tp> b)
{
return a.real() * b.imag()
- a.imag() * b.real();
} //计算向量a, b的外积。

template <typename _Tp>
_Tp inner_product(const complex <_Tp> a,
const complex <_Tp> b)
{
return a.real() * b.real()
+ a.imag() * b.imag();
} //计算向量a, b的内积。

template <typename _Tp>
_Tp dist(const complex <_Tp> S,
const complex <_Tp> a,
const complex <_Tp> b)
{
vec _Sa = a - S,
_Sb = b - S,
_ab = b - a;
if (inner_product(_Sa, _ab) > -zero)
return abs(_Sa);
if (inner_product(_Sb, _ab) < zero)
return abs(_Sb);
vec _norm = _ab * vec(0, 1);
//计算向量AB的法向量
//(即把AB逆时针旋转90°,
//即用AB对应的复数乘以i)。
return fabs(inner_product(_norm, _Sa)) / abs(_norm);
} //得到点S到线段AB的距离。

void work()
{
int pos = 0;
double ans = MAX;
bool outside = false;
for (int ths = 0; ths < n; ++ths)
{
int next = (ths + 1) % n;
outside = outside ||
outer_product(p[ths] - S,
p[next] - S) < -zero;
ans = std::min(ans, dist(S, p[ths], p[next]));
}
if (!outside)
{
printf("0");
return;
}
printf("%.3lf", ans * 2);
return;
}

int main()
{
init_file();
readdata();
work();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  output numbers file input each