#include <stdio.h>
#include <stdlib.h>
//#define ZEROVALUE 0.00000000000001
#ifndef __max
#define __max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef __min
#define __min(a,b) (((a) < (b)) ? (a) : (b))
#endif
typedef struct _LINE
{
double x1;
double y1;
double x2;
double y2;
_LINE* pNext;
} LINE;
//以Pi为原点,从 PiPj 到 PiPk 的方位(返回值的符号表示顺时针 or 逆时针)
double Direction(double xi, double yi, //原点
double xj, double yj, //线段1结束点
double xk, double yk) //线段2结束点
{
return (xk - xi) * (yj - yi) - (xj - xi) * (yk - yi);
}
//如果点 Pk 位于线段 PiPj 所在直线上,则它是否位于该线段内
int OnSegment(double xi, double yi,
double xj, double yj, //线段1结束点
double xk, double yk) //线段2结束点
{
if(xk >= __min(xi, xj) && xk <= __max(xi, xj)
&& yk >= __min(yi, yj) && yk <= __max(yi, yj))
return 1;
else
return 0;
}
//判断两个线段P1P2,P3P4是否相交
int intersect(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
double d1 = Direction(x3, y3, x4, y4, x1, y1);
double d2 = Direction(x3, y3, x4, y4, x2, y2);
double d3 = Direction(x1, y1, x2, y2, x3, y3);
double d4 = Direction(x1, y1, x2, y2, x4, y4);
if( ((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0))
&& ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0)) )
return 1; //相交
else if(d1 == 0 && OnSegment(x3, y3, x4, y4, x1, y1))
return 1;
else if(d2 == 0 && OnSegment(x3, y3, x4, y4, x2, y2))
return 1;
else if(d3 == 0 && OnSegment(x1, y1, x2, y2, x3, y3))
return 1;
else if(d4 == 0 && OnSegment(x1, y1, x2, y2, x4, y4))
return 1;
else
return 0; //绝对不相交
}
/* 增加线段到链表尾部 */
void AddLine(LINE** ppHead, LINE** ppTail,
double x1, double y1,
double x2, double y2)
{
LINE *pNode = (LINE*)malloc(sizeof(LINE));
pNode->pNext = NULL;
pNode->x1 = x1;
pNode->y1 = y1;
pNode->x2 = x2;
pNode->y2 = y2;
if(*ppTail != NULL)
{
(*ppTail)->pNext = pNode;
}
else
{
*ppHead = pNode;
}
*ppTail = pNode;
}
void FreeList(LINE** ppHead, LINE** ppTail)
{
LINE* pNode = (*ppHead);
while(pNode != NULL)
{
LINE* tmp = pNode->pNext;
free(pNode);
pNode = tmp;
}
*ppHead = NULL;
*ppTail = NULL;
}
/* 检查是否这一系列点围成的多边形是否合法 */
int CheckValid(LINE* pHead)
{
int index = 0; /* 当前正循环到的边的索引 */
LINE* pCur = pHead;
LINE* pTest;
while(pCur != NULL)
{
pTest = NULL;
if(pCur->pNext != NULL)
pTest = pCur->pNext->pNext;
while(pTest != NULL)
{
//最后一条边(n-1) -- (0),不与第一条边 (0) -- (1) 检测
if(index == 0 && pTest->pNext == NULL)
break;
/* 非相邻边相交? */
if(intersect(pCur->x1, pCur->y1, pCur->x2, pCur->y2,
pTest->x1, pTest->y1, pTest->x2, pTest->y2))
{
return 0;
}
pTest = pTest->pNext;
}
pCur = pCur->pNext;
++index;
}
return 1;
}
int main(int argc, char* argv[])
{
LINE *pHead = NULL, *pTail = NULL;
int i, n = 0, figure = 1;
double x0, y0, x1, y1, x2, y2;
double area = 0;
//int test = intersect(0, 1, 1, 0, 1, -1, 0, 0.5);
while(1)
{
scanf("%d", &n);
if(n <= 0)
break;
//打印一个空行
if(figure > 1)
printf("\n");
area = 0;
scanf("%lf %lf", &x0, &y0);
x1 = x0;
y1 = y0;
for(i = 1; i <= n; i++)
{
if(i < n)
scanf("%lf %lf", &x2, &y2);
else
{
x2 = x0;
y2 = y0;
}
area += (y1 + y2) * (x2 - x1) * 0.5;
AddLine(&pHead, &pTail, x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
if(area < 0)
area *= -1;
if(n < 3)
printf("Figure %d: Impossible\n", figure);
else if(!CheckValid(pHead))
printf("Figure %d: Impossible\n", figure);
else
printf("Figure %d: %.02lf\n", figure, area);
FreeList(&pHead, &pTail);
figure++;
}
return 0;
}