算法模板の计算几何

1、凸包

 1 inline bool cmp(const POINT &a, const POINT &b) {
 2     if(a.y == b.y) return a.x < b.x;
 3     return a.y < b.y;
 4 }
 5 //turn left
 6 inline bool Cross(POINT &sp, POINT &ep, POINT &op) {
 7     return (sp.x - op.x) * (ep.y - op.y) - (ep.x - op.x) * (sp.y - op.y) >= 0;
 8 }
 9   
10 inline double dist(POINT &a, POINT &b) {
11     return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
12 }
13   
14 void Graham_scan() {
15     std::sort(p, p + n, cmp);
16     top = 1;
17     stk[0] = 0; stk[1] = 1;
18     for(int i = 2; i < n; ++i) {
19         while(top && Cross(p[i], p[stk[top]], p[stk[top - 1]])) --top;
20         stk[++top] = i;
21     }
22     int len = top;
23     stk[++top] = n - 2;
24     for(int i = n - 3; i >= 0; --i) {
25         while(top != len && Cross(p[i], p[stk[top]], p[stk[top - 1]])) --top;
26         stk[++top] = i;
27     }
28 }
View Code

2、旋转卡壳(POJ 3384)

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <algorithm>
  5 using namespace std;
  6  
  7 #define EPS 1e-8
  8 #define MAXN 1000
  9  
 10 inline int sgn(double x) {
 11     if(fabs(x) < EPS) return 0;
 12     return x > 0 ? 1 : -1;
 13 }
 14  
 15 struct Point {
 16     double x, y;
 17     Point(double xx = 0, double yy = 0): x(xx), y(yy) {}
 18     bool operator == (const Point &b) const {
 19         return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
 20     }
 21 };
 22 //cross
 23 inline double operator ^ (const Point &a, const Point &b) {
 24     return a.x * b.y - a.y * b.x;
 25 }
 26  
 27 inline Point operator - (const Point &a, const Point &b) {
 28     return Point(a.x - b.x, a.y - b.y);
 29 }
 30  
 31 struct Line {
 32     Point s, e;
 33     double ag;
 34 };
 35  
 36 struct polygon {
 37     Point v[MAXN];
 38     int n;
 39 } pg, res;
 40  
 41 inline double dist(Point &a, Point &b) {
 42     return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
 43 }
 44  
 45 inline double Cross(Point o, Point s, Point e) {
 46     return (s - o) ^ (e - o);
 47 }
 48 //cross_point
 49 Point operator * (const Line &a, const Line &b) {
 50     Point res;
 51     double u = Cross(a.s, a.e, b.s), v = Cross(a.e, a.s, b.e);
 52     res.x = (b.s.x * v + b.e.x * u)/(u + v);
 53     res.y = (b.s.y * v + b.e.y * u)/(u + v);
 54     return res;
 55 }
 56  
 57 int parallel(Line a, Line b) {
 58     double u = (a.e.x - a.s.x) * (b.e.y - b.s.y) - (a.e.y - a.s.y) * (b.e.x - b.s.x);
 59     return sgn(u) == 0;
 60 }
 61  
 62 inline void set_vector(double x1, double y1, double x2, double y2, Line &v) {
 63     v.s.x = x1; v.s.y = y1;
 64     v.e.x = x2; v.e.y = y2;
 65     v.ag = atan2(y2 - y1, x2 - x1);
 66 }
 67  
 68 Line vct[MAXN], deq[MAXN];
 69  
 70 bool cmp(const Line &a, const Line &b) {
 71     if(sgn(a.ag - b.ag) == 0)
 72         return sgn(Cross(b.s, b.e, a.s)) < 0;
 73     return a.ag < b.ag;
 74 }
 75  
 76 int half_planes_cross(Line *v, int vn) {
 77     int i, n;
 78     //sort(v, v + vn, cmp);
 79     for(i = n = 1; i < vn; ++i) {
 80         if(sgn(v[i].ag - v[i-1].ag) == 0) continue;
 81         v[n++] = v[i];
 82     }
 83     int head = 0, tail = 1;
 84     deq[0] = v[0], deq[1] = v[1];
 85     for(i = 2; i < n; ++i) {
 86         if(parallel(deq[tail - 1], deq[tail]) || parallel(deq[head], deq[head + 1]))
 87             return false;
 88         while(head < tail && sgn(Cross(v[i].s, v[i].e, deq[tail - 1] * deq[tail])) > 0)
 89             --tail;
 90         while(head < tail && sgn(Cross(v[i].s, v[i].e, deq[head] * deq[head + 1])) > 0)
 91             ++head;
 92         deq[++tail] = v[i];
 93     }
 94     while(head < tail && sgn(Cross(deq[head].s, deq[head].e, deq[tail - 1] * deq[tail])) > 0)
 95         --tail;
 96     while(head < tail && sgn(Cross(deq[tail].s, deq[tail].e, deq[head] * deq[head + 1])) > 0)
 97         ++head;
 98     if(tail <= head + 1) return false;
 99     res.n = 0;
100     for(i = head; i < tail; ++i)
101         res.v[res.n++] = deq[i] * deq[i + 1];
102     res.v[res.n++] = deq[head] * deq[tail];
103     res.n = unique(res.v, res.v + res.n) - res.v;
104     res.v[res.n] = res.v[0];
105     return true;
106 }
107  
108 void moving(Line v[], int vn, double r) {
109     for(int i = 0; i < vn; ++i) {
110         double dx = v[i].e.x - v[i].s.x, dy = v[i].e.y - v[i].s.y;
111         dx = dx / dist(v[i].s, v[i].e) * r;
112         dy = dy / dist(v[i].s, v[i].e) * r;
113         v[i].s.x += dy; v[i].e.x += dy;
114         v[i].s.y -= dx; v[i].e.y -= dx;
115     }
116 }
117  
118 int ix, jx;
119  
120 double dia_roataing_calipers() {
121     double dia = 0;
122     ix = jx = 0;
123     int q = 1;
124     for(int i = 0; i < res.n; ++i) {
125         while(sgn(Cross(res.v[i+1], res.v[i], res.v[q+1]) - Cross(res.v[i+1], res.v[i], res.v[q])) > 0)
126             q = (q + 1) % res.n;
127         if(sgn(dist(res.v[i], res.v[q]) - dia) > 0) {
128             dia = dist(res.v[i], res.v[q]);
129             ix = i; jx = q;
130         }
131         if(sgn(dist(res.v[i+1], res.v[q]) - dia) > 0) {
132             dia = dist(res.v[i+1], res.v[q]);
133             ix = i+1; jx = q;
134         }
135     }
136     return dia;
137 }
138  
139 int main() {
140     int n;
141     double r;
142     while(scanf("%d%lf", &n, &r) != EOF) {
143         for(int i = 0; i < n; ++i) scanf("%lf%lf", &pg.v[i].x, &pg.v[i].y);
144         pg.v[n] = pg.v[0];
145         for(int i = 0; i < n; ++i)
146             set_vector(pg.v[i].x, pg.v[i].y, pg.v[i+1].x, pg.v[i+1].y, vct[i]);
147         moving(vct, n, r);
148         half_planes_cross(vct, n);
149         dia_roataing_calipers();
150         printf("%.4f %.4f %.4f %.4f\n", res.v[ix].x, res.v[ix].y, res.v[jx].x, res.v[jx].y);
151     }
152 }
View Code

