#include <iostream>
#include <cmath>
#include <vector>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
using namespace std; #define MAX_N 110 /*------------------常量区-------------------*/ const double INF = 1e10; // 无穷大
const double EPS = 1e-; // 计算精度
const double PI = acos(-1.0);// PI
const int PINXING = ; // 平行
const int XIANGJIAO = ; // 相交
const int XIANGLI = ; // 相离
const int GONGXIAN = ; // 共线
const int CHONGDIE = -; // 重叠
const int INSIDE = ; // 点在图形内部
const int OUTSIDE = ; // 点在图形外部
const int BORDER = ; // 点在图形边界 /*-----------------类型定义区----------------*/ struct Point { // 二维点或矢量
double x, y;
//double angle, dis;
Point() {}
Point(double x0, double y0): x(x0), y(y0) {}
void read()
{
scanf("%lf%lf",&x,&y);
}
};
struct Point3D { //三维点或矢量
double x, y, z;
Point3D() {}
Point3D(double x0, double y0, double z0): x(x0), y(y0), z(z0) {}
};
struct Line { // 二维的直线或线段
Point p1, p2;
Line() {}
Line(Point p10, Point p20): p1(p10), p2(p20) {}
void read()
{
scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y);
}
};
struct Line3D { // 三维的直线或线段
Point3D p1, p2;
Line3D() {}
Line3D(Point3D p10, Point3D p20): p1(p10), p2(p20) {}
};
struct Rect { // 用长宽表示矩形的方法 w, h分别表示宽度和高度
double w, h;
Rect() {}
Rect(double _w,double _h) : w(_w),h(_h) {}
};
struct Rect_2 { // 表示矩形,左下角坐标是(xl, yl),右上角坐标是(xh, yh)
double xl, yl, xh, yh;
Rect_2() {}
Rect_2(double _xl,double _yl,double _xh,double _yh) : xl(_xl),yl(_yl),xh(_xh),yh(_yh) {}
};
struct Circle { //圆
Point c;
double r;
Circle() {}
Circle(Point _c,double _r) :c(_c),r(_r) {}
}; typedef vector<Point> Polygon; // 二维多边形
typedef vector<Point> Points; // 二维点集 /*-------------------基本函数区---------------------*/ inline double max(double x,double y)
{
return x > y ? x : y;
}
inline double min(double x, double y)
{
return x > y ? y : x;
}
inline bool ZERO(double x) // x == 0
{
return (fabs(x) < EPS);
}
inline bool ZERO(Point p) // p == 0
{
return (ZERO(p.x) && ZERO(p.y));
}
inline bool ZERO(Point3D p) // p == 0
{
return (ZERO(p.x) && ZERO(p.y) && ZERO(p.z));
}
inline bool EQ(double x, double y) // eqaul, x == y
{
return (fabs(x - y) < EPS);
}
inline bool NEQ(double x, double y) // not equal, x != y
{
return (fabs(x - y) >= EPS);
}
inline bool LT(double x, double y) // less than, x < y
{
return ( NEQ(x, y) && (x < y) );
}
inline bool GT(double x, double y) // greater than, x > y
{
return ( NEQ(x, y) && (x > y) );
}
inline bool LEQ(double x, double y) // less equal, x <= y
{
return ( EQ(x, y) || (x < y) );
}
inline bool GEQ(double x, double y) // greater equal, x >= y
{
return ( EQ(x, y) || (x > y) );
} // 输出浮点数前,防止输出-0.00调用该函数进行修正!
inline double FIX(double x)
{
return (fabs(x) < EPS) ? : x;
} /*------------------二维矢量运算重载区---------------------*/
bool operator==(Point p1, Point p2)
{
return ( EQ(p1.x, p2.x) && EQ(p1.y, p2.y) );
}
bool operator!=(Point p1, Point p2)
{
return ( NEQ(p1.x, p2.x) || NEQ(p1.y, p2.y) );
}
bool operator<(Point p1, Point p2)
{
if (NEQ(p1.x, p2.x)) {
return (p1.x < p2.x);
} else {
return (p1.y < p2.y);
}
}
Point operator+(Point p1, Point p2)
{
return Point(p1.x + p2.x, p1.y + p2.y);
}
Point operator-(Point p1, Point p2)
{
return Point(p1.x - p2.x, p1.y - p2.y);
}
double operator*(Point p1, Point p2) // 计算叉乘 p1 × p2
{
return (p1.x * p2.y - p2.x * p1.y);
}
double operator&(Point p1, Point p2) { // 计算点积 p1·p2
return (p1.x * p2.x + p1.y * p2.y);
}
double Norm(Point p) // 计算矢量p的模
{
return sqrt(p.x * p.x + p.y * p.y);
} /*-------------------基本函数区------------------*/ //得到两点之间的距离
double Dis(Point p1,Point p2)
{
return sqrt( (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) );
} //求二维平面上点到直线的距离
double Dis(Point p, Line L)
{
return ( fabs((p - L.p1) * (L.p2 - L.p1)) / Norm(L.p2 - L.p1) );
} //得到两点之间距离的平方,为减少误差用
double Dis2(Point p1,Point p2)
{
return (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y);
} //返回A关于B的对称点C,即(A+C)/2=b
Point SymmetryPoint(Point A,Point B)
{
Point C;
C.x = *B.x-A.x;
C.y = *B.y-A.y;
return C;
} // 把矢量p旋转角度angle (弧度表示)
// angle > 0表示逆时针旋转
// angle < 0表示顺时针旋转
Point Rotate(Point p, double angle)
{
Point result;
result.x = p.x * cos(angle) - p.y * sin(angle);
result.y = p.x * sin(angle) + p.y * cos(angle);
return result;
} //得到向量p与x正半轴的夹角[0,2PI)
double GetAngle(Point p)
{
double tmp=atan2(p.y,p.x);
if(tmp<) tmp=*PI+tmp;
return tmp;
}
//得到两个向量之间的夹角[0,PI]
//若p1按顺时针转到p2的角小于PI(p1在p2的逆时针方向),则返回正数.否则返回负数.
double GetAngle(Point p1,Point p2)
{
double tmp = GetAngle(p1) - GetAngle(p2);
if( GT( tmp,PI) ) return -(*PI-tmp);
if( LEQ( tmp,-PI) ) return (tmp+*PI);
return tmp;
} // 判断二维平面上点是否在线段上
// 输入:任意点p,和任意直线L
// 输出:p在线段上返回1,否则返回0
bool OnSeg(Point p, Line L)
{
return ( ZERO( (L.p1 - p) * (L.p2 - p) ) &&
LEQ((p.x - L.p1.x)*(p.x - L.p2.x), ) &&
LEQ((p.y - L.p1.y)*(p.y - L.p2.y), ) );
} // 判断二维平面上点p是否在直线L上,在线段上返回1,否则返回0
bool OnLine(Point p, Line L)
{
return ZERO( (p - L.p1) * (L.p2 - L.p1) );
} bool OnCir(Point p,Circle cir)
{
return EQ( (p.x-cir.c.x)*(p.x-cir.c.x)+(p.y-cir.c.y)*(p.y-cir.c.y),cir.r*cir.r );
} //得到点p到直线L的距离,并返回p到直直线L的最近点rep
double PointToLine(Point p,Line L,Point& rep)
{
if(L.p1==L.p2)
{
rep=L.p1;
return Dis(p,L.p1);
}
Point a,b;
a = L.p2-L.p1;
b = p-L.p1;
double dis12 = Dis(L.p1,L.p2);
double dis = ( fabs(a*b) )/dis12; double k = (a&b)/(Norm(a)*dis12) ;
rep.x = L.p1.x + k*(L.p2.x-L.p1.x);
rep.y = L.p1.y + k*(L.p2.y-L.p1.y); return dis;
} //得到点P到线段L的距离,并放回p到线段L的最近点rep
double PointToSeg(Point P, Line L,Point& rep)
{
if(L.p1 == L.p2)
{
rep = L.p1;
return Dis(rep,P);//如果线段是一个点,返回这个点。
}
Point result;
double a, b, t; a = L.p2.x - L.p1.x;
b = L.p2.y - L.p1.y;
t = ( (P.x - L.p1.x) * a + (P.y - L.p1.y) * b ) / (a * a + b * b);//线段上的投影 if ( GEQ(t, ) && LEQ(t, ) ) {
result.x = L.p1.x + a * t;//值得学习的由比例求坐标的方法。
result.y = L.p1.y + b * t;
} else {
if ( Norm(P - L.p1) < Norm(P - L.p2) ) {
result = L.p1;
} else {
result = L.p2;
}
}
return Dis(result, P);
} //返回点A关于直线L的对称点
Point SymmetryPonitToLine(Point A,Line L)
{
Point B;
PointToLine(A, L, B);//A在L上的投影
return SymmetryPoint(A, B);
} /*-------------------几何题面积计算(注意正负!)----------------------*/ // 根据三个顶点坐标计算三角形面积
// 面积的正负按照右手旋规则确定,向量AB->向量AC
double Area(Point A, Point B, Point C)
{
return ((B-A)*(C-A) / 2.0);
} // 根据三条边长计算三角形面积
double Area(double a, double b, double c)
{
double s = (a + b + c) / 2.0;
return sqrt(s * (s - a) * (s - b) * (s - c));
} //求圆的面积
double Area(Circle C)
{
return PI * C.r * C.r;
} // 计算多边形面积,复杂度:O(顶点数)
// 面积的正负按照右手旋规则确定,顺时针为负
double Area(Polygon _poly)
{
int nsize=_poly.size();
double area=;
for(int i=;i<nsize;i++)
{
area += _poly[i]*_poly[(i+)%nsize];
}
return area/2.0;
} //求两条直线之间的关系(二维)
//输入:两条不为点的直线
//输出:相交返回XIANGJIAO和交点p,平行返回PINGXING,共线返回GONGXIAN
int LineAndLine(Line L1,Line L2,Point &p)
{
Point px,py;
px = L1.p1 - L1.p2;
py = L2.p1 - L2.p2;
if( EQ(px*py,) )//平行或者共线
{
if( ZERO( (L2.p1-L1.p1)*py ) ) //共线
{
return GONGXIAN;
}
return PINXING;
} double xa,xb,xc,ya,yb,yc;
xa=(L1.p2.y-L1.p1.y); xb=(L1.p1.x-L1.p2.x); xc=(L1.p1.y*L1.p2.x-L1.p1.x*L1.p2.y);
ya=(L2.p2.y-L2.p1.y); yb=(L2.p1.x-L2.p2.x); yc=(L2.p1.y*L2.p2.x-L2.p1.x*L2.p2.y); p.y = (xa*yc-xc*ya)/(xb*ya-xa*yb);
p.x = (xb*yc-xc*yb)/(xa*yb-xb*ya); return XIANGJIAO;
} //判断两条线段是否相交,相交返回1
bool SegAndSeg(Line L1,Line L2)
{
return ( GEQ( max(L1.p1.x, L1.p2.x), min(L2.p1.x, L2.p2.x) ) &&
GEQ( max(L2.p1.x, L2.p2.x), min(L1.p1.x, L1.p2.x) ) &&
GEQ( max(L1.p1.y, L1.p2.y), min(L2.p1.y, L2.p2.y) ) &&
GEQ( max(L2.p1.y, L2.p2.y), min(L1.p1.y, L1.p2.y) ) &&
LEQ( ((L2.p1 - L1.p1) * (L1.p2 - L1.p1)) * ((L2.p2 - L1.p1) * (L1.p2 - L1.p1)), ) &&
LEQ( ((L1.p1 - L2.p1) * (L2.p2 - L2.p1)) * ((L1.p2 - L2.p1) * (L2.p2 - L2.p1)), ) );
} //求两条线段交点(二维)
//输入:两条不为点的直线
//输出:相交返回XIANGJIAO和交点p,相离返回XIANGLI,重叠返回CHONGDIE
int SegAndSeg(Line L1,Line L2,Point &p)
{ double signx,signy; //跨立实验
if( LEQ(signx=( ((L1.p2-L1.p1)*(L1.p1-L2.p1))*((L1.p2-L1.p1)*(L1.p1-L2.p2)) ),) &&
LEQ(signy=( ((L2.p2-L2.p1)*(L2.p1-L1.p1))*((L2.p2-L2.p1)*(L2.p1-L1.p2)) ),) )
{
if( ZERO(signx) && ZERO(signy) )
{
//线段共线
signx = min( max(L1.p1.x,L1.p2.x),max(L2.p1.x,L2.p2.x) )-
max( min(L1.p1.x,L1.p2.x),min(L2.p1.x,L2.p2.x) ); signy = min( max(L1.p1.y,L1.p2.y),max(L2.p1.y,L2.p2.y) )-
max( min(L1.p1.y,L1.p2.y),min(L2.p1.y,L2.p2.y) ); if( ZERO(signx) && ZERO(signy) ) //说明共线,且相交一点
{
if(L1.p1==L2.p1||L1.p1==L2.p2) p=L1.p1;
if(L1.p2==L2.p1||L1.p2==L2.p2) p=L1.p2;
return XIANGJIAO;
}
else if( GEQ(signx, ) && GEQ(signy, ) )
{
return CHONGDIE;//重叠
}
else
{
return XIANGLI;//相离
}
}
return LineAndLine(L1, L2, p);//转化为直线相交
}
return XIANGLI;//相离
} // 判断点p是否在简单多边形poly内, 多边形可以是凸的或凹的
// poly的顶点数目要大于等于3
// 返回值为:
// INSIDE -- 点在poly内
// BORDER -- 点在poly边界上
// OUTSIDE -- 点在poly外
int InPolygon(const Polygon poly, Point p)
{
int i, n, count;
Line ray, side; n = poly.size();
count = ;
ray.p1 = p;
ray.p2.y = p.y;
ray.p2.x = - INF;// 设定一个极大值 for (i = ; i < n; i++) {
side.p1 = poly[i];
side.p2 = poly[(i+)%n]; if( OnSeg(p, side) ) {
return BORDER;
}
// 如果side平行x轴则不作考虑
if ( EQ(side.p1.y, side.p2.y) ) {
continue;
}
if (OnSeg(side.p1, ray)) {
if ( GT(side.p1.y, side.p2.y) ) count++;
} else if (OnSeg(side.p2, ray)) {
if ( GT(side.p2.y, side.p1.y) ) count++;
} else if ( SegAndSeg(ray, side) ) {
count++;
}
}
return ((count % == ) ? INSIDE : OUTSIDE);
} //得到直线与圆的交点
int LineToCir(Line L,Circle R,Point p[])
{
if(L.p1 == L.p2)//当直线为1个点时
{
if( EQ( Dis(L.p1, R.c),R.r ) )
{
p[]=L.p1;
return ;
}
else return ;//相离
}
Point tp;//表示圆心在直线L上的投影。
double dis=PointToLine(R.c, L,tp );
if( LT(R.r, dis) )//相离
{
return ;
}
if( EQ(dis,R.r) )//相切
{
p[]=tp;
return ;
}
double len=sqrt(R.r*R.r-dis*dis);
Point onep=L.p2-L.p1;
double _t = len/Norm(onep); p[].x =tp.x + onep.x*_t;
p[].y =tp.y + onep.y*_t; onep=L.p1-L.p2;
p[].x =tp.x + onep.x*_t;
p[].y =tp.y + onep.y*_t; return ;
} //得到三角形外接圆
//注意:A,B,C三点不能共线
Circle OutCircle(Point A,Point B,Point C)
{
Circle tmp;
double a, b, c, c1, c2;
double xA, yA, xB, yB, xC, yC;
a = Dis(A, B);
b = Dis(B, C);
c = Dis(C, A);
//根据 S = a * b * c / R / 4;求半径 R
tmp.r = (a*b*c)/( fabs(Area(A,B,C)) *4.0);
xA = A.x;
yA = A.y;
xB = B.x;
yB = B.y;
xC = C.x;
yC = C.y;
c1 = (xA*xA+yA*yA - xB*xB-yB*yB) / ;
c2 = (xA*xA+yA*yA - xC*xC-yC*yC) / ;
tmp.c.x = (c1*(yA - yC)-c2*(yA - yB)) / ((xA - xB)*(yA - yC)-(xA - xC)*(yA - yB));
tmp.c.y = (c1*(xA - xC)-c2*(xA - xB)) / ((yA - yB)*(xA - xC)-(yA - yC)*(xA - xB));
return tmp;
} //得到三角形内切圆
//注意:A,B,C三点不能共线
Circle InCircle(Point A,Point B,Point C)
{
Circle rec;
double a=Dis(B,C);
double b=Dis(A,C);
double c=Dis(A,B);
rec.c.x = (a*A.x+b*B.x+c*C.x)/(a+b+c);
rec.c.y = (a*A.y+b*B.y+c*C.y)/(a+b+c);
rec.r = *fabs( Area(A,B,C) )/(a+b+c);
return rec;
} //得到两圆的面积并
double CirArea(Circle _c1,Circle _c2)
{
if(_c2.r<_c1.r) swap(_c1,_c2); //保证_c2的半径大
double d12 = Dis(_c1.c,_c2.c);
if( LEQ(_c1.r+_c2.r,d12) )//相离
{
return ;
}
if( LEQ(d12+_c1.r, _c2.r) )//包含
{
return Area(_c1);
}
//相交
double _area=;
_area -= 2.0*Area(_c1.r,_c2.r,d12);
double ang1 = acos( (d12*d12+_c1.r*_c1.r-_c2.r*_c2.r) / (*d12*_c1.r) );
double ang2 = acos( (d12*d12+_c2.r*_c2.r-_c1.r*_c1.r) / (*d12*_c2.r) );
_area += ang1*_c1.r*_c1.r+ang2*_c2.r*_c2.r;
return _area;
} //得到两个圆的交点p[2]
//返回值为交点数,-1为两圆重叠。
int CirAndCir(Circle _c1,Circle _c2,Point p[])
{
if(_c2.r < _c1.r) swap(_c1,_c2); //保证_c2的半径大
double d12 = Dis(_c1.c,_c2.c);
if( LT(_c1.r+_c2.r,d12) )//相离
{
return ;
}
if( LT(d12+_c1.r, _c2.r) )//包含
{
return ;
}
if(_c1.c == _c2.c)//两个圆重叠
{
return -;
}
Point u,v;
double t;
double r1=_c1.r,r2=_c2.r; t=( +(r1*r1-r2*r2)/(Dis(_c1.c,_c2.c)*Dis(_c1.c,_c2.c)) ) /;
u.x = _c1.c.x + (_c2.c.x-_c1.c.x)*t;
u.y = _c1.c.y + (_c2.c.y-_c1.c.y)*t; v.x = u.x + _c1.c.y - _c2.c.y;
v.y = u.y - _c1.c.x + _c2.c.x; Line _l(u,v);
return LineToCir(_l,_c1,p);
} //求凸包Graham-Scan(GS)算法,复杂度nlog(n),内附两种模式,最小点集凸包,与最大点集凸包。
//调用GetConvex_GS(Point ps[],int pn,Point cx[],int &cxn)
//其中ps是输入的点集,pn为ps的大小,cx为返回的凸包集,cxn表示凸包的大小。
//注意:pn必须>=3,下标都是从0开始,返回的凸包集为逆时针。且如果点带标号,一样处理。 int GScmp(Point a,Point b)
{
double _tmp=a*b;
Point zero;
zero.x=;
zero.y=;
if( ZERO(_tmp) )
{
return Dis2(a,zero)>Dis2(b,zero);
}
return _tmp > ;
} void GetConvex_GS(Point ps[],int pn,Point cx[],int &cxn)
{
Polygon pg; pg.clear();
//先找出最下面,如果有相同的找最靠左,也就找y轴最小的,然后y相同时选x最小。
Point minp=ps[];
for(int i=;i<pn;i++)
{
if( ps[i].y < minp.y )
{
minp = ps[i];
}
else if(EQ(ps[i].y, minp.y) && ps[i].x < minp.x)
{
minp = ps[i];
}
} for(int i=;i<pn;i++)
{
ps[i].x -= minp.x;
ps[i].y -= minp.y;
pg.push_back( ps[i] );
} //排序
sort(pg.begin(),pg.end(),GScmp); //在这一步,除去与minp共线的点。
long int pgsize=pg.size();
int pgcnt=;
for(int i=;i<pgsize;i++)
{
if( !ZERO(pg[i]*pg[pgcnt-]) )
{
pg[ pgcnt++ ] = pg[i];
}
} cxn = ;
cx[ cxn++ ] = minp; if( !(ZERO(pg[].x) && ZERO(pg[].y)) )//不为一点时
{
pg[].x += minp.x;
pg[].y += minp.y;
cx[ cxn++ ] = pg[];//必须保存id for(int i=;i < pgcnt;i++)
{
pg[i].x += minp.x;
pg[i].y += minp.y; double _tmp = (cx[cxn-]-cx[cxn-])*(pg[i]-cx[cxn-]);
// 无法处理重复点!
// nice !
while( LEQ(_tmp, ) )
{
cxn--;
//if(cxn==1) break;//只剩下一个的时候,退出
_tmp = (cx[cxn-]-cx[cxn-])*(pg[i]-cx[cxn-]);
}
cx[ cxn++ ] = pg[i];
}
}
//已经找到了,最小凸包集,且为逆时针排序。
/*
//接下来步骤为找出所有在凸包边界上的点,并按逆时针排序。
sort(ps,ps+pn,GScmp);
int cxn1=0;
int tj=0;
for(int i=0;i<pn;i++)
{
ps[i].x += minp.x;
ps[i].y += minp.y;
Line l(cx[tj],cx[(tj+1)%cxn]);
if( OnSeg(ps[i], l) )
{
ps[ cxn1++ ] = ps[i];
continue;
}
if( tj+1<cxn && GEQ( (cx[tj+1]-minp)*(ps[i]-minp),0 ) )
{
tj++;
}
l.p1 = cx[ tj ];
l.p2 = cx[ (tj+1)%cxn ];
if(OnSeg(ps[i], l)) ps[cxn1++]=ps[i];
}
cxn=cxn1;
for(int i=0;i<cxn1;i++)
cx[i]=ps[i];
//接下来的步骤是,将凸包点集调整为逆时针,其实只需要调整斜率最大的一条边。
tj=1;
Line l(minp,cx[0]);
while(tj<cxn && OnSeg(cx[tj], l)) tj++;
tj--;
for(int i=0;i<=tj;i++)
cx[i] = ps[tj-i];
////////////////////////////////////
*/
} /*---------------------代码区---------------------------*/ //what the fuck
double ans; //返回两条线段的最短距离
double Dis(Line l1,Line l2)
{
Point p;
return min( min(PointToSeg(l1.p1, l2,p),PointToSeg(l1.p2, l2, p))
,min(PointToSeg(l2.p1, l1,p),PointToSeg(l2.p2, l1, p)) );
} void CirAndCut(Point psn[],int n,Point psm[],int m)
{
int nid=,mid=; for(int i=;i<n;i++)
if(psn[i].y>psn[nid].y)
{
nid=i;
}
for(int i=;i<m;i++)
if(psm[i].y<psm[mid].y)
{
mid=i;
}
//找到点集n中最上点,m中的最下点。
//l 为水平向右的向量
for(int ii=;ii<n+m;ii++)
{
//第一步判断谁先 滚起来
Point nextn,nextm;
nextn = psn[(nid+)%n];
nextm = psm[(mid+)%m]; if( (nextn-psn[nid])*(psm[mid]-nextm)> )
{
//n先滚
nid = (nid+)%n;
}
else
{
mid= (mid+)%m;
}
//这里就可以得到对踵点
Line l1,l2;
l1.p1 = psn[nid];
l1.p2 = psn[ (nid-+n)%n ];
l2.p1 = psm[mid];
l2.p2 = psm[ (mid-+m)%m ];
ans = min(ans,Dis(l1, l2));
}
} Point psn[],psm[]; int main(int argc, const char * argv[]) {
int n,m;
while( scanf("%d%d",&n,&m) && (n+m) )
{
for(int i=;i<n;i++)
psn[i].read();
for(int i=;i<m;i++)
psm[i].read();
Point cn[],cm[];
int cntn,cntm;
GetConvex_GS(psn, n, cn, cntn);
GetConvex_GS(psm, m, cm, cntm);
ans = INF;
/*
if(cntn<=3||cntm<=3)
{
for(int i=0;i<cntn;i++)
{
for(int j=0;j<cntm;j++)
{
Line l(cm[j],cm[(j+1)%cntm]);
Point p;
ans = min(ans,PointToSeg(cn[i], l, p));
}
}
for(int i=0;i<cntm;i++)
{
for(int j=0;j<cntn;j++)
{
Line l(cn[j],cn[(j+1)%cntn]);
Point p;
ans = min(ans,PointToSeg(cm[i], l, p));
}
}
}
else */ CirAndCut(cn,cntn,cm,cntm);
printf("%.6lf\n",ans);
}
return ;
} /*
5 5
1 -1
2 -1
3 -1
2 -2
3 -2
-1 1
-2 1
-3 1
-2 2
-3 2
5 5
-1 1
-2 1
-3 1
-2 2
-3 2
1 -1
2 -1
3 -1
2 -2
3 -2
*/
05-11 20:55