/*题意若干线段相交,求平面被分成几个区域
利用欧拉公式:n-m+r==2
n为线段相交的点数,m为线段数量,r为平面被分成的区域数量
r==2+m-n,只要找出交点数n以及线段数m即可。
*/
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
const double pi=acos(-1.0);
const double eps=1e-10;
int cmp(double x)//判断一个数的大小
{
if(fabs(x)<eps)return 0;
if(x>0)return 1;
return -1;
}
struct point
{
double x,y;
point(double a=0.0,double b=0.0){x=a,y=b;}
friend point operator + (const point &a,const point &b){
return point(a.x+b.x,a.y+b.y);}
friend point operator - (const point &a,const point &b){
return point(a.x-b.x,a.y-b.y);}
friend bool operator == (const point &a ,const point &b){//bool类型
return cmp(a.x-b.x)==0&&cmp(a.y-b.y)==0;}
friend point operator * (const point &a ,const double &b){//b为double
return point(a.x*b,a.y*b);}
friend point operator * (const double &a ,const point &b){//a为double
return point(a*b.x,a*b.y);}
friend point operator / (const point &a ,const double &b){//b为double
return point(a.x/b,a.y/b);}
double norm(){//求距离
return sqrt(x*x+y*y);}
};
double det(point a,point b)//两个向量的叉积
{
return a.x*b.y-a.y*b.x;
}
double dot(point a,point b)//两个向量的点积
{
return a.x*b.x+a.y*b.y;
}
struct line //利用线段a-b代表直线,可直线可线段
{
point a,b;
line(point x,point y):a(x),b(y){}//!!!此处
};
bool pointOnsegment(point p,line l)//点p是否在线段l上
{
point s=l.a,t=l.b;
return cmp(det(p-s,t-s))==0&&cmp(dot(p-s,p-t))<=0;
}
bool parallel(line a,line b)//直线a和直线b是否平行
{
return !cmp(det(a.a-a.b,b.a-b.b));
}
bool line_make_point(line a,line b,point &res)//求直线a-b的交点
{
if(parallel(a,b)) return 0;
double s1=det(a.a-b.a,b.b-b.a);
double s2=det(a.b-b.a,b.b-b.a);
res=(s1*a.b-s2*a.a)/(s1-s2);
return 1;
}
bool segment_make_point(line a,line b,point &res) //线段a,b交点
{
if(line_make_point(a,b,res))
return pointOnsegment(res,a)&&pointOnsegment(res,b);
return false;
}
const int maxn=100000;
point p[maxn];
point jiaodian[maxn];
bool cmp1(point a,point b)
{
if(a.x-b.x)
return a.x<b.x;
return a.y<b.y;
}
int main()
{
int n,m,N,cas=1;
while(cin>>N,N)
{
n=0;
m=0;
for(int i=0;i<N;i++)
cin>>p[i].x>>p[i].y;
for(int i=0;i<N;i++)//枚举个条边,寻找交点
for(int j=0;j<N;j++)
{
line l1(p[i],p[(i+1)%N]);
line l2(p[j],p[(j+1)%N]);
point res;
if(segment_make_point(l1,l2,res)) //端点也属于交点,也加入jiaodian[]
jiaodian[n++]=res;
}
sort(jiaodian,jiaodian+n,cmp1); //排序
n=unique(jiaodian,jiaodian+n)-jiaodian;//删除重复顶点
for(int i=0;i<n;i++) //枚举交点,若交点在某线段上,则把线段一分为二。
for(int j=0;j<N;j++)
{
line l(p[j],p[(j+1)%N]);
if(pointOnsegment(jiaodian[i],l)&&!(l.a==jiaodian[i]))// !(l.a==jiaodian[i])防止重复出现
m++;
}
printf("Case %d: There are %d pieces.\n",cas++,2+m-n);
}
return 0;
}
/*
5
0 0 0 1 1 1 1 0 0 0
7
1 1 1 5 2 1 2 5 5 1 3 5 1 1
Case 1: There are 2 pieces.
Case 2: There are 5 pieces.*/