3、最小圆覆盖

  1 #include <cstdio>
  2 #include <cmath>
  3 
  4 const int MAXN = 1010;
  5 
  6 struct Point {
  7     double x, y;
  8     Point(double xx = 0, double yy = 0): x(xx), y(yy) {}
  9 };
 10 
 11 double operator ^ (const Point &a, const Point &b) {
 12     return a.x * b.y - a.y * b.x;
 13 }
 14 
 15 Point operator - (const Point &a, const Point &b) {
 16     return Point(a.x - b.x, a.y - b.y);
 17 }
 18 
 19 double dist(const Point &a, const Point &b) {
 20     double x = a.x - b.x, y = a.y - b.y;
 21     return sqrt(x * x + y * y);
 22 }
 23 
 24 struct Circle {
 25     double r;
 26     Point centre;
 27 };
 28 
 29 struct Triangle {
 30     Point t[3];
 31     double Area() {
 32         return fabs((t[1] - t[0]) ^ (t[2] - t[0]))/2;
 33     }
 34 };
 35 
 36 Circle circumcircleOfTriangle(Triangle t) {
 37     Circle tmp;
 38     double a, b, c, c1, c2;
 39     Point A(t.t[0].x, t.t[0].y);
 40     Point B(t.t[1].x, t.t[1].y);
 41     Point C(t.t[2].x, t.t[2].y);
 42     a = dist(B, C);
 43     b = dist(A, C);
 44     c = dist(A, B);
 45     tmp.r = a * b * c / t.Area() / 4;
 46     c1 = (A.x * A.x + A.y * A.y - B.x * B.x - B.y * B.y) / 2;
 47     c2 = (A.x * A.x + A.y * A.y - C.x * C.x - C.y * C.y) / 2;
 48     tmp.centre.x = (c1 * (A.y - C.y) - c2 * (A.y - B.y)) / ((A.x - B.x) * (A.y - C.y) - (A.x - C.x) * (A.y - B.y));
 49     tmp.centre.y = (c1 * (A.x - C.x) - c2 * (A.x - B.x)) / ((A.y - B.y) * (A.x - C.x) - (A.y - C.y) * (A.x - B.x));
 50     return tmp;
 51 }
 52 
 53 Circle c;
 54 Point a[MAXN];
 55 
 56 Circle MinCircle2(int tce, Triangle ce) {
 57     Circle tmp;
 58     if(tce == 0) tmp.r = -2;
 59     else if(tce == 1) {
 60         tmp.centre = ce.t[0];
 61         tmp.r = 0;
 62     }
 63     else if(tce == 2) {
 64         tmp.r = dist(ce.t[0], ce.t[1]) / 2;
 65         tmp.centre.x = (ce.t[0].x + ce.t[1].x) / 2;
 66         tmp.centre.y = (ce.t[0].y + ce.t[1].y) / 2;
 67     }
 68     else if(tce == 3) tmp = circumcircleOfTriangle(ce);
 69     return tmp;
 70 }
 71 
 72 void MinCircle(int t, int tce, Triangle ce) {
 73     Point tmp;
 74     c = MinCircle2(tce, ce);
 75     if(tce == 3) return;
 76     for(int i = 1; i <= t; ++i) {
 77         if(dist(a[i], c.centre) > c.r) {
 78             ce.t[tce] = a[i];
 79             MinCircle(i - 1, tce + 1, ce);
 80             tmp = a[i];
 81             for(int j = i; j >= 2; --j) a[j] = a[j - 1];
 82             a[1] = tmp;
 83         }
 84     }
 85 }
 86 
 87 void run(int n) {
 88     Triangle ce;
 89     MinCircle(n, 0, ce);
 90     printf("%.2f %.2f %.2f\n", c.centre.x, c.centre.y, c.r);
 91 }
 92 
 93 int main() {
 94     int n;
 95     while(scanf("%d", &n) != EOF) {
 96         if(n == 0) break;
 97         for(int i = 1; i <= n; ++i)
 98             scanf("%lf%lf", &a[i].x, &a[i].y);
 99         run(n);
100     }
101 }
View Code

