#include<stdio.h>
#include <iostream>
#include <math.h>
using namespace std;
#define ABS_FLOAT_0 0.0001
double xx[88],yy[88];
struct node
{
double x, y;
} st1, ed1, st2, ed2;
struct point_float
{
float x;
float y;
};
double get_area(node a0, node a1, node a2) //求有向面积
{
double s = a0.x*a1.y + a2.x*a0.y +a1.x*a2.y - a2.x*a1.y - a0.x*a2.y - a1.x*a0.y;
return s;
}
float GetTriangleSquar(const point_float pt0, const point_float pt1, const point_float pt2)
{
point_float AB, BC;
AB.x = pt1.x - pt0.x;
AB.y = pt1.y - pt0.y;
BC.x = pt2.x - pt1.x;
BC.y = pt2.y - pt1.y;
return fabs((AB.x * BC.y - AB.y * BC.x)) / 2.0f;
}
bool IsInTriangle(const point_float A, const point_float B, const point_float C, const point_float D)
{
float SABC, SADB, SBDC, SADC;
SABC = GetTriangleSquar(A, B, C);
SADB = GetTriangleSquar(A, D, B);
SBDC = GetTriangleSquar(B, D, C);
SADC = GetTriangleSquar(A, D, C);
float SumSuqar = SADB + SBDC + SADC;
if ((-ABS_FLOAT_0 < (SABC - SumSuqar)) && ((SABC - SumSuqar) < ABS_FLOAT_0))
{
return true;
}
else
{
return false;
}
}
int pd()
{
double s1 = get_area(st1, ed1, st2);
double s2 = get_area(st1, ed1, ed2);
double s3 = get_area(st2, ed2, st1);
double s4 = get_area(st2, ed2, ed1);
if(s1 * s2 <= 0 && s3 * s4 <= 0)
return 1; //printf("Interseetion\n");
else
return 0; //printf("Not Interseetion\n");
}
int main()
{
int t,flag,i,j,k,h;
scanf("%d",&t);
while(t--)
{
scanf("%lf %lf %lf %lf %lf %lf",&xx[1],&yy[1],&xx[2],&yy[2],&xx[3],&yy[3]);
scanf("%lf %lf %lf %lf %lf %lf",&xx[4],&yy[4],&xx[5],&yy[5],&xx[6],&yy[6]);
flag=0;
for(i=1; i<=3; i++)
{
st1.x=xx[i];
st1.y=yy[i];
for(k=1; k<=3; k++)
{
if(k!=i)
{
ed1.x=xx[k];
ed1.y=yy[k];
for(j=4; j<=6; j++)
{
st2.x=xx[j];
st2.y=yy[j];
for(h=4; h<=6; h++)
{
if(h!=j)
{
ed2.x=xx[h];
ed2.y=yy[h];
if(pd())
{
flag=1;
break;
}
}
}
}
}
}
} //利用两线段是否相交 判断三角形是否相交
if(flag)
{
printf("intersect\n");
continue;
}
point_float A, B, C, P;
A.x =xx[1];
A.y =yy[1] ;
B.x =xx[2] ;
B.y =yy[2] ;
C.x =xx[3] ;
C.y =yy[3] ;
//判断三个点是否在三角形内
for(i=4; i<=6; i++)
{
P.x=xx[i];
P.y=yy[i];
if(IsInTriangle(A, B, C, P))
{
flag=1;
break;
}
}
//再判断A在B里面吗
A.x =xx[4];
A.y =yy[4] ;
B.x =xx[5] ;
B.y =yy[5] ;
C.x =xx[6] ;
C.y =yy[6] ;
//判断三个点是否在三角形内
for(i=1; i<=3; i++)
{
P.x=xx[i];
P.y=yy[i];
if(IsInTriangle(A, B, C, P))
{
flag=1;
break;
}
}
if(flag)
{
printf("contain\n");
continue;
}
else printf("disjoint\n");
}
return 0;
}
点在多边形内
const int offset=1000;
struct Point{
double x,y;
}Q[205],p[205];
double Cross(Point pi,Point pj,Point pk)
{ // (pi,pj)X(pi,pk)
return (pj.x-pi.x)*(pk.y-pi.y)-(pj.y-pi.y)*(pk.x-pi.x);
}
//arr 多边形顶点数 len 点数 p 点
int InPolygon(const Point *arr,const int &len,const Point &p,int on_edge=1)
{
Point q;
int i=0,counter;
while(i<len)
{
q.x=rand()+offset;//随机取一个足够远的点q
q.y=rand()+offset;//以p为起点q为终点做射线L
for(counter=i=0;i<len;i++)
{//依次对多边形的每条边进行考察
if(fabs(Cross(p,arr[i],arr[(i+1)%len]))<eps &&
(arr[i].x-p.x)*(arr[(i+1)%len].x-p.x)<eps && (arr[i].y-p.y)*(arr[(i+1)%len].y-p.y)<eps)
return on_edge; //点p在边上,返回on_edge
else if(fabs(Cross(p,q,arr[i]))<eps) break; //点arr[i]在射线pq上,停止本循环,另取q
else if(Cross(p,arr[i],q)*Cross(p,arr[(i+1)%len],q)<-eps &&
Cross(arr[i],p,arr[(i+1)%len])*Cross(arr[i],q,arr[(i+1)%len])<-eps)
counter++;
}
}
return counter&1;
}
最小圆覆盖
double get_distance(const point a, const point b)//两点之间的距离
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
point get_circle_center(const point a, const point b, const point c)//得到三角形外接圆的圆心
{
point center;
double a1 = b.x - a.x;
double b1 = b.y - a.y;
double c1 = (a1 * a1 + b1 * b1) / 2.0;
double a2 = c.x - a.x;
double b2 = c.y - a.y;
double c2 = (a2 * a2 + b2 * b2) / 2.0;
double d = a1 * b2 - a2 * b1;
center.x = a.x + (c1 * b2 - c2 * b1) / d;
center.y = a.y + (a1 * c2 - a2 * c1) / d;
return center;
}
//p表示定点, n表示顶点的个数, c代表最小覆盖圆圆心, r是半径
void min_cover_circle(point *p, int n, point &c, double &r)//找最小覆盖圆(这里没有用全局变量p[], 因为是为了封装一个函数便于调用)
{
random_shuffle(p, p + n);//随机函数,使用了之后使程序更快点,也可以不用
c = p[0];
r = 0;
for (int i = 1; i < n; i++)
{
if (sgn(get_distance(p[i], c) - r) > 0)//如果p[i]在当前圆的外面, 那么以当前点为圆心开始找
{
c = p[i];//圆心为当前点
r = 0;//这时候这个圆只包括他自己.所以半径为0
for (int j = 0; j < i; j++)//找它之前的所有点
{
if (sgn(get_distance(p[j], c) - r) > 0)//如果之前的点有不满足的, 那么就是以这两点为直径的圆
{
c.x = (p[i].x + p[j].x) / 2.0;
c.y = (p[i].y + p[j].y) / 2.0;
r = get_distance(p[j], c);
for (int k = 0; k < j; k++)
{
if (sgn(get_distance(p[k], c) - r) > 0)//找新作出来的圆之前的点是否还有不满足的, 如果不满足一定就是三个点都在圆上了
{
c = get_circle_center(p[i], p[j], p[k]);
r = get_distance(p[i], c);
}
}
}
}
}
}
}
int main()
{
int n;
point p[maxn];
point c; double r;
while (~scanf("%d", &n) && n)
{
for (int i = 0; i < n; i++)
scanf("%lf %lf", &p[i].x, &p[i].y);
min_cover_circle(p, n, c, r);
printf("%.2lf %.2lf %.2lf\n", c.x, c.y, r);
}
return 0;
}