sgu283:Mechanics(计算几何)

来源:互联网 发布:轰炸手机号码软件 编辑:程序博客网 时间:2024/06/01 19:36

题目大意:
      给你平面上两个圆(x1,y1),(x2,y2),以及它们的质量m1,m2和速度v1,v2
      碰撞过程中不考虑能量损失。
      求出在时刻t的两圆坐标和速度。

分析:
      首先我们很容易解个方程求出碰撞时间。问题就是如何计算碰撞后的速度。
      设碰撞时两圆圆心为A,B,将v1,v2根据AB正交分解为垂直的law1,law2,和共线的x,y,即v1=law1+x,v2=law2+y。那么根据动量守恒和能量守恒,碰撞后只有x,y会改变,我们可以列出两个方程:
                      {m1x+m2y=m1x+m2ym1v21+m2v22=m1(law21+x2)+m2(law22+y2)
      解出来就是x=((m1m21)x+2y)/(1+m1m2),y=x+xy
      然后就没有然后了...

AC code:

#include <cstdio>#include <cmath>#include <algorithm>#define sqr(x) ((x)*(x))typedef double DB;using namespace std;const DB eps = 1e-9;struct pot{    DB x, y;    pot() {x = y = 0;}    pot(DB _x, DB _y):x(_x),y(_y){}    void read() {scanf("%lf%lf", &x, &y);}    void print() {printf("%.3lf %.3lf", x, y);}    friend pot operator + (const pot &a, const pot &b) {return pot(a.x+b.x, a.y+b.y);}    friend pot operator - (const pot &a, const pot &b) {return pot(a.x-b.x, a.y-b.y);}    friend pot operator * (const pot &a, DB k) {return pot(a.x*k, a.y*k);}    friend pot operator / (const pot &a, DB k) {return pot(a.x/k, a.y/k);}    friend DB operator * (const pot &a, const pot &b) {return a.x*b.x+a.y*b.y;}    friend DB operator ^ (const pot &a, const pot &b) {return a.x*b.y-a.y*b.x;}    DB size() {return sqrt(sqr(x)+sqr(y));}}p1, v1, p2, v2;DB r1, r2, m1, m2, t;DB bump_t;int sign(DB x){    if(x < -eps) return -1;    else return x > eps;}bool bump(){    DB a, b, c, d, e;    DB A, B, C;    a = p1.x-p2.x, b = v1.x-v2.x;    c = p1.y-p2.y, d = v1.y-v2.y;e = r1+r2;    A = sqr(b)+sqr(d), B = 2*(a*b+c*d), C = sqr(a)+sqr(c)-sqr(e);    if(sign(A) == 0)    {        if(sign(-C/B) < 0) return false;        else         {            bump_t = -C/B;            return true;        }    }     else if(sign(sqr(B)-4*A*C) <= 0) return false;    else    {        DB u, v;        u = -B/(2*A), v = sqrt(sqr(B)-4*A*C)/(2*A);        if(sign(u+v) < 0) return false;        else if(sign(u-v) < 0) bump_t = u+v;        else bump_t = u-v;        return true;    }}void solve2(DB t){    p1 = p1+v1*t;    p2 = p2+v2*t;    p1.print(), putchar(' '), v1.print(), puts("");    p2.print(), putchar(' '), v2.print(), puts("");}void solve1(DB t){    pot A, B, par, x, y, _x, _y;    pot law1, law2, _v1, _v2;    A = p1+v1*bump_t, B = p2+v2*bump_t, par = B-A;    x = par*(v1*par/sqr(par.size())), y = par*(v2*par/sqr(par.size()));    law1 = v1-x, law2 = v2-y;    _x = (x*(m1/m2-1)+y*2)/(1+m1/m2), _y = x+_x-y;    _v1 = law1+_x, _v2 = law2+_y;    p1 = A, p2 = B, v1 = _v1, v2 = _v2;    solve2(t-bump_t);}int main(){    #ifndef ONLINE_JUDGE    freopen("input.txt", "r", stdin);    freopen("output.txt", "w", stdout);    #endif    p1.read(), v1.read(), scanf("%lf%lf", &r1, &m1);    p2.read(), v2.read(), scanf("%lf%lf", &r2, &m2);    scanf("%lf", &t);    if(bump())    {        if(sign(t-bump_t) > 0)            solve1(t);        else solve2(t);    }    else solve2(t);    #ifndef ONLINE_JUDGE    fclose(stdin);    fclose(stdout);    #endif    return 0;}
0 0
原创粉丝点击