4、半平面交+最远点对

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <algorithm>
  5 using namespace std;
  6 
  7 #define EPS 1e-8
  8 #define MAXN 1000
  9 
 10 inline int sgn(double x) {
 11     if(fabs(x) < EPS) return 0;
 12     return x > 0 ? 1 : -1;
 13 }
 14 
 15 struct Point {
 16     double x, y;
 17     Point(double xx = 0, double yy = 0): x(xx), y(yy) {}
 18     bool operator == (const Point &b) const {
 19         return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
 20     }
 21 };
 22 //cross
 23 inline double operator ^ (const Point &a, const Point &b) {
 24     return a.x * b.y - a.y * b.x;
 25 }
 26 
 27 inline Point operator - (const Point &a, const Point &b) {
 28     return Point(a.x - b.x, a.y - b.y);
 29 }
 30 
 31 struct Line {
 32     Point s, e;
 33     double ag;
 34 };
 35 
 36 struct polygon {
 37     Point v[MAXN];
 38     int n;
 39 } pg, res;
 40 
 41 inline double dist(Point &a, Point &b) {
 42     return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
 43 }
 44 
 45 inline double Cross(Point o, Point s, Point e) {
 46     return (s - o) ^ (e - o);
 47 }
 48 //cross_point
 49 Point operator * (const Line &a, const Line &b) {
 50     Point res;
 51     double u = Cross(a.s, a.e, b.s), v = Cross(a.e, a.s, b.e);
 52     res.x = (b.s.x * v + b.e.x * u)/(u + v);
 53     res.y = (b.s.y * v + b.e.y * u)/(u + v);
 54     return res;
 55 }
 56 
 57 int parallel(Line a, Line b) {
 58     double u = (a.e.x - a.s.x) * (b.e.y - b.s.y) - (a.e.y - a.s.y) * (b.e.x - b.s.x);
 59     return sgn(u) == 0;
 60 }
 61 
 62 inline void set_vector(double x1, double y1, double x2, double y2, Line &v) {
 63     v.s.x = x1; v.s.y = y1;
 64     v.e.x = x2; v.e.y = y2;
 65     v.ag = atan2(y2 - y1, x2 - x1);
 66 }
 67 
 68 Line vct[MAXN], deq[MAXN];
 69 
 70 bool cmp(const Line &a, const Line &b) {
 71     if(sgn(a.ag - b.ag) == 0)
 72         return sgn(Cross(b.s, b.e, a.s)) < 0;
 73     return a.ag < b.ag;
 74 }
 75 
 76 int half_planes_cross(Line *v, int vn) {
 77     int i, n;
 78     //sort(v, v + vn, cmp);
 79     for(i = n = 1; i < vn; ++i) {
 80         if(sgn(v[i].ag - v[i-1].ag) == 0) continue;
 81         v[n++] = v[i];
 82     }
 83     int head = 0, tail = 1;
 84     deq[0] = v[0], deq[1] = v[1];
 85     for(i = 2; i < n; ++i) {
 86         if(parallel(deq[tail - 1], deq[tail]) || parallel(deq[head], deq[head + 1]))
 87             return false;
 88         while(head < tail && sgn(Cross(v[i].s, v[i].e, deq[tail - 1] * deq[tail])) > 0)
 89             --tail;
 90         while(head < tail && sgn(Cross(v[i].s, v[i].e, deq[head] * deq[head + 1])) > 0)
 91             ++head;
 92         deq[++tail] = v[i];
 93     }
 94     while(head < tail && sgn(Cross(deq[head].s, deq[head].e, deq[tail - 1] * deq[tail])) > 0)
 95         --tail;
 96     while(head < tail && sgn(Cross(deq[tail].s, deq[tail].e, deq[head] * deq[head + 1])) > 0)
 97         ++head;
 98     if(tail <= head + 1) return false;
 99     res.n = 0;
100     for(i = head; i < tail; ++i)
101         res.v[res.n++] = deq[i] * deq[i + 1];
102     res.v[res.n++] = deq[head] * deq[tail];
103     res.n = unique(res.v, res.v + res.n) - res.v;
104     res.v[res.n] = res.v[0];
105     return true;
106 }
107 
108 void moving(Line v[], int vn, double r) {
109     for(int i = 0; i < vn; ++i) {
110         double dx = v[i].e.x - v[i].s.x, dy = v[i].e.y - v[i].s.y;
111         dx = dx / dist(v[i].s, v[i].e) * r;
112         dy = dy / dist(v[i].s, v[i].e) * r;
113         v[i].s.x += dy; v[i].e.x += dy;
114         v[i].s.y -= dx; v[i].e.y -= dx;
115     }
116 }
117 
118 int ix, jx;
119 
120 double dia_roataing_calipers() {
121     double dia = 0;
122     ix = jx = 0;
123     int q = 1;
124     for(int i = 0; i < res.n; ++i) {
125         while(sgn(Cross(res.v[i+1], res.v[i], res.v[q+1]) - Cross(res.v[i+1], res.v[i], res.v[q])) > 0)
126             q = (q + 1) % res.n;
127         if(sgn(dist(res.v[i], res.v[q]) - dia) > 0) {
128             dia = dist(res.v[i], res.v[q]);
129             ix = i; jx = q;
130         }
131         if(sgn(dist(res.v[i+1], res.v[q]) - dia) > 0) {
132             dia = dist(res.v[i+1], res.v[q]);
133             ix = i+1; jx = q;
134         }
135     }
136     return dia;
137 }
138 
139 int main() {
140     int n;
141     double r;
142     while(scanf("%d%lf", &n, &r) != EOF) {
143         for(int i = 0; i < n; ++i) scanf("%lf%lf", &pg.v[i].x, &pg.v[i].y);
144         pg.v[n] = pg.v[0];
145         for(int i = 0; i < n; ++i)
146             set_vector(pg.v[i].x, pg.v[i].y, pg.v[i+1].x, pg.v[i+1].y, vct[i]);
147         moving(vct, n, r);
148         half_planes_cross(vct, n);
149         dia_roataing_calipers();
150         printf("%.4f %.4f %.4f %.4f\n", res.v[ix].x, res.v[ix].y, res.v[jx].x, res.v[jx].y);
151     }
152 }
View Code

 

其他1:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef double TYPE;
#define Abs(x) (((x)>0)?(x):(-(x)))
#define Sgn(x) (((x)<0)?(-1):(1))
#define Max(a,b) (((a)>(b))?(a):(b))
#define Min(a,b) (((a)<(b))?(a):(b))
#define EPS 1e-8
#define Infinity 1e+10
#define PI acos(-1.0)//3.14159265358979323846
TYPE Deg2Rad(TYPE deg){return (deg * PI / 180.0);}
TYPE Rad2Deg(TYPE rad){return (rad * 180.0 / PI);}
TYPE Sin(TYPE deg){return sin(Deg2Rad(deg));}
TYPE Cos(TYPE deg){return cos(Deg2Rad(deg));}
TYPE ArcSin(TYPE val){return Rad2Deg(asin(val));}
TYPE ArcCos(TYPE val){return Rad2Deg(acos(val));}
TYPE Sqrt(TYPE val){return sqrt(val);}

