计算几何
————————————————————-.
hdu 5572
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <string>
#include <set>
using namespace std;
#define LL __int64
const int MOD = 1e9+7;
const double eps = 1e-8;
struct point
{
double x,y,r;
} a;
double multi(point p1,point p2,point p0)
{
return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
point jian (point &a,point &b)
{
point ttt;
ttt.x=b.x-a.x;
ttt.y=b.y-a.y;
return ttt;
}
double mod(point a)
{
return a.x*a.x+a.y*a.y;
}
double dis(point a,point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
point GetPoint(int cx,int cy,int r,double k,double b)
{
//列方程
/*
(1 + k^2)*x^2 - x*(2*cx -2*k*(b -cy) ) + cx*cx + ( b - cy)*(b - cy) - r*r = 0
*/
double x1,y1,x2,y2;
double c = cx*cx + (b - cy)*(b- cy) -r*r;
double aa = (1 + k*k);
double b1 = (2*cx - 2*k*(b - cy));
//得到下面的简化方程
// a*x^2 - b1*x + c = 0;
double tmp = sqrt(b1*b1 - 4*aa*c);
x1 = ( b1 + tmp )/(2*aa);
y1 = k*x1 + b;
x2 = ( b1 - tmp)/(2*aa);
y2 = k*x2 + b;
//判断求出的点是否在圆上
double res1 = (x1 -a.x)*(x1 -a.x) + (y1 - a.y)*(y1 -a.y);
double res2 = (x2 -a.x)*(x2 -a.x) + (y2 - a.y)*(y2 -a.y);
point p;
if( res1<res2) //我这里 r = 50,res = 2500.632,还是比较准确的
{
p.x = x1;
p.y = y1;
}
else
{
p.x = x2;
p.y = y2;
}
return p;
}
point c,b,aa;
bool judge(/*Circle c,point a,point b*/) // 判断圆与直线相交
{
point ob=jian(c,b),oa=jian(c,a);
double cosx = (a.x*b.x+a.y*b.y)/sqrt(mod(oa)*mod(ob));
double s = fabs(multi(a,b,c)),AB = dis(a,b);
if(cosx>=0&&c.r*c.r<dis(c,a)&&c.r*c.r<dis(b,a))
return true;
if(cosx<=0&&s*s>=c.r*c.r*AB)//直线距离
return true;
return false;
}
int main()
{
int t,p=0,flag=0;
scanf("%d",&t);
while(t--)
{
flag=0;
scanf("%lf%lf%lf",&c.x,&c.y,&c.r);
scanf("%lf%lf%lf%lf",&a.x,&a.y,&aa.x,&aa.y);
scanf("%lf%lf",&b.x,&b.y);
if( (b.x-a.x)*aa.y == (b.y-a.y)*aa.x ) //判断 A 能不能直线走到 B
{
//sudu fangxiang 判断之间you没有球被弹开
if(((b.y-a.y)*aa.y>=0&&(b.x-a.x)*aa.x>=0) && judge())
{
flag=1;
}
}
else
{
//直线方程 y=kx+b
double k=aa.y/aa.x,C=a.y-a.x*aa.y/aa.x;
point pj = GetPoint(c.x,c.y,c.r,k,C);
point pjo= jian(pj,c),pja=jian(pj,a),pjb=jian(pj,b);
//printf("%.4lf %.4lf\n", pj.x, pj.y);
double sinx1 = multi(a,c,pj)/sqrt(mod(pjo)*mod(pja));
double sinx2 = multi(b,c,pj)/sqrt(mod(pjo)*mod(pjb));
sinx1=fabs(sinx1);
sinx2=fabs(sinx2);
// printf("%.4lf %.4lf\n",sinx1,sinx2);
if( sinx1 <= sinx2+eps && sinx1 >= sinx2-eps )
if( pja.x * aa.x <= 0 && pja.x * aa.x <= 0 )
flag=1;
}
if(flag)
printf("Case #%d: Yes\n",++p);
else
printf("Case #%d: No\n",++p);
}
return 0;
}
/*
// YES
0 0 1
3 1 -2 -1
3 -1
0 0 1
3 1 -2 -1
5 -2
0 0 1
-1 2 1 -1
1 2
// NO
0 0 1
2 2 0 1
-1 -1
*/