An Easy Physics Problem

来源:互联网 发布:oracle 数据库迁移 编辑:程序博客网 时间:2024/06/08 01:32

An Easy Physics Problem

这里写图片描述
.
.
题意:平面上一个点与圆,点延一个方向前进,问能否达到另外一个点。
.
.
解法:分两种,1是相撞,2是相离或相切。对于第二种直接求解就好了,而第一种注意一下精度,考虑点出现在相撞前的地方等就好了。
.
.
队友代码

#include <cstdio>#include <iostream>#include <cmath>#include <vector>using namespace std;const double eps=1e-6;typedef long long LL;int dcmp(double x) {    if (fabs(x)<eps) return 0;    else if (x<0) return -1;    else return 1;}struct Point {    double x, y;    Point() {}    Point(double x, double y): x(x), y(y) {}    void read() {scanf("%lf%lf", &x, &y);}    Point operator+ (const Point& a) {        return Point(x+a.x, y+a.y);    }    Point operator- (const Point& a) {        return Point(x-a.x, y-a.y);    }} a, v, b;Point operator*(double t, Point a) {    return Point(t*a.x, t*a.y);}struct Line {    Point p, v;    Line() {}    Line(Point p, Point v): p(p.x, p.y), v(v.x, v.y) {}    Point point(double t) {        return p+(t*v);    }};struct Circle {    Point c;    double r;    void read() {c.read(); scanf("%lf", &r);}} cc;inline double sqr(double x) {return x*x;}int getLineCircleIntersection(Line L, Circle C, Point& sol) {    double t;    double a=L.v.x, b=L.p.x-C.c.x, c=L.v.y, d=L.p.y-C.c.y;    double e=sqr(a)+sqr(c), f=2*(a*b+c*d), g=sqr(b)+sqr(d)-sqr(C.r);    double delta=f*f-4*e*g;    if (dcmp(delta)<=0) return 0;    else {        t=(-f-sqrt(delta))/(2*e);        if (dcmp(t)>0) {            sol=L.point(t);            return 1;        }        else return 0;    }}bool det(Point a, Point b) {    return fabs(a.x*b.y-a.y*b.x)<eps;}bool SameLine(Point v, Point p) {    double a=v.x, b=v.y, c=p.x, d=p.y;        int aa=dcmp(a), bb=dcmp(b);        int cc=dcmp(c), dd=dcmp(d);        if (aa*cc>=0&&bb*dd>=0&&det(v, p)) return true;        else return false;}double dist(Point a, Point b) {    return hypot(a.x-b.x, a.y-b.y);}double Dot(Point a, Point b) {    return a.x*b.x+a.y*b.y;}Point GetLineProjection(Point P, Point A, Point B) {    Point v=B-A;    return A+(Dot(v, P-A)/Dot(v, v))*v;}int main() {    // freopen("untitled.in", "r", stdin);    int T, kase=0; cin >> T;    while (T--) {        printf("Case #%d: ", ++kase);        cc.read(); a.read(); v.read(); b.read();        Line l(a, v);        Point i;        bool flag=getLineCircleIntersection(l, cc, i);        if (flag) {            if (SameLine(v, b-a)&&dist(a, b)<dist(a, i)+eps) puts("Yes");            else {                Point bb=GetLineProjection(b, i, cc.c);                b=2*bb-b;                if (SameLine(Point(-v.x, -v.y), b-i)) puts("Yes");                else puts("No");            }        }        else {            if (SameLine(v, b-a)) puts("Yes");            else puts("No");        }    }}
0 0
原创粉丝点击