//点
struct POINT {
    TYPE x, y;
    POINT(TYPE xx = 0, TYPE yy = 0): x(xx), y(yy) {}
};
// 两个点的距离
TYPE 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));
}
//线段
struct SEG {
    POINT a ,b;
    SEG() {};
    SEG(POINT aa, POINT bb): a(aa), b(bb) {}
};
//直线(两点式)
struct LINE {
    POINT a, b;
    LINE() {};
    LINE(POINT aa, POINT bb): a(aa), b(bb) {}
};
//直线(一般式)
struct LINE2 {
    TYPE A,B,C;
    LINE2() {};
    LINE2(TYPE AA, TYPE BB, TYPE CC): A(AA), B(BB), C(CC) {}
};
//两点式化一般式
LINE2 Line2line(const LINE &L) {
    LINE2 L2;
    L2.A = L.b.y - L.a.y;
    L2.B = L.a.x - L.b.x;
    L2.C = L.b.x * L.a.y - L.a.x * L.b.y;
    return L2;
}
// 引用返回直线 Ax + By + C =0 的系数
void Coefficient(const LINE &L, TYPE &A, TYPE &B, TYPE &C) {
    A = L.b.y - L.a.y;
    B = L.a.x - L.b.x;
    C = L.b.x * L.a.y - L.a.x * L.b.y;
}
void Coefficient(const POINT &p,const TYPE &a,TYPE &A,TYPE &B,TYPE &C) {
    A = Cos(a);
    B = Sin(a);
    C = - (p.y * B + p.x * A);
}
//直线相交的交点
POINT Intersection(const LINE &A, const LINE &B) {
    TYPE A1, B1, C1;
    TYPE A2, B2, C2;
    Coefficient(A, A1, B1, C1);
    Coefficient(B, A2, B2, C2);
    POINT I;
    I.x = - (B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1);
    I.y =   (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1);
    return I;
}
//点到直线的距离
TYPE Ptol(const POINT &p,const LINE2 &L) {
    return fabs(L.A * p.x + L.B * p.y + L.C)/Sqrt(L.A * L.A + L.B * L.B);
}
//两线段叉乘
TYPE Cross2(const SEG &p, const SEG &q) {
    return (p.b.x - p.a.x) * (q.b.y - q.a.y) - (q.b.x - q.a.x) * (p.b.y - p.a.y);
}
//有公共端点O叉乘,并判拐,若正p0->p1->p2拐向左
TYPE Cross(const POINT &a, const POINT &b, const POINT &o) {
    return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
}
//判等(值,点,直线)
bool IsEqual(const TYPE &a, const TYPE &b) {
    return (Abs(a - b) < EPS);
}
bool IsEqual(const POINT & a, const POINT & b) {
    return IsEqual(a.x, b.x) && IsEqual(a.y, b.y);
}
bool IsEqual(const LINE & A, const LINE & B) {
    TYPE A1, B1, C1;
    TYPE A2, B2, C2;
    Coefficient(A, A1, B1, C1);
    Coefficient(B, A2, B2, C2);
    return IsEqual(A1 * B2, A2 * B1) && IsEqual(A1 * C2, A2 * C1) && IsEqual(B1 * C2, B2 * C1);
}
// 判断点是否在线段上
bool IsOnSeg(const SEG &seg, const POINT &p) {
    return (IsEqual(p, seg.a) || IsEqual(p, seg.b)) ||
        (((p.x - seg.a.x) * (p.x - seg.b.x) < 0 ||
        (p.y - seg.a.y) * (p.y - seg.b.y) < 0) &&
        (IsEqual(Cross(seg.b, p, seg.a), 0)));
}

