题目链接: http://codeforces.com/problemset/gymProblem/100942/A
------------------------------------------------------------------------------------
我们可以把给定的角看成圆周角 从而算出圆心角
然后每条边以及一个角可以确定两个可能的圆
如果$M1 M2$确定出来的两个圆与$M2 M3$确定出来的两个圆圆心不同的话
再判断这两个圆的交点即为答案 另外每次两个交点中一定有一个点是$M2$
如果圆心相同就是四点共圆了
此题卡精度比较严重 不要随意地使用三角函数库函数 尤其是$atan2$这类的
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 const double eps = 1e-6, inf = 1e8, pi = acos(-1.0); 7 const double eps2 = 1e-2; 8 struct point 9 { 10 double x, y; 11 point(){} 12 point(double _x,double _y) 13 { 14 x = _x; 15 y = _y; 16 } 17 point operator - (const point &p) const 18 { 19 return point(x - p.x, y - p.y); 20 } 21 point operator + (const point &p) const 22 { 23 return point(x + p.x, y + p.y); 24 } 25 double operator * (const point &p) const 26 { 27 return x * p.y - y * p.x; 28 } 29 double operator / (const point &p) const 30 { 31 return x * p.x + y * p.y; 32 } 33 }a[3]; 34 struct circle 35 { 36 double x, y, r; 37 }c[4]; 38 int t, cnt; 39 double ang1, ang2; 40 bool flag; 41 double getdist2(const point &aa) 42 { 43 return (aa.x * aa.x + aa.y * aa.y); 44 } 45 double mycos(double B, double C, double A) 46 { 47 return (B * B + C * C - A * A) / (B * C * 2); 48 } 49 double mycos2(const point &aa, const point &bb, const point &cc) 50 { 51 double C2 = getdist2(aa - bb), A2 = getdist2(bb - cc), B2 = getdist2(cc - aa); 52 return (B2 + C2 - A2) / (sqrt(B2 * C2) * 2); 53 } 54 point rotate(const point &p, double cost, double sint) 55 { 56 double x = p.x, y = p.y; 57 return point(x * cost - y * sint, x * sint + y * cost); 58 } 59 void getcircle(const point &aa, const point &bb, double ang) 60 { 61 ang = (ang < pi * 0.5 ? ang: pi - ang); 62 point mid; 63 mid.x = (aa.x + bb.x) * 0.5; 64 mid.y = (aa.y + bb.y) * 0.5; 65 if(ang + eps < pi * 0.5) 66 { 67 double tan1 = tan(ang); 68 c[cnt].x = mid.x + (aa.y - mid.y) / tan1; 69 c[cnt].y = mid.y - (aa.x - mid.x) / tan1; 70 c[cnt].r = sqrt(getdist2(mid - point(c[cnt].x, c[cnt].y)) + 71 getdist2(mid - aa)); 72 ++cnt; 73 c[cnt].x = mid.x - (aa.y - mid.y) / tan1; 74 c[cnt].y = mid.y + (aa.x - mid.x) / tan1; 75 c[cnt].r = c[cnt - 1].r; 76 ++cnt; 77 } 78 else 79 { 80 c[cnt].x = mid.x; 81 c[cnt].y = mid.y; 82 c[cnt].r = sqrt(getdist2(mid - aa)); 83 ++cnt; 84 c[cnt] = c[cnt - 1]; 85 ++cnt; 86 } 87 } 88 bool checkpoint(const point &re) 89 { 90 for(int i = 0; i < 3; ++i) 91 if(getdist2(a[i] -re) < eps) 92 return 0; 93 double tmp = acos(mycos2(re, a[0], a[1])) - ang1 - pi; 94 while(tmp < -eps2) 95 tmp += pi; 96 if(abs(tmp) > eps2) 97 return 0; 98 tmp = acos(mycos2(re, a[1], a[2])) - ang2 - pi; 99 while(tmp < -eps2) 100 tmp += pi; 101 return abs(tmp) < eps2; 102 } 103 void getpoint2(const circle &c1) 104 { 105 double dab = sqrt(getdist2(point(a[0].x - a[1].x, a[0].y - a[1].y))); 106 double ang = acos(dab / (c1.r * 2)); 107 ang -= ang1; 108 double len = c1.r * 2 * cos(ang); 109 double cang1 = cos(ang1); 110 double l2 = len * cang1; 111 point d, re; 112 d.x = a[1].x + (a[0].x - a[1].x) * l2 / dab; 113 d.y = a[1].y + (a[0].y - a[1].y) * l2 / dab; 114 double l3 = len * sqrt(1 - cang1 * cang1); 115 re.x = d.x + (a[0].y - a[1].y) * l3 / dab; 116 re.y = d.y - (a[0].x - a[1].x) * l3 / dab; 117 if(checkpoint(re)) 118 { 119 printf("%.8f %.8f ", re.x, re.y); 120 flag = 1; 121 return; 122 } 123 re.x = d.x - (a[0].y - a[1].y) * l3 / dab; 124 re.y = d.y + (a[0].x - a[1].x) * l3 / dab; 125 if(checkpoint(re)) 126 { 127 printf("%.8f %.8f ", re.x, re.y); 128 flag = 1; 129 return; 130 } 131 } 132 void getpoint(circle c1, circle c2) 133 { 134 double dab = sqrt(getdist2(point(c1.x, c1.y) - point(c2.x, c2.y))); 135 if(dab < eps) 136 { 137 getpoint2(c1); 138 return; 139 } 140 if(c1.r > c2.r) 141 swap(c1, c2); 142 double cost = mycos(c1.r, dab, c2.r); 143 double sint = sqrt(1 - cost * cost); 144 point re = rotate(point(c2.x, c2.y) - point(c1.x, c1.y), cost, sint); 145 re.x = c1.x + re.x * (c1.r / dab); 146 re.y = c1.y + re.y * (c1.r / dab); 147 if(getdist2(a[1] - re) < eps) 148 { 149 re = rotate(point(c2.x, c2.y) - point(c1.x, c1.y), cost, -sint); 150 re.x = c1.x + re.x * (c1.r / dab); 151 re.y = c1.y + re.y * (c1.r / dab); 152 } 153 if(!checkpoint(re)) 154 return; 155 flag = 1; 156 printf("%.8f %.8f ", re.x, re.y); 157 } 158 int main() 159 { 160 scanf("%d", &t); 161 while(t--) 162 { 163 for(int i = 0; i < 3; ++i) 164 scanf("%lf%lf", &a[i].x, &a[i].y); 165 scanf("%lf%lf", &ang1, &ang2); 166 ang1 = ang1 * pi / 180; 167 ang2 = ang2 * pi / 180; 168 cnt = 0; 169 getcircle(a[0], a[1], ang1); 170 getcircle(a[1], a[2], ang2); 171 flag = 0; 172 getpoint(c[0], c[2]); 173 if(!flag) 174 getpoint(c[0], c[3]); 175 if(!flag) 176 getpoint(c[1], c[2]); 177 if(!flag) 178 getpoint(c[1], c[3]); 179 } 180 return 0; 181 }