三角形和圆的位置关系

来源:互联网 发布:淘宝联盟就是阿里妈妈 编辑:程序博客网 时间:2024/05/07 19:56

Problem I

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 56   Accepted Submission(s) : 9

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

在几何的世界里,有一个圆和一个三角形,现在分别告诉他们的位置,请编程判断他们之间的位置关系,是不是很简单呢?祝你好运吧~

Input

多组测试数据,第一行有一个整数t(1<=t<=100)代表case数量,对于每个case,第一行有三个整数x,y,r分别代表圆心的位置和半径,第二行有6个整数分别代表三角形的三个点(对于所有坐标绝对值小于1000,0<r<1000)

Output

每个case形如"Case #K: M",K代表case数,从1开始,M代表它们之间的关系。(如果相离或者相切输出"OO",如果三角形包含圆或者圆包含三角形输出"II",部分相交则输出"XX")

Sample Input

30 0 1-5 -5 0 5 5 00 0 1-2 -1 0 1 2 10 0 15 5 6 5 6 6

Sample Output

Case #1: IICase #2: XXCase #3: OO

#define DeBUG#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <string>#include <set>#include <sstream>#include <map>#include <list>#include <bitset>using namespace std ;#define zero {0}#define INF 0x3f3f3f3f#define EPS 1e-9typedef long long LL;const double PI = acos(-1.0);//#pragma comment(linker, "/STACK:102400000,102400000")inline int sgn(double x){    return fabs(x) < EPS ? 0 : (x < 0 ? -1 : 1);}#define N 100005struct Point;typedef Point Vec;struct Point{    double x, y;    Point () {}    Point(double a, double b)    {        x = a;        y = b;    }    Vec operator + (const Vec &b)//点加法    {        return Vec(x + b.x, y + b.y);    }    Vec operator - (const Vec &b)//点减法    {        return Vec(x - b.x, y - b.y);    }    Vec operator * (const double &p)//点与常数相乘    {        return Vec(x * p, y * p);    }    Vec operator / (const double &p)//点除以常数    {        return Vec(x / p, y / p);    }    bool operator < (const Point &b)//平面直角坐标系中左下方的为小    {        return x < b.x || (sgn(x - b.x) == 0 && y < b.y);    }    bool operator == (const Point &b)//点相等判断    {        return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;    }};double dis(Point a, Point b){    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}inline double dotDet(Vec a, Vec b)//点乘{    return a.x * b.x + a.y * b.y;}inline double crossDet(Vec a, Vec b)//叉乘{    return a.x * b.y - a.y * b.x;}inline double crossDet(Point o, Point a, Point b)//向量叉乘{    return crossDet(a - o, b - o);}inline double triArea(Point o, Point b, Point c)//三点求三角形面积{    return fabs(crossDet(b - o, c - o)) / 2;}inline bool onSeg(Point x, Point a, Point b)//判断点在线段ab上,加上||x==a||x==b在端点也算{    return sgn(crossDet(a - x, b - x)) == 0 && sgn(dotDet(a - x, b - x)) < 0 || x == a || x == b;}inline double vecLen(Vec a)//求一点到原点距离{    return sqrt(dotDet(a, a));}double pt2Line(Point x, Point a, Point b)//这里已经fabs保证为正,x到直线ab的距离(投影),注意被投影向量为ax,投向ab{    Vec v1 = b - a, v2 = x - a;    return fabs(crossDet(v1, v2) / vecLen(v1));}// Polygon classstruct Poly//平面类{    vector<Point> pt;//保存平面对应的端点    Poly()    {        pt.clear();    }    ~Poly() {}    Poly(vector<Point> pt): pt(pt) {} //使用vector进行初始化    Point operator [](int x) const//重载[]返回对应端点    {        return pt[x];    }    int size()//返回对应平面点数    {        return pt.size();    }} ;int ptInPoly(Point p, Poly &poly)//判断点在多边形内,用vector<Point>初始化多边形,-1在边上,0在外面,1在里面{    int wn = 0, sz = poly.size();    for (int i = 0; i < sz; i++)    {        if (onSeg(p, poly[i], poly[(i + 1) % sz])) return -1;        int k = sgn(crossDet(poly[(i + 1) % sz] - poly[i], p - poly[i]));        int d1 = sgn(poly[i].y - p.y);        int d2 = sgn(poly[(i + 1) % sz].y - p.y);        if (k > 0 && d1 <= 0 && d2 > 0) wn++;        if (k < 0 && d2 <= 0 && d1 > 0) wn--;    }    if (wn != 0) return 1;    return 0;}double pt2Seg(Point x, Point a, Point b)//x在线段ab上的投影,这里保证为正{    if (a == b) return vecLen(x - a);    Vec v1 = b - a, v2 = x - a, v3 = x - b;    if (sgn(dotDet(v1, v2)) < 0) return vecLen(v2);    if (sgn(dotDet(v1, v3)) > 0) return vecLen(v3);    return fabs(crossDet(v1, v2)) / vecLen(v1);}bool incirle(Point p[], Point o, double r){    int flag = 0;    for (int i = 0; i < 3; i++)    {        if (sgn(r - dis(o, p[i])) < 0)            return 0;    }    return 1;}int outtri1(Point p[], Point o, double r){    for (int i = 0; i < 3; i++)    {        if (sgn(r - pt2Line(o, p[i], p[i + 1])) > 0)        {            return 0;        }    }    return 1;}int outtri(Point p[], Point o, double r){     for (int i = 0; i < 3; i++)    {        if (sgn(r - dis(o, p[i])) > 0)            return 0;    }    for (int i = 0; i < 3; i++)    {        if (sgn(r - pt2Seg(o, p[i], p[i + 1])) > 0)        {            return 0;        }    }    return 1;}int cnt = 1;int main(){#ifdef DeBUGs    freopen("C:\\Users\\Sky\\Desktop\\1.in", "r", stdin);#endif    int T;    scanf("%d", &T);    while (T--)    {        double x, y, r;        scanf("%lf%lf%lf", &x, &y, &r);        std::vector<Point> v;        Point p[5];        for (int i = 0; i < 3; i++)        {            scanf("%lf%lf", &p[i].x, &p[i].y);            v.push_back(p[i]);        }        p[3] = p[0];        Poly tri(v);        Point o(x, y);        printf("Case #%d: ", cnt++);        int flag = 0;        if(incirle(p, o, r))//先判断三角形在圆内        {            printf("II\n");        }        else if (ptInPoly(o, tri) == 1)//如果点在三角形内两种情况        {            if (outtri1(p, o, r))//不相交            {                printf("II\n");            }            else            {                printf("XX\n");            }        }        else        {            if (outtri(p, o, r))//圆心在三角形外且不相交            {                printf("OO\n");            }            else                printf("XX\n");        }    }    return 0;}



0 0
原创粉丝点击