/**
Author: LinZhiQ
Date: 2018-10-01 17:28
Graham扫描法 求凸包
*/
#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
const double PI = acos(-1.0);
struct Point {
double x,y;
Point() {}
Point(double _x, double _y) {
x = _x;
y = _y;
}
Point operator -(const Point &b)const {
return Point(x - b.x, y - b.y);
}// (点 a - 点 b) 表示以 b 为坐标轴原点重新定义 a 的坐标
double operator ^(const Point &b)const {
return x * b.y - y * b.x;
}//Cross 比较 点 a 与 点 b 到原点 连线的斜率 ,a的斜率小则返回值 大于零,等于零表示在同一直线
double operator *(const Point &b)const {
return x * b.x + y * b.y;
}//Dot 点自己 乘 自己 表示 点到原点距离的平方 也就是点乘
void transXY(double B) {
double tx = x,ty = y;
x = tx * cos(B) - ty * sin(B);
y = tx * sin(B) + ty * cos(B);
}
} p[105], lis[105];
bool CheckCross(Point a, Point b, Point c){ // 判断点 c 是否在 直线 ab 左侧
if((c ^ a) >= 0 && (b ^ c) >= 0 && ((a - b) ^ (c - b)) >= 0){
return true;
}
return false;
// 求交叉积(ab,ac)
// return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
// 返回值小于0表示c在ab右侧,大于0则在左侧
}
bool cmp1(const Point &a, const Point &b) {
return (a.x != b.x ? a.x < b.x : a.y < b.y);
} // 按照点的 y 坐标从小到大,x 坐标从小到大 (逆时针)
bool cmp2(const Point &a, const Point &b) {
return ((a ^ b) == 0 ? (a * a) < (b * b) : (a ^ b) > 0);
} // 极角排序,如果 a与b 在同一直线,那就与原点距离近的优先,否则极角小的优先
int T, n, m;
void PolarAngleSort(){ // 极角排序
sort(p + 1, p + 1 + n, cmp1);
for(int i = 2;i <= n;i++){
p[i] = p[i] - p[1];
}
p[1].x = p[1].y = 0;
sort(p + 1, p + 1 + n, cmp2);
}
void ConvexHull() {
PolarAngleSort();
lis[1] = p[1]; // 起点
lis[2] = p[2]; // 前两个点与起点三点可构成面
lis[3] = p[3];
m = 3;
for(int i = 4;i <= n;i++){
while(CheckCross(p[i],lis[m - 1],lis[m]) && m > 2){ // 把被新点包围的点全部删去
m--;
}
lis[++m] = p[i];
}
}
double getArea() { // 求面积
double area = 0;
for(int i = 2; i <= m - 1; i++) {
area += ((lis[i] - lis[1]) ^ (lis[i + 1] - lis[1]));
}
return fabs(area) / 2.0;
}
double dis(const Point &a, const Point &b){
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double getPerimeter(){ //求周长
double sum = 0;
for(int i = 2; i <= m; i++){
sum += dis(lis[i - 1],lis[i]);
}
sum += dis(lis[m], lis[1]);
return sum;
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
scanf("%lf %lf",&p[i].x,&p[i].y);
}
ConvexHull();
for(int i = 1; i <= m; i++) {
printf("(%lf,%lf)\n",lis[i].x,lis[i].y);
}
printf("%lf %lf\n",getArea(),getPerimeter());
}
return 0;
}