//判断两条线断是否相交,端点重合算相交
bool IsIntersect(const SEG &u, const SEG &v) {
    return (Cross(v.a, u.b, u.a) * Cross(u.b, v.b, u.a) >= 0) &&
        (Cross(u.a, v.b, v.a) * Cross(v.b, u.b, v.a) >= 0) &&
        (Max(u.a.x, u.b.x) >= Min(v.a.x, v.b.x)) &&
        (Max(v.a.x, v.b.x) >= Min(u.a.x, u.b.x)) &&
        (Max(u.a.y, u.b.y) >= Min(v.a.y, v.b.y)) &&
        (Max(v.a.y, v.b.y) >= Min(u.a.y, u.b.y));
}
//判断线段P和直线Q是否相交,端点重合算相交
bool Isonline(const SEG &p, const LINE &q) {
    SEG p1,p2,q0;
    p1.a = q.a; p1.b = p.a;
    p2.a = q.a; p2.b = p.b;
    q0.a = q.a; q0.b = q.b;
    return (Cross2(p1,q0) * Cross2(q0,p2) >= 0);
}
//判断两条线断是否平行
bool IsParallel(const LINE &A, const LINE &B) {
    TYPE A1, B1, C1;
    TYPE A2, B2, C2;
    Coefficient(A, A1, B1, C1);
    Coefficient(B, A2, B2, C2);
    return (A1 * B2 == A2 * B1);
}
//判断两条直线是否相交
bool IsIntersect(const LINE & A, const LINE & B) {
  return !IsParallel(A, B);
}
// 矩形
struct RECT {
    POINT a; // 左下点
    POINT b; // 右上点
    RECT() {}
    RECT(const POINT &aa, const POINT &bb): a(aa), b(bb) {}
};
//矩形化标准
RECT Stdrect(const RECT &q) {
    RECT p = q;
    if(p.a.x > p.b.x) swap(p.a.x , p.b.x);
    if(p.a.y > p.b.y) swap(p.a.y , p.b.y);
    return p;
}
//根据下标返回矩形的边
SEG Edge(const RECT &rect, int idx) {
    SEG edge;
    while (idx < 0) idx += 4;
    switch (idx % 4) {
        case 0: //下边
            edge.a = rect.a;
            edge.b = POINT(rect.b.x, rect.a.y);
            break;
        case 1: //右边
            edge.a = POINT(rect.b.x, rect.a.y);
            edge.b = rect.b;
            break;
        case 2: //上边
            edge.a = rect.b;
            edge.b = POINT(rect.a.x, rect.b.y);
            break;
        case 3: //左边
            edge.a = POINT(rect.a.x, rect.b.y);
            edge.b = rect.a;
            break;
        default:
            break;
    }
    return edge;
}
//矩形的面积
TYPE Area(const RECT &rect) {
    return (rect.b.x - rect.a.x) * (rect.b.y - rect.a.y);
}
//两个矩形的公共面积
TYPE CommonArea(const RECT &A, const RECT &B) {
    TYPE area = 0.0;
    POINT LL(Max(A.a.x, B.a.x), Max(A.a.y, B.a.y));
    POINT UR(Min(A.b.x, B.b.x), Min(A.b.y, B.b.y));
    if((LL.x <= UR.x) && (LL.y <= UR.y)) {
        area = Area(RECT(LL, UR));
    }
    return area;
}
// 圆
struct CIRCLE {
    TYPE x, y, r;
    CIRCLE() {}
    CIRCLE(TYPE xx, TYPE yy, TYPE zz): x(xx), y(yy), r(zz) {}
};
//圆心
POINT Center(const CIRCLE &circle) {
    return POINT(circle.x, circle.y);
}
//圆的面积
TYPE Area(const CIRCLE &circle) {
    return PI * circle.r * circle.r;
}
//两个圆的公共面积
TYPE CommonArea(const CIRCLE &A, const CIRCLE &B)
{
    TYPE area = 0.0;
    const CIRCLE & M = (A.r > B.r) ? A : B;
    const CIRCLE & N = (A.r > B.r) ? B : A;
    TYPE D = Distance(Center(M), Center(N));
    if((D < M.r + N.r) && (D > M.r - N.r)) {
        TYPE cosM = (M.r * M.r + D * D - N.r * N.r) / (2.0 * M.r * D);
        TYPE cosN = (N.r * N.r + D * D - M.r * M.r) / (2.0 * N.r * D);
        TYPE alpha = 2.0 * ArcCos(cosM);
        TYPE beta = 2.0 * ArcCos(cosN);
        TYPE TM = 0.5 * M.r * M.r * Sin(alpha);
        TYPE TN = 0.5 * N.r * N.r * Sin(beta);
        TYPE FM = (alpha / 360.0) * Area(M);
        TYPE FN = (beta / 360.0) * Area(N);
        area = FM + FN - TM - TN;
    }
    else if(D <= M.r - N.r) {
        area = Area(N);
    }
    return area;
}
//判断圆是否在矩形内(不允许相切)
bool IsInCircle(const CIRCLE &circle, const RECT &rect) {
    return (circle.x - circle.r > rect.a.x) &&
        (circle.x + circle.r < rect.b.x) &&
        (circle.y - circle.r > rect.a.y) &&
        (circle.y + circle.r < rect.b.y);
}
//判断矩形是否在圆内(不允许相切)
bool IsInRect(const CIRCLE & circle, const RECT & rect) {
    POINT c,d;
    c.x = rect.a.x; c.y = rect.b.y;
    d.x = rect.b.x; d.y = rect.a.y;
    return (Distance( Center(circle) , rect.a ) < circle.r) &&
        (Distance( Center(circle) , rect.b ) < circle.r) &&
        (Distance( Center(circle) , c ) < circle.r) &&
        (Distance( Center(circle) , d ) < circle.r);
}
//判断矩形是否与圆相离(不允许相切)
bool Isoutside(const CIRCLE & circle, const RECT & rect) {
    POINT c,d;
    c.x = rect.a.x; c.y=rect.b.y;
    d.x = rect.b.x; d.y=rect.a.y;
    return ((Distance( Center(circle) , rect.a ) > circle.r) &&
        (Distance( Center(circle) , rect.b ) > circle.r) &&
        (Distance( Center(circle) , c ) > circle.r) &&
        (Distance( Center(circle) , d ) > circle.r) &&
        (rect.a.x > circle.x || circle.x > rect.b.x || rect.a.y > circle.y || circle.y > rect.b.y)) ||
        ((circle.x - circle.r > rect.b.x) ||
        (circle.x + circle.r < rect.a.x) ||
        (circle.y - circle.r > rect.b.y) ||
        (circle.y + circle.r < rect.a.y));
}
//三角形
struct TRIANGLE {
    POINT a, b, c;
    TRIANGLE() {};
    TRIANGLE(const POINT & aa, const POINT & bb, const POINT & cc):
        a(aa), b(bb), c(cc) {}
};
//三角形标准化
TRIANGLE StdTRIANGLE(TYPE len1, TYPE len2, TYPE len3) //把3边长转化成三角形
{
    POINT a, b, c;     //已知边长后将其转化成坐标三角形
    a.x = a.y = 0.0;
    b.x = len1;
    b.y = 0.0;
    c.x = (len2 * len2 - len3 * len3 + len1 * len1)/len1/2.0;
    c.y = Sqrt(len2 * len2 - c.x * c.x);
    TRIANGLE temp(a,b,c);
    return temp;
};
//三角形费马点(即三角形到三顶点之和最小的点)
POINT fermentPONT(TRIANGLE &t) {
    POINT u, v;
    double step = fabs(t.a.x) + fabs(t.a.y) + fabs(t.b.x) + fabs(t.b.y) + fabs(t.c.x) + fabs(t.c.y);
    int i, j, k;
    u.x = (t.a.x + t.b.x + t.c.x)/3;
    u.y = (t.a.y + t.b.y + t.c.y)/3;
    while (step > EPS)
    for(k = 0; k < 10; step /= 2, ++k)
    for(i = -1; i <= 1; ++i)
    for(j = -1; j <= 1; ++j) {
        v.x = u.x + step * i;
        v.y = u.y + step * j;
        if(Distance(u,t.a) + Distance(u,t.b) + Distance(u,t.c) > Distance(v,t.a) + Distance(v,t.b) + Distance(v,t.c))
            u = v;
    }
    return u;
};
//三角形重心(中线交点)
POINT InCenter(const TRIANGLE &t) {
    return POINT((t.a.x + t.b.x + t.c.x)/3, (t.a.y + t.b.y + t.c.y)/3);
}
//三角形外心(中垂线交点)
POINT CcCenter(const TRIANGLE &t) {
    POINT u, v;
    LINE A, B;
    A.a = t.a; A.b = t.b; B.a = t.b; B.b = t.c;
    TYPE A1, B1, C1;
    TYPE A2, B2, C2;
    Coefficient(A, B1, A1, C1);
    Coefficient(B, B2, A2, C2);
    B1 = -B1; B2 = -B2;
    C1 = -((A.a.x + A.b.x) * A1 + (A.a.y + B.a.y) * B1)/2;
    C2 = -((B.a.x + B.b.x) * A2 + (B.a.y + B.b.y) * B2)/2;
    POINT I(0, 0);
    I.x = - (B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1);
    I.y =   (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1);
    return I;
}
//三角形内心(角平分线交点)
POINT incenter(const TRIANGLE &t) {
    LINE u, v;
    TYPE m, n;
    u.a = t.a;
    m = atan2(t.b.y - t.a.y, t.b.x - t.a.x);
    n = atan2(t.c.y - t.a.y, t.c.x - t.a.x);
    u.b.x = u.a.x + cos((m + n)/2);
    u.b.y = u.a.y + sin((m + n)/2);
    v.a = t.b;
    m = atan2(t.a.y - t.b.y, t.a.x - t.b.x);
    n = atan2(t.c.y - t.b.y, t.c.x - t.b.x);
    v.b.x = v.a.x + cos((m + n)/2);
    v.b.y = v.a.y + sin((m + n)/2);
    return Intersection(u, v);
};
//三角形内切圆面积
TYPE InArea(const TRIANGLE &t) {
    TYPE p, a, b, c, s;
    a = Distance(t.a, t.b);
    c = Distance(t.a, t.c);
    b = Distance(t.c, t.b);
    s = (a + b + c)/2;
    p = s * (s - a) * (s - b) * (s - c);
    s = p * PI/s/s;
    return s;
}
//三角形外接圆面积
TYPE OutArea(const TRIANGLE & t) {
    TYPE a,b,c;
    a = (t.a.x - t.b.x) * (t.a.x - t.b.x) + (t.a.y - t.b.y) * (t.a.y - t.b.y);
    b = (t.a.x - t.c.x) * (t.a.x - t.c.x) + (t.a.y - t.c.y) * (t.a.y - t.c.y);
    c = (t.c.x - t.b.x) * (t.c.x - t.b.x) + (t.c.y - t.b.y) * (t.c.y - t.b.y);
    a = PI * sqrt(c/(1-(a+b-c)*(a+b-c)/a/b/4));
    return a;
}
// 多边形 ,逆时针或顺时针给出x,y
struct POLY {
    int n;     //n个点
    TYPE *x, *y;   //x,y为点的指针,首尾必须重合
    POLY(): n(0), x(NULL), y(NULL) {};
    POLY(int nn, const TYPE *xx, const TYPE *yy) {
        n = nn;
        x = new TYPE[n + 1];
        memcpy(x, xx, n*sizeof(TYPE));
        x[n] = xx[0];
        y = new TYPE[n + 1];
        memcpy(y, yy, n*sizeof(TYPE));
        y[n] = yy[0];
    }
};
//多边形顶点
POINT Vertex(const POLY &poly, int idx) {
  // idx %= poly.n;
  return POINT(poly.x[idx], poly.y[idx]);
}
//多边形的边
SEG Edge(const POLY &poly, int idx) {
  // idx %= poly.n;
  return SEG(POINT(poly.x[idx], poly.y[idx]), POINT(poly.x[idx + 1], poly.y[idx + 1]));
}
//多边形的周长
TYPE Perimeter(const POLY & poly) {
    TYPE p = 0.0;
    for (int i = 0; i < poly.n; ++i)
        p += Distance(Vertex(poly, i), Vertex(poly, i + 1));
    return p;
}
//求多边形面积
TYPE Area(const POLY & poly) {
    if (poly.n < 3) return TYPE(0);
    double s = poly.y[0] * (poly.x[poly.n - 1] - poly.x[1]);
    for (int i = 1; i < poly.n; ++i) {
        s += poly.y[i] * (poly.x[i - 1] - poly.x[(i + 1) % poly.n]);
    }
    return s/2;
}
//多边形的重心
POINT InCenter(const POLY & poly) {
    TYPE S,Si,Ax,Ay;
    POINT p;
    Si = (poly.x[poly.n - 1] * poly.y[0] - poly.x[0] * poly.y[poly.n - 1]);
    S = Si;
    Ax = Si * (poly.x[0] + poly.x[poly.n - 1]);
    Ay = Si * (poly.y[0] + poly.y[poly.n - 1]);
    for(int i = 1; i < poly.n; ++i){
        Si = (poly.x[i-1] * poly.y[i] - poly.x[i] * poly.y[i-1]);
        Ax += Si * (poly.x[i-1] + poly.x[i]);
        Ay += Si * (poly.y[i-1] + poly.y[i]);
        S += Si;
    }
    S = S * 3;
    return POINT(Ax/S,Ay/S);
}
//判断点是否在多边形上
bool IsOnPoly(const POLY &poly, const POINT &p) {
    for(int i = 0; i < poly.n; ++i){
        if( IsOnSeg(Edge(poly, i), p) ) return true;
    }
    return false;
}
//判断点是否在多边形内部
bool IsInPoly(const POLY &poly, const POINT &p) {
    SEG L(p, POINT(Infinity, p.y));
    int count = 0;
    for (int i = 0; i < poly.n; i++) {
    SEG S = Edge(poly, i);
    if (IsOnSeg(S, p)) {
        return true; //如果想让 在poly上则返回 true,
    }
    if(!IsEqual(S.a.y, S.b.y)) {
        POINT & q = (S.a.y > S.b.y)?(S.a):(S.b);
        if(IsOnSeg(L, q)) ++count;
        else if(!IsOnSeg(L, S.a) && !IsOnSeg(L, S.b) && IsIntersect(S, L)) {
          ++count;
        }
    }
  }
  return (count % 2 != 0);
}
//判断是否简单多边形
bool IsSimple(const POLY & poly) {
    if(poly.n < 3) return false;
    SEG L1, L2;
    for(int i = 0; i < poly.n - 1; ++i) {
        L1 = Edge(poly, i);
        for(int j = i + 1; j < poly.n; ++j) {
            L2 = Edge(poly, j);
            if(j == i + 1) {
                if(IsOnSeg(L1, L2.b) || IsOnSeg(L2, L1.a)) return false;
            }
            else if(j == poly.n - i - 1) {
              if (IsOnSeg(L1, L2.a) || IsOnSeg(L2, L1.b)) return false;
            }
            else if(IsIntersect(L1, L2)) return false;
        } // for j
    } // for i
    return true;
}
// 点阵的凸包,返回一个多边形(求法一,已测试),不适用于点少于三个的情况
POLY ConvexHull(const POINT * set, int n) {
    POINT * points = new POINT[n];
    memcpy(points, set, n * sizeof(POINT));
    TYPE * X = new TYPE[n];
    TYPE * Y = new TYPE[n];
    int i, j, k = 0, top = 2;
    for(i = 1; i < n; ++i) {
        if ((points[i].y < points[k].y) || ((points[i].y == points[k].y) && (points[i].x < points[k].x)))
            k = i;
    }
    swap(points[0], points[k]);
    for(i = 1; i < n - 1; ++i) {
        k = i;
        for(j = i + 1; j < n; ++j) {
            if((Cross(points[j], points[k], points[0]) > 0) ||
              ((Cross(points[j], points[k], points[0]) == 0) &&
              (Distance(points[0], points[j]) < Distance(points[0], points[k]))))
                k = j;
        }
        swap(points[i], points[k]);
    }
    X[0] = points[0].x; Y[0] = points[0].y;
    X[1] = points[1].x; Y[1] = points[1].y;
    X[2] = points[2].x; Y[2] = points[2].y;
    for(i = 3; i < n; i++) {
        while(Cross(points[i], POINT(X[top], Y[top]),POINT(X[top - 1], Y[top - 1])) >= 0)
            --top;
        ++top;
        X[top] = points[i].x;
        Y[top] = points[i].y;
    }
    delete [] points;
    POLY poly(++top, X, Y);
    delete [] X;
    delete [] Y;
    return poly;
}
// 点阵的凸包,返回一个多边形 (求法二,未测试)
bool cmp(const POINT& aa, const POINT& bb) {
    if(aa.y != bb.y) return aa.y < bb.y;
    else return aa.x < bb.x;
}
POLY ConvexHull2(const POINT * set, int n) {// 不适用于点少于三个的情况
    POINT *a = new POINT[n];
    memcpy(a, set, n * sizeof(POINT));
    sort(a, a + n, cmp);
    TYPE * X = new TYPE[n];
    TYPE * Y = new TYPE[n];
    X[0] = a[0].x;
    Y[0] = a[0].y;
    X[1] = a[1].x;
    Y[1] = a[1].y;
    int i,j;
    for(i = 2, j = 2; i < n; ++i) {
        X[j] = a[i].x;
        Y[j] = a[i].y;
        while(((X[j]-X[j-1]) * (Y[j-1]-Y[j-2]) - (Y[j]-Y[j-1]) * (X[j-1]-X[j-2])) >= 0 && j > 1) {
            X[j-1] = X[j];
            Y[j-1] = Y[j];
            --j;
        }
        ++j;
    }
    X[j] = a[n-2].x;
    Y[j] = a[n-2].y;
    ++j;
    for(i = n - 3; i >= 0; --i) {
        X[j] = a[i].x;
        Y[j] = a[i].y;
        while(((X[j]-X[j-1]) * (Y[j-1]-Y[j-2]) - (Y[j]-Y[j-1]) * (X[j-1]-X[j-2])) >= 0) {
            X[j-1] = X[j];
            Y[j-1] = Y[j];
            --j;
        }
        ++j;
    }
    delete [] a;
    POLY poly(j, X, Y);
    delete [] X;
    delete [] Y;
    return poly;
}

