hdu 4793 Collision(几何)

582 篇文章 0 订阅
99 篇文章 0 订阅

题目链接:hdu 4793 Collision

代码

#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>

using namespace std;
const double pi = 4 * atan(1);
const double eps = 1e-6;

inline int dcmp(double x) { if (fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; }
inline double torad(double deg) { return deg / 180 * pi; }

struct Point {
    double x, y;
    Point (double x = 0, double y = 0): x(x), y(y) {}
    void read() { scanf("%lf%lf", &x, &y); }

    Point operator + (const Point& p) { return Point(x+p.x, y+p.y); }
    Point operator - (const Point& p) { return Point(x-p.x, y-p.y); }
};

typedef Point Vector;
double getDot (Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
//double getCross (Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
double getLength (Vector a) { return sqrt(getDot(a, a)); }

struct Circle {
    Point o;
    double r;
    Circle() {}
    Circle(Point o, double r): o(o), r(r) {}
};

int getLineCircleIntersection(Point p, Vector v, Circle O, double& t1, double& t2) {
    double a = v.x, b = p.x - O.o.x, c = v.y, d = p.y - O.o.y;
    double e = a*a+c*c, f = 2*(a*b+c*d), g = b*b+d*d-O.r*O.r;
    double delta = f*f - 4*e*g;
    if (dcmp(delta) < 0) return 0;
    if (dcmp(delta) == 0) {
        t1 = t2 = -f / (2*e);
        return 1;
    }

    t1 = (-f - sqrt(delta)) / (2*e);
    t2 = (-f + sqrt(delta)) / (2*e);
    return 2;
}

double Rm, R, r, X, Y, VX, VY;

int main () {
    while (scanf("%lf%lf%lf%lf%lf%lf%lf", &Rm, &R, &r, &X, &Y, &VX, &VY) == 7) {
        double t1, t2, ans = 0;
        Point P = Point(X, Y);
        Vector V = Vector(VX, VY);
        int tmp = getLineCircleIntersection(P, V, Circle(Point(0, 0), Rm+r), t1, t2);
        if (tmp && dcmp(t1) >= 0) {
            double k = t1;
            getLineCircleIntersection(P, V, Circle(Point(0, 0), R+r), t1, t2);
            ans = (2 * k - t1 - max(t1, 0.0));
        } else if (getLineCircleIntersection(P, V, Circle(Point(0, 0), R+r), t1, t2)) {
            t1 = max(t1, 0.0); t2 = max(t2, 0.0);
            ans = (t2-t1);
        }
        printf("%.3lf\n", ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值