#include <iostream>
#include <fstream>
#include <math.h>
#include <cstdlib>
using namespace std;
ifstream f("rubarba.in");
ofstream g("rubarba.out");
typedef struct cel2
{ struct cel2 *pre, *urm; /* legaturi spre celulele vecine */
float x, y;
} TCel2, *TL2;
float angle(TL2 p1, TL2 p2, TL2 p3);
TL2 f1(TL2 l, TL2 a);
TL2 search(TL2 l, TL2 r);
float d3p(TL2 p1, TL2 p2, TL2 p3);
TL2 proj(TL2 p1, TL2 p0, TL2 q);
TL2 proj(TL2 p1, TL2 p0, TL2 q)//coordonatele proiectiei lui q pe dreapta p1p0
{
float x, y, a, b, c, d, s1, s2;
a=(p1->x)-(p0->x);
b=(p1->y)-(p0->y);
c=(p0->y)-(p1->y);
d=(p1->x)-(p0->x);
s1=(q->x)*((p1->x)-(p0->x))+(q->y)*((p1->y)-(p0->y));
s2=(p0->y)*(p1->x-p0->x)-(p0->x)*((p1->y)-(p0->y));
x=(d*s1-b*s2)/(a*d-b*c);
y=(c*s1-a*s2)/(b*c-a*d);
TL2 sol = (TL2)malloc (sizeof(TCel2));
sol->x=x;
sol->y=y;
return sol;
}
float d3p(TL2 p1, TL2 p2, TL2 p3)//distanta de la p3 la p1p2
{
float x1=p1->x, y1=p1->y, x2=p2->x, y2=p2->y, x3=p3->x, y3=p3->y;
float a, b, d, s;
a=(y2-y1)/(x2-x1);
b=y1-a*x1;
s=sqrt(a*a+1);
d=(a*x3-y3+b)/s;
return d;
}
TL2 search(TL2 l, TL2 r)
{
TL2 p;
for(p=l->urm;p!=l;p=p->urm)
if(p->x==r->x&&p->y==r->y)
return p;
return NULL;
}
float angle(TL2 p1, TL2 p2, TL2 p3)//unghiul in sens trigonometric de la dreapta p1p2 la p1p3
{
/*
Vectorial product
| e1 e2 e3 |
|dx21 dy21 z1 | = P
|dx31 dy31 z2 |
*/
float x1=p1->x, y1=p1->y, x2=p2->x, y2=p2->y, x3=p3->x, y3=p3->y;
float dx21 = x2-x1;
float dx31 = x3-x1;
float dy21 = y2-y1;
float dy31 = y3-y1;
float m12 = sqrt( dx21*dx21 + dy21*dy21 );
float m13 = sqrt( dx31*dx31 + dy31*dy31 );
//float v=(dy21-dy31)-(dx21-dx31)+(dx21*dy31-dx31*dy21);
float v=(dx21*dy31-dx31*dy21);
v=v/abs((int)v);
if(m12==m13||m12*m13==0)
return 100;
return v*acos( (dx21*dx31 + dy21*dy31) / (m12 * m13) );
}
TL2 f1(TL2 l, TL2 a)
{
TL2 p, q, r, aux;
float ang1, ang2, s1, s2;
for(p=l->urm, q=p->urm;p!=l->pre;p=p->urm, q=q->urm)
{
for(r=a->urm;r!=a;r=r->urm)
{
ang1=angle(p, q, r);
s1=sin(ang1);
if(p->pre!=l)
ang2=angle(p, p->pre, r);
else
ang2=angle(p, p->pre->pre, r);
s2=sin(ang2);
aux=search(l, r);
if(!aux&&ang1+ang2<90)
{
if(s1>=0&&s2>=0)
{
aux = (TL2)malloc (sizeof(TCel2));
p->urm=aux;
aux->urm=q;
q->pre=aux;
aux->pre=p;
q=aux;
aux->x=r->x;
aux->y=r->y;
r=a;
}
if(s1>0&&s2<0)
{
aux = (TL2)malloc (sizeof(TCel2));
aux->urm=q;
aux->pre=p->pre;
p->pre->urm=aux;
q->pre=aux;
p->urm=NULL;
p->pre=NULL;
q=aux;
p=aux->pre;
aux->x=r->x;
aux->y=r->y;
r=a;
}
}
else if(ang1+ang2<90)
{
if(s1>0){
q->urm->pre=q->pre;
q->pre->urm=q->urm;
q->urm=NULL;
q->pre=NULL;
q=p->urm;
r=a;}
}
}
}
/*
for(p=l->urm, q=p->urm->urm;p!=l;p=p->urm, q=q->urm)
{
if(q==l)
{
q=q->urm;
r=l->pre;
}
else r=q->pre;
ang1=angle(p, q, r);
s1=sin(ang1);
if(p->pre!=l)
ang2=angle(p, p->pre, r);
else
ang2=angle(p, p->pre->pre, r);
s2=sin(ang2);
if(s1*s2<0)
{
r->urm->pre=r->pre;
r->pre->urm=r->urm;
r->urm=NULL;
r->pre=NULL;
}
}*/
return l;
}
int main()
{
//double xmax=0, ymax=0, xmin=1000000, ymin=1000000, n, i, x, y, xp1, xp2, yp1, yp2;
int n, i;
float xmax=0, ymax=0, xmin=1000000, ymin=1000000, smin=1000000, dmax=0, d;
TL2 a, b, p, l, m1, m2, m3, m4, q, r;
//a = (TL2)(new TL2); /* incearca alocare santinela */
a = (TL2)malloc (sizeof(TCel2)); /* incearca alocare santinela */
if (a) /* aux contine adresa santinelei */
{ a->pre = a->urm = a; /* completeaza celula */
}
b = (TL2)malloc (sizeof(TCel2)); /* incearca alocare santinela */
if (b) /* aux contine adresa santinelei */
{ b->pre = b->urm = b; /* completeaza celula */
}
l = (TL2)malloc (sizeof(TCel2)); /* incearca alocare santinela */
if (l) /* aux contine adresa santinelei */
{ l->pre = l->urm = l; /* completeaza celula */
}
m1= (TL2)malloc (sizeof(TCel2));
if (m1) /* aux contine adresa santinelei */
{ m1->pre = m1->urm = m1; /* completeaza celula */
}
m2= (TL2)malloc (sizeof(TCel2));
if (m2) /* aux contine adresa santinelei */
{ m2->pre = m2->urm = m2; /* completeaza celula */
}
m3= (TL2)malloc (sizeof(TCel2));
if (m3) /* aux contine adresa santinelei */
{ m3->pre = m3->urm = m3; /* completeaza celula */
}
m4= (TL2)malloc (sizeof(TCel2));
if (m4) /* aux contine adresa santinelei */
{ m4->pre = m4->urm = m4; /* completeaza celula */
}
f>>n;
for(i=1;i<=n;i++)
{
p= (TL2)malloc (sizeof(TCel2));
f>>(p->x);
f>>(p->y);
p->urm = a;
p->pre = a->pre;
a->pre->urm = p;
a->pre = p;
if(p->x > xmax)
{
xmax=p->x;
m2->x=p->x;
m2->y=p->y;
}
if(p->x<xmin)
{
xmin=p->x;
m4->x=p->x;
m4->y=p->y;
}
if(p->y>ymax)
{
ymax=p->y;
m1->x=p->x;
m1->y=p->y;
}
if(p->y<ymin)
{
ymin=p->y;
m3->x=p->x;
m3->y=p->y;
}
}
/*cout<<a->urm->x<<endl;
cout<<a->urm->urm->x<<endl;
cout<<a->urm->urm->urm->x<<endl;
cout<<a->urm->urm->urm->urm->x<<endl;*/
l->urm=m1;
m1->pre=l;
m1->urm=m2;
m2->pre=m1;
m2->urm=m3;
m3->pre=m2;
m3->urm=m4;
m4->pre=m3;
m4->urm=l;
l->pre=m4;
l=f1(l, a);
cout<<"Puncte contur:\n";
/*for(p=l->urm;p!=l;p=p->urm)
cout<<p->x<<' '<<p->y<<endl;*/
TL2 x1, x2, x3;
x1=(TL2)malloc (sizeof(TCel2));
x2=(TL2)malloc (sizeof(TCel2));
x3=(TL2)malloc (sizeof(TCel2));
float ang, dleft=0, dright=0, apq, bpq, u;
for(p=l->urm, q=p->urm;p!=l->pre;p=p->urm, q=q->urm)
{
dright = 0;
dleft=0;
dmax=0;
for(r=q->urm;r!=p;r=r->urm)
{
if(r==l)
r=r->urm;
if(r->x==p->x&&r->y==p->y)
break;
d=d3p(p,q,r);
if(d<0)
d=d*(-1);
if(d>dmax)
{dmax=d;
b=r;}
}
apq=((p->y)-(q->y))/((p->x)-(q->x));
bpq=(p->y)-(apq*(p->x));
//x3->y=b->y;
//x3->x=((x3->y)-bpq)/apq;
//ang=angle(x3,p,q);
//u=(((b->x)-(p->x))*((q->x)-(p->x))+((b->y)-(p->y))*((q->y)-(p->y)))/(((p->y)-(q->y))+((p->x)-(q->x)));
//x2->x=(p->x)+u*((q->x)-(p->x));
//x2->y=(p->y)+u*((q->y)-(p->y));
x2=proj(p, q, b);
for(x1=b->urm;x1!=b;x1=x1->urm)
{
if(x1==l)
x1=x1->urm;
if(x1->x==b->x&&x1->y==b->y)
break;
d=d3p(b, x2, x1);
if(d>dright)
dright=d;
if(d<dleft)
dleft=d;
}
dleft=dleft*(-1);
if((dright+dleft)*dmax<smin)
smin=(dright+dleft)*dmax;
}
int prec=0;
float cont=smin;
while(cont>=1)
{
prec++;
cont/=10;
}
g.precision(prec+2);
g<<smin<<endl;
//cout<<"\nAria minima a dreptunghiului circumscris: \n"<<smin;
f.close();
g.close();
//getch();
return 0;
}