int main() {
    double a,b,c,l1,l2,l3,l4;
    POINT d;
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%lf%lf%lf",&a,&b,&c);
        TRIANGLE t=StdTRIANGLE(a,b,c);

        d=fermentPONT(t);//费马点
        l1=Distance(d,t.a)+Distance(d,t.b)+Distance(d,t.c);

        d=incenter(t);//内心
        l2=Distance(d,t.a)+Distance(d,t.b)+Distance(d,t.c);

        d=InCenter(t);//重心
        l3=Distance(d,t.a)+Distance(d,t.b)+Distance(d,t.c);

        d=CcCenter(t);//外心
        l4=Distance(d,t.a)+Distance(d,t.b)+Distance(d,t.c);

        printf("%.3lf %.3lf %.3lf %.3lf\n",l1,l2,l3,l4);
    }
    return 0;
}

其他2:

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;

struct Tpoint{
    double x, y;
};

inline double length(Tpoint A, Tpoint B){
    double x = A.x - B.x, y = A.y - B.y;
    return sqrt(x * x + y * y);
}

inline double across(Tpoint A, Tpoint B, Tpoint C){
    double x1 = C.x - A.x, x2 = C.x - B.x;
    double y1 = C.y - A.y, y2 = C.y - B.y;
    return x1 * y2 - x2 * y1;
}

