判断一个多边形是否有核。
大体思想是,用多边形的边构成的直线,一点一点去削去原多边形。
蓝色区域则为多边形的核。
判断大于0还是小于0有一个小技巧:直线走向的左手边是小于0的,右手边是大于0的。
向量AB等于点B减去点A,走向为A指向B。
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
#define MAXN 2010
#define eps 1e-10
#define max(x, y) (x > y ? x : y)
#define min(x, y) (x < y ? x : y)
#define sig(x) ((x > eps) - (x < -eps))
#define cross(o, a, b) ((p[a] - p[o]) ^ (p[b] - p[o]))
const double pi = acos(-1.0);
typedef struct Point
{
double x, y;
Point() {}
Point(double _x, double _y):
x(_x), y(_y) {}
bool operator <(const Point &argu) const
{
return sig(x - argu.x) == 0 ? y < argu.y : x < argu.x;
}
double dis(const Point &argu) const
{
return sqrt((x - argu.x) * (x - argu.x) + (y - argu.y) * (y - argu.y));
}
double dis2(const Point &argu) const
{
return (x - argu.x) * (x - argu.x) + (y - argu.y) * (y - argu.y);
}
double operator ^(const Point &argu) const
{
return x * argu.y - y * argu.x;
}
double operator *(const Point &argu) const
{
return x * argu.x + y * argu.y;
}
Point operator -(const Point &argu) const
{
return Point(x - argu.x, y - argu.y);
}
double len2() const
{
return x * x + y * y;
}
double len() const
{
return sqrt(x * x + y * y);
}
void in()
{
scanf("%lf%lf", &x, &y);
}
void out()
{
printf("%.3lf %.3lf\n", x, y);
}
}Vector;
inline double Cross(const Point &o, const Point &a, const Point &b)
{
return (a - o) ^ (b - o);
}
Point Get_Intersection(const Point &u1, const Point &u2, const Point &v1, const Point &v2)
{
Point ret = u1;
double t = ((u1.x - v1.x) * (v1.y - v2.y) - (u1.y-v1.y) * (v1.x - v2.x))
/ ((u1.x - u2.x) * (v1.y - v2.y) - (u1.y - u2.y) * (v1.x - v2.x));
ret.x += (u2.x - u1.x) * t;
ret.y += (u2.y - u1.y) * t;
return ret;
}
Point Get_Intersection(const Point &x, const Point &y, double a, double b, double c)
{
double u = fabs(a * x.x + b * x.y + c);
double v = fabs(a * y.x + b * y.y + c);
return Point((x.x * v + y.x * u) / (u + v), (x.y * v + y.y * u) / (u + v));
}
void Get_Line(const Point &x, const Point &y, double &a, double &b, double &c)
{
a = y.y - x.y;
b = x.x - y.x;
c = y.x * x.y - x.x * y.y;
}
Point q[MAXN];
int Cut(Point p[], double a, double b, double c, int n)
{
int cc = 0;
for(int i = 1; i <= n; i++)
{
double k = a * p[i].x + b * p[i].y + c;
if(sig(k) >= 0) q[++cc] = p[i];
else
{
double k1 = a * p[i - 1].x + b * p[i - 1].y + c;
double k2 = a * p[i + 1].x + b * p[i + 1].y + c;
if(k1 > 0) q[++cc] = Get_Intersection(p[i], p[i - 1], a, b, c);
if(k2 > 0) q[++cc] = Get_Intersection(p[i], p[i + 1], a, b, c);
}
}
for(int i = 1; i <= cc; i++) p[i] = q[i];
p[cc + 1] = q[1], p[0] = p[cc];
return cc;
}
int solve(Point pp[], Point ke[], int n)
{
int cc = n;
for(int i = 1; i <= n; i++)
{
double a, b, c;
Get_Line(pp[i], pp[i + 1], a, b, c);
cc = Cut(ke, a, b, c, cc);
}
if(cc > 0) return 0;
if(cc <= 0) return 1;
}
char ans[2][30] = {
"Surveillance is possible.",
"Surveillance is impossible." };
Point pp[MAXN], ke[MAXN];
int n;
int main()
{
// freopen("J.in", "r", stdin);
int cas = 1;
while(scanf("%d", &n) && n)
{
for(int i = 1; i <= n; i++) pp[i].in(), ke[i] = pp[i];
ke[n + 1] = pp[n + 1] = pp[1];
ke[0] = pp[0] = pp[n];
printf("Floor #%d\n%s\n\n", cas++, ans[solve(pp, ke, n)]);
}
return 0;
}