这是一堆 wrong 懵逼的题目

计算几何

————————————————————-.

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


*/





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值