double distance(Tpoint A, Tpoint B, Tpoint C){
    return abs(across(A,B,C))/length(B,C);
}
//http://iask.sina.com.cn/b/14697945.html
int main(){
    Tpoint A, B, C, cen;
    while(true){
        cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y;
        /*
        srand(time(0));
        A.x = (double)rand()/rand(); A.y = (double)rand()/rand();
        B.x = (double)rand()/rand(); B.y = (double)rand()/rand();
        C.x = (double)rand()/rand(); C.y = (double)rand()/rand();
        cout<<A.x<<' '<<A.y<<' '<<B.x<<' '<<B.y<<' '<<C.x<<' '<<C.y<<endl;*/
        double a = length(B,C), b = length(C, A), c = length(A, B);
        if(abs(across(A, B, C)) < 0.01) {cout<<"Wrong Input!"<<endl; continue;}
        cen.x = (a * A.x + b * B.x + c * C.x)/(a + b + c);
        cen.y = (a * A.y + b * B.y + c * C.y)/(a + b + c);
        cout<<cen.x<<' '<<cen.y<<endl;
        cout<<distance(cen, A, B)<<' '<<distance(cen, B, C)<<' '<<distance(cen, C, A)<<endl;
        //cout<<abs(across(A, B, C))/(a + b + c)<<endl;
        system("pause");
    }
}



#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;

struct Tpoint{
    double x, y, z;
};

inline double length(Tpoint A, Tpoint B){
    double x = A.x - B.x, y = A.y - B.y, z = A.z - B.z;
    return sqrt(x * x + y * y + z * z);
}

inline double across(Tpoint A, Tpoint B, Tpoint C){
    Tpoint p1, p2;
    p1.x = C.x - A.x; p1.y = C.y - A.y; p1.z = C.z - A.z;
    p2.x = C.x - B.x; p2.y = C.y - B.y; p2.z = C.z - B.z;
    double x = p1.y * p2.z - p1.z * p2.y;
    double y = p1.z * p2.x - p1.x * p2.z;
    double z = p1.x * p2.y - p1.y * p2.x;
    //cout<<x<<' '<<y<<' '<<z<<endl;
    return sqrt(x * x + y * y + z * z);
}

