1. 程式人生 > >51nod 1298 圓與三角形

51nod 1298 圓與三角形

給出圓的圓心和半徑,以及三角形的三個頂點,問圓同三角形是否相交。相交輸出"Yes",否則輸出"No"。(三角形的面積大於0)。      

輸入

第1行:一個數T,表示輸入的測試數量(1 <= T <= 10000),之後每4行用來描述一組測試資料。
4-1:三個數,前兩個數為圓心的座標xc, yc,第3個數為圓的半徑R。(-3000 <= xc, yc <= 3000, 1 <= R <= 3000)
4-2:2個數,三角形第1個點的座標。
4-3:2個數,三角形第2個點的座標。
4-4:2個數,三角形第3個點的座標。(-3000 <= xi, yi <= 3000)

輸出

共T行,對於每組輸入資料,相交輸出"Yes",否則輸出"No"。

輸入樣例

2
0 0 10
10 0
15 0
15 5
0 0 10
0 0
5 0
5 5

輸出樣例

Yes
No

題意是求圓與三角形是否相交,即是否有交點,實際上就是求圓心到三邊的距離,不過 要注意這裡的邊是線段,可不是求到直線的距離,如果三個點都在圓內或者圓心到三條邊的距離都大於半徑,那麼就是不相交,其他的情況相交,
點與點之間的距離很好求,點到線的距離可以藉助海倫公式,海倫公式求出點與邊兩點組成三角形的面積,而面積又等於點到直線的距離*邊長/2,以此能求出點到直線距離,還要另外分點到直線距離不等於點到線段距離的情況。
還有精度問題,全程用浮點數,判斷相等的情況要用到精度,不然可能出錯。
程式碼:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define MAX 101
#define eps 1e-6
using namespace std;
typedef pair<double,double> pa;
int t;
double r;
pa cir,a,b,c;
double ptop(pa x,pa y) {///點到點
    return
sqrt((x.first - y.first) * (x.first - y.first) + (x.second - y.second) * (x.second - y.second)); } double ptol(pa p,pa la,pa lb) {///點到線 double x = ptop(p,la); double y = ptop(p,lb); double z = ptop(lb,la); if(x * x >= y * y + z * z) return y;///不能用點到直線 if(y * y >= x * x + z * z) return x;///不能用點到直線 double hc = (x + y + z) / 2; return sqrt(hc * (hc - x) * (hc - y) * (hc - z)) * 2 / z;///點到直線 } bool check(pa p,double rr,pa x,pa y,pa z) { if(ptop(cir,x) - rr < -eps && ptop(cir,y) - rr < -eps && ptop(cir,z) - rr < -eps || ptol(p,x,y) - rr > eps && ptol(p,z,y) - rr > eps && ptol(p,x,z) - rr > eps) return false; return true; } int main() { scanf("%d",&t); while(t --) { scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf",&cir.first,&cir.second,&r,&a.first,&a.second,&b.first,&b.second,&c.first,&c.second); if(check(cir,r,a,b,c)) puts("Yes"); else puts("No"); } }