51nod1298

来源:互联网 发布:单片机呼吸灯原理 编辑:程序博客网 时间:2024/05/17 04:31

判断线段与园是否有交。。其实很简单啊。。。就是先看两点是都在园内还是园外,然后求一个点到线段最短距离就好了

点到线段最短距离怎么弄?用向量比比划划就好了。。。

教程:http://blog.csdn.net/qq_21120027/article/details/50525835

#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;struct point{double x, y;point(double xx, double yy) :x(xx), y(yy){}point(){}};double operator*(point a, point b){return a.x*b.x + a.y*b.y;}double dot(point a, point b){return a.x*b.y - a.y*b.x;}point operator-(point a, point b){return point(a.x - b.x, a.y - b.y);}point operator+(point a, point b){return point(a.x + b.x, a.y + b.y);}double getdis(point a, point b){ double len=sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)); if (len < 1e-8) return 0; else return len;}double getmin(point a, point b, point c){double s = fabs(dot(c-a, c-b));return s / getdis(a, b);}double  judge(point a, point b, point c){if (!getdis(a, b))return getdis(a, c);double cc = ((b - a)*(c - a)); double kk = getdis(a, b);double r = ((b-a)*(c-a)) /kk;///这求得是向量a->c到向量a->b上的投影r = r /kk;//求得是向量a->c与向量a->b投影的比值符号代表方向if (r < 0)return getdis(a, c);if (r >= 1)return getdis(b, c);return getmin(a, b, c);}double  g(double a, double b){if (fabs(a - b) < 1e-8)return 0;elsereturn a -b;}int main(){int t;scanf("%d", &t);while (t--){point circle; double r;scanf("%lf%lf%lf", &circle.x, &circle.y, &r);point a, b, c;scanf("%lf%lf", &a.x, &a.y);scanf("%lf%lf", &b.x, &b.y);scanf("%lf%lf", &c.x, &c.y);double l[5]; l[1] = getdis(a, circle);  l[2] = getdis(b, circle);  l[3]= getdis(c, circle); if (g(l[1], r)<0 && g(l[2], r)<0 && g(l[3], r)<0) printf("No\n"); else { double rl[5]; rl[1] = judge(a, b, circle); rl[2] = judge(b, c, circle); rl[3] = judge(c, a, circle); bool judge = false; for (int i = 1; i <= 3; i++) if (g(rl[i], r)<=0) judge = true; if (judge) printf("Yes\n"); else printf("No\n"); }}return 0;}