double distance(Tpoint A, Tpoint B, Tpoint C){
    return abs(across(A,B,C))/length(B,C);
}

void neijieyuan(Tpoint A, Tpoint B, Tpoint C){
    Tpoint cen;

    srand(time(0));
    A.x = (double)rand()/rand(); A.y = -(double)rand()/rand();
    B.x = -(double)rand()/rand(); B.y = (double)rand()/rand();
    C.x = -(double)rand()/rand(); C.y = (double)rand()/rand();
    cout<<A.x<<' '<<A.y<<' '<<B.x<<' '<<B.y<<' '<<C.x<<' '<<C.y<<endl;
    double a = length(B,C), b = length(C, A), c = length(A, B);
    //cout<<a<<' '<<b<<' '<<c<<endl;
    if(abs(across(A, B, C)) < 0.01) {cout<<"Wrong Input!"<<endl;return;}
    cen.x = (a * A.x + b * B.x + c * C.x)/(a + b + c);
    cen.y = (a * A.y + b * B.y + c * C.y)/(a + b + c);
    cen.z = (a * A.z + b * B.z + c * C.z)/(a + b + c);
    cout<<cen.x<<' '<<cen.y<<' '<<cen.z<<endl;
    cout<<distance(cen, A, B)<<' '<<distance(cen, B, C)<<' '<<distance(cen, C, A)<<endl;
}

int main(){
    Tpoint A, B, C;
    while(true){
        //cin>>A.x>>A.y>>A.z>>B.x>>B.y>>B.z>>C.x>>C.y>>C.z;
        //cout<<across(A, B, C)<<endl;
        neijieyuan(A, B, C);
        //cout<<abs(across(A, B, C))/(a + b + c)<<endl;
        system("pause");
    }
}



#include <stdio.h>
#include <math.h>

typedef struct TPoint

{

    //平面点

    double x;

    double y;

}TPoint;


typedef struct TTriangle

{

    TPoint t[2];

}TTriangle;

 

typedef struct TCircle

{

    //圆

    double r;

    TPoint centre;

}TCircle;

 

double distance(const TPoint p1, const TPoint p2)

{

    //计算平面上两个点之间的距离

   return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));   

}

 

double triangleArea(const TTriangle t)

{

    //已知三角形三个顶点的坐标,求三角形的面积

    return fabs(t.t[0].x * t.t[1].y + t.t[1].x * t.t[2].y + t.t[2].x * t.t[0].y

      - t.t[1].x * t.t[0].y - t.t[2].x * t.t[1].y - t.t[0].x * t.t[2].y) / 2;  

}

 

TCircle circumcircleOfTriangle(const TTriangle t)

{

    //三角形的外接圆

    TCircle tmp;

    double a, b, c, c1, c2;

    double xA, yA, xB, yB, xC, yC;

    a = distance(t.t[0], t.t[1]);

    b = distance(t.t[1], t.t[2]);

    c = distance(t.t[2], t.t[0]);

    printf("a = %lf b = %lf, c = %lf\n", a, b, c);

    //根据S = a * b * c / R / 4;求半径R

    tmp.r = a * b * c / triangleArea(t) / 4;

   

   xA = t.t[0].x; yA = t.t[0].y;

    xB = t.t[1].x; yB = t.t[1].y;

    xC = t.t[2].x; yC = t.t[2].y;

    c1 = (xA * xA + yA * yA - xB * xB - yB * yB) / 2;

    c2 = (xA * xA + yA * yA - xC * xC - yC * yC) / 2;

   

    tmp.centre.x = (c1 * (yA - yC) - c2 * (yA - yB)) /

         (xA - xB) * (yA - yC) - (xA - xC) * (yA - yB);

    tmp.centre.y = (c1 * (xA - xC) - c2 * (xA - xB)) /

         (yA - yB) * (xA - xC) - (yA - yC) * (xA - xB);

        

    return tmp;    

}

 

TCircle incircleOfTriangle(const TTriangle t)

{

    //三角形的内接圆

    TCircle tmp;

    double a, b, c, angleA, angleB, angleC, p, p2, p3, f1, f2;

    double xA, yA, xB, yB, xC, yC;

    a = distance(t.t[0], t.t[1]);

    b = distance(t.t[1], t.t[2]);

    c = distance(t.t[2], t.t[0]);

   

    printf("a = %lf b = %lf, c = %lf\n", a, b, c);

    tmp.r = 2 * triangleArea(t) / (a + b +c);

    angleA = acos((b * b + c * c - a * a) / (2 * b * c));

    angleB = acos((a * a + c * c - b * b) / (2 * a * c));

    angleC = acos((a * a + b * b - c * c) / (2 * a * b));

    p = sin(angleA / 2);

    p2 = sin(angleB / 2);

    p3 = sin(angleC / 2);

   

    xA = t.t[0].x; yA = t.t[0].y;

    xB = t.t[1].x; yB = t.t[1].y;

    xC = t.t[2].x; yC = t.t[2].y;

   

    f1 = ((tmp.r / p2) * (tmp.r / p2) - (tmp.r / p) * (tmp.r / p) +

         xA * xA - xB * xB + yA * yA - yB * yB) / 2;

    f2 = ((tmp.r / p3) * (tmp.r / p3) - (tmp.r / p) * (tmp.r / p) +

         xA * xA - xC * xC + yA * yA - yC * yC) / 2;

    tmp.centre.x = (f1 * (yA - yC) - f2 * (yA - yB)) /

                   ((xA - xB) * (yA - yC) - (xA - xC) * (yA - yB));

    tmp.centre.y = (f1 * (xA - xC) - f2 * (xA - xB)) /

                   ((yA - yB) * (xA - xC) - (yA - yC) * (xA - xB));

    return tmp;  

}

 

int main()

{

    TTriangle t;

    TCircle circumcircle, incircle;

    while(scanf("%lf%lf%lf%lf%lf%lf",

                    &t.t[0].x, &t.t[0].y, &t.t[1].x, &t.t[1].y,

                             &t.t[2].x, &t.t[2].y) != EOF)

    {

          incircle = incircleOfTriangle(t);

          circumcircle = circumcircleOfTriangle(t);

          printf("%lf %lf \n", incircle.r, circumcircle.r);

          printf("%.3lf\n", incircle.r / circumcircle.r);

    }      

    return 0;

}

  

posted @ 2013-08-19 23:32  Oyking  阅读(384)  评论(0编辑  收藏  举报