HDU5572 An Easy Physics Problem【计算几何】

首先考虑射线A->A+V与圆是否会有交点

如果没有:
判断点B是否在射线A->A+V上。

如果有交点:
求出与A点更近的那个交点pInter
首先判断点B是否在线段(A,pInter)上,如果是则会相遇。
如果不是,继续判断:
求出A点关于直线(O,pInter)对称的点pS,判断点B是否在射线pInter->pS上。

(训练的时候想着不求对称点直接根据角度判断就WA了,现在想想精度真的炸了呀,以后写题尽量都不要用到角度吧,毕竟范围[0,PI]。还有这个代码精度1e-13也WA了,要到1e-8就过了)

代码:


    #include<bits/stdc++.h>
    using namespace std;
    #define sq(x) ((x)*(x))
    const double eps = 1e-8;
    //#define double long double
    int sgn(double x) {
        if (fabs(x) < eps) return 0;
        return x < 0? -1: 1;
    }
    struct point {
        double x, y;
        void output() {
            printf("x%f y%f\n", x, y);
        }
        void input() {
            scanf("%lf%lf", &x, &y);
        }
        point (double x=0., double y=0.): x(x), y(y) {}
        point operator+ (const point &rhs) const {
            return point (x+rhs.x, y+rhs.y);
        }
        point operator- (const point &rhs) const {
            return point (x-rhs.x, y-rhs.y);
        }
        double operator* (const point &rhs) const {
            return x * rhs.x + y * rhs.y;
        }
        double operator^ (const point &rhs) const {
            return x * rhs.y - y * rhs.x;
        }
        point operator* (double k) const {
            return point (x*k, y*k);
        }
        point operator/ (double k) const {
            return point (x/k, y/k);
        }
    };
    point operator* (double a, point b) {
        return point(a*b.x, a*b.y);
    }
    double vlen(point p) {
        return sqrt(p*p);
    }
    point unit(point p) {
        return p*(1.0/vlen(p));
    }
    point lerp(point a, point b, double t) {
        return a * (1-t) + b*t;
    }
    double project(point a, point b) {
        return a * unit(b);
    }
    
    double angleVV(point a, point b) {
        return acos(project(a,b)/vlen(a));
    }
    bool Quadratic(double A, double B, double C, double *t0, double *t1) {
        double discrim=sq(B)-4.f*A*C;
        if (discrim < 0.) return false;
        double rootDiscrim=sqrt(discrim);
        double q;
        if (B<0) q= -.5f * (B - rootDiscrim);
        else     q= -.5f * (B + rootDiscrim);
        *t0 = q/A;
        *t1 = C/q;
        if (*t0 > *t1) swap(*t0, *t1);
        return true;
    }
    bool CL_inter(point o, double r, point a, point b, double *t0, double *t1) {
        point d = b-a;
        double A=sq(d);
        double B=d*(a-o)*2.;
        double C=sq(a-o)-sq(r);
        return Quadratic(A,B,C,t0,t1);
    }
    double slen(point a) {
        return a*a;
    }
    bool sameLine(point a, point b) {
        return !sgn(a*b - vlen(a)*vlen(b));
    }
    bool PointOnS(point p, point a, point b) {
        return !sgn((p-a)^(b-a)) && sgn((p-a)*(p-b))<=0;
    }
    bool twoside(point a, point b, point c) {
        double pl = a^b, pr = a^c;
        return sgn(pl)*sgn(pr)<0 || (!sgn(pl) && !sgn(pr));
    }
    point ABClineInter(double a1, double b1, double c1, double a2, double b2, double c2) {
        return point((c1*b2-c2*b1)/(a2*b1-a1*b2),(c1*a2-c2*a1)/(a1*b2-a2*b1));
    }
    point Symmetry(point p, point a, point b) {
        double A = a.y-b.y, B = b.x-a.x, C = -A*a.x-B*a.y;
        double a1 = A, b1 = B, c1 = A*p.x+B*p.y+2.*C;
        double a2 = -B, b2 = A, c2 = B*p.x-A*p.y;
        return ABClineInter(a1, b1, c1, a2, b2, c2);
    }
    
    int T, ks;
    point a, b, o, v;
    double r;
    int main(){
        scanf("%d",&T);
        while (T--) {
            o.input(); scanf("%lf", &r);
            a.input(); v.input(); b.input();
            printf("Case #%d: ", ++ks);
            double t0,t1;
            if (!CL_inter(o,r,a,a+v,&t0,&t1) || !sgn(t1-t0)) {
                if (sameLine(v,b-a)) {
                    puts("Yes");
                } else puts("No"); continue;
            }
            point pInter = lerp(a,a+v,t0), pInter_ = lerp(a,a+v,t1);
            if (vlen(a-pInter) > vlen(a-pInter_)) swap(pInter, pInter_);
            if (!sameLine(v,pInter-a)) {
                if (sameLine(v,b-a)) {
                    puts("Yes");
                } else puts("No"); continue;
            }
            if (PointOnS(b, a, pInter)) {
                puts("Yes"); continue;
            }
            point pS = Symmetry(a, pInter, o);
            if (sameLine(b-pInter,pS-pInter)) {
                puts("Yes");
            } else puts("No");
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值