⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 billmove.c

📁 这是一个相当棒的Linux下的台球游戏
💻 C
📖 第 1 页 / 共 3 页
字号:
    move_log.event[move_log.eventnr].ballnr=nr;    move_log.event[move_log.eventnr].ballnr2=nr2;    if(event==BALL_ball){        move_log.event[move_log.eventnr].pos =BM_get_ball_by_nr(nr,pballs)->r;        move_log.event[move_log.eventnr].pos2=BM_get_ball_by_nr(nr2,pballs)->r;        move_log.event[move_log.eventnr].v   =BM_get_ball_by_nr(nr,pballs)->v;        move_log.event[move_log.eventnr].v2  =BM_get_ball_by_nr(nr2,pballs)->v;        move_log.event[move_log.eventnr].w   =BM_get_ball_by_nr(nr,pballs)->w;        move_log.event[move_log.eventnr].w2  =BM_get_ball_by_nr(nr2,pballs)->w;    }else if(event==BALL_wall){        move_log.event[move_log.eventnr].pos2=BM_get_ball_by_nr(nr2,pballs)->r;        move_log.event[move_log.eventnr].v2  =BM_get_ball_by_nr(nr2,pballs)->v;        move_log.event[move_log.eventnr].w2  =BM_get_ball_by_nr(nr2,pballs)->w;    }else if(event==BALL_out){        move_log.event[move_log.eventnr].pos =BM_get_ball_by_nr(nr,pballs)->r;    }    move_log.event[move_log.eventnr].timestep_nr = move_log.timestep_nr;    move_log.event[move_log.eventnr].timeoffs    = timeoffs;    move_log.eventnr++;}int my_rand(nr){    return rand()%nr;}static void calc_rand_table(int * rnd, int nr){    int i,i1,dummy;    for(i=0;i<nr;i++){        rnd[i]=i;    }    for(i=0;i<nr;i++){        i1    = my_rand(nr);        dummy = rnd[i];        rnd[i] = rnd[i1];        rnd[i1] = dummy;    }}BMfloat plane_dist(VMvect r, VMvect rp, VMvect n){ return( vec_mul(vec_diff(r,rp),n) ); }#ifdef USE_ADV_BORDERint inrange_advborder( BallType *b, BorderType *w ){    VMvect r,dr,dr1,dr2,dr3,n;    BMfloat d,dra;    if       (w->pnr==3){        dr1 = vec_diff(w->r2,w->r1);        dr2 = vec_diff(w->r3,w->r2);        dr3 = vec_diff(w->r1,w->r3);        n   = vec_unit(vec_cross(dr1,dr2));        return( plane_dist( b->r, w->r1, vec_unit(vec_cross(n,dr1)) ) >= 0.0 &&                plane_dist( b->r, w->r2, vec_unit(vec_cross(n,dr2)) ) >= 0.0 &&                plane_dist( b->r, w->r3, vec_unit(vec_cross(n,dr3)) ) >= 0.0 );    } else if(w->pnr==2){        r   = vec_diff(b->r,w->r1);        dr  = vec_diff(w->r2,w->r1);        dra = vec_abs(dr);        d   = vec_mul(r,dr)/dra;        return (d>=0.0 && d<dra);    } else if(w->pnr==1){        return 1;    }    return 1;}BMfloat ball_advborder_dist( BallType *b, BorderType *w ){    VMvect r,dr;    if(inrange_advborder(b,w)){        if       (w->pnr==3){            return vec_mul(vec_diff(b->r,w->r1),w->n);        } else if(w->pnr==2){            r=vec_diff(b->r,w->r1);            dr=vec_diff(w->r2,w->r1);            return vec_abs(vec_diff(r,vec_proj(r,dr)));        } else if(w->pnr==1){            return vec_abs(vec_diff(b->r,w->r1));        }    } else {        return -1.0E20;    }    return -1.0E20;}#endif#ifdef USE_ADV_BORDERstatic BMfloat calc_wall_collision_time( BallType * ball, BorderType * wall ){    BMfloat h, vn, rval, ph, q, t1,t2;    myvec   dr, r, v;    rval=0.0;    if       (wall->pnr==3){        dr = vec_diff( ball->r, wall->r1 );        h  = vec_mul( dr, wall->n ) - ball->d/2.0;        vn = vec_mul( ball->v, wall->n );        rval = -h/vn;    } else if(wall->pnr==2){        /* del all comps par to cylinder */        dr = vec_diff( wall->r2 ,wall->r1 );        r = vec_diff( ball->r, wall->r1 );        r = vec_diff( r, vec_proj(r,dr) );        v = ball->v;        v = vec_diff( v, vec_proj(v,dr) );        ph = vec_mul(v,r)/vec_abssq(v);        q  = (vec_abssq(r) - ball->d*ball->d/4.0)/vec_abssq(v);        if(ph*ph>q){           t1 = -ph+sqrt(ph*ph-q);           t2 = -ph-sqrt(ph*ph-q);        } else {           t1 = SQRTM1;           t2 = SQRTM1;        }        /* solve |r+vt|=d/2 */        rval = (t1<t2)?t1:t2;    } else if(wall->pnr==1){        r = vec_diff( ball->r, wall->r1 );        ph = vec_mul(ball->v,r)/vec_abssq(ball->v);        q  = (vec_abssq(r) - ball->d*ball->d/4.0)/vec_abssq(v);        if(ph*ph>q){	        t1 = -ph+sqrt(ph*ph-q);   	     t2 = -ph-sqrt(ph*ph-q);        } else {           t1 = SQRTM1;           t2 = SQRTM1;        }        rval = (t1<t2)?t1:t2;    }    if( !inrange_advborder( ball, wall ) ){        rval=1E20;    }    return(rval);}#elsestatic BMfloat calc_wall_collision_time( BallType * ball, BorderType * wall ){    BMfloat h, vn;    myvec   dr;    dr = vec_diff( ball->r, wall->r );    h  = vec_mul( dr, wall->n ) - ball->d/2.0;    vn = vec_mul( ball->v, wall->n );    return(-h/vn);}#endifstatic BMfloat calc_ball_collision_time( BallType * b1, BallType * b2 ){    BMfloat p, q, vs, rs, t1, t2, ds;    myvec   dv, dr;    dv = vec_diff( b1->v, b2->v );    dr = vec_diff( b1->r, b2->r );    vs = dv.x*dv.x + dv.y*dv.y + dv.z*dv.z ;    rs = dr.x*dr.x + dr.y*dr.y + dr.z*dr.z ;    ds = (b1->d+b2->d)/2.0;    ds *= ds;    p  = ( dv.x*dr.x + dv.y*dr.y + dv.z*dr.z )/vs;    q  = (rs-ds)/vs;    q  = (p*p>q)?sqrt(p*p-q):SQRTM1;    t1 = -p + q;    t2 = -p - q;    return( (t1<t2)?t1:t2 );}#ifdef USE_ADV_BORDERmyvec perimeter_speed_wall( BallType * ball, BorderType * wall )/* only for 3-point wall */{    return(            vec_cross(                      ball->w,                      vec_scale(wall->n,-ball->d/2.0)                     )           );}myvec perimeter_speed_normal( BallType * ball, myvec normal ){    return(            vec_cross(                      ball->w,                      vec_scale(normal,-ball->d/2.0)                     )           );}#if 0  /* new ball-wall ia */static void ball_wall_interaction( BallType * ball, BorderType * wall ){//#define CUSHION_LOSS         0.2     /* const loss of energy by cushion *///#define CUSHION_LOSS_O1      0.07    /* linear (in speed) loss of energy by cushion *///#define MU_BANDE             0.1     /* friction const between cusion an ball */#define CUSHION_LOSS_O0      (wall->loss0)       /* const loss of energy by cushion */#define CUSHION_MAX_LOSS     (wall->loss_max)    /* const loss of energy by cushion */#define CUSHION_LOSS_WSPEED  (wall->loss_wspeed) /* prop. halbwertsgeschwindigkeit */#define MU_BANDE             (wall->mu)          /* friction const between cusion an ball */    myvec dv, dv_tot, dw, dw_tot, dr, n;    dv_tot  = vec_xyz(0.0,0.0,0.0);    dw_tot  = vec_xyz(0.0,0.0,0.0);    if       (wall->pnr==3){        myvec vp, vn;        double loss;        vn      = vec_proj(ball->v, wall->n);        vp      = vec_diff(ball->v, vn);        //        dv      = vec_scale(wall->n,vec_mul(wall->n,ball->v)*2.0);        /* normal component */        loss = CUSHION_LOSS_O0+               (CUSHION_MAX_LOSS-CUSHION_LOSS_O0)*(1.0-exp(-vec_abs(vn)/CUSHION_LOSS_WSPEED));        //        loss    = CUSHION_LOSS;        dv      = vec_scale( vn, -(1.0+sqrt(1.0-loss)) );        if( !options_jump_shots ) dv.z = 0.0;        dv_tot  = vec_add(dv_tot,dv);/*        dv      = vec_scale( vn, -(1.0+sqrt( 1.0-(1.0-exp(-vec_abs(vn)*CUSHION_LOSS_O1)) )) );        ball->v = vec_add(ball->v,dv);*/        /* parallel component */        dv      = vec_scale( vec_unit(vec_add(perimeter_speed_mormal(ball, wall->n),vp)), -vec_abs(dv)*MU_BANDE );        if( !options_jump_shots ) dv.z = 0.0;        /* ang mom change due to friction */        dw      = vec_cross(vec_scale(dv,ball->m/2.0/ball->I),vec_scale(wall->n,ball->d));        dw_tot  = vec_add(dw_tot,dw);/*#if options_jump_shots#else        dv.z    = 0.0;#endif*/        dv_tot  = vec_add(dv_tot,dv);//        printf("dv=(%f,%f,%f)\n",vn.x,vn.y,vn.z);        /* ang mom change due to eccentric hit */////        dw      = vec_scale(vec_cross(wall->n, vec_proj(dv,ball->v)), ball->d/2.0 * ball->m/ball->I );////        if( vec_mul(vec_unit(ball->w),dw)<-2.0*vec_abs(vec_proj(ball->w,dw)) ) dw=vec_scale(vec_proj(ball->w,dw),-2.0);////        dw_tot  = vec_add(dw_tot,dw);        ball->v = vec_add(ball->v,dv_tot);        ball->w = vec_add(ball->w,dw_tot);//        fprintf(stderr,"dv=(%f,%f,%f)",dv.x,dv.y,dv.z);        /* maybe some angular momentum loss has to be implemented here */        /* ... */    } else if(wall->pnr==2){        myvec vp, vn;        double loss;        dr      = vec_diff( wall->r2, wall->r1 );        n       = vec_diff( ball->r, wall->r1 );        n       = vec_unit( vec_diff( n, vec_proj(n,dr) ) );        vn      = vec_proj(ball->v, n);        vp      = vec_diff(ball->v, vn);        loss = CUSHION_LOSS_O0+            (CUSHION_MAX_LOSS-CUSHION_LOSS_O0)*(1.0-exp(-vec_abs(vn)/CUSHION_LOSS_WSPEED));        dv      = vec_scale(n,-vec_mul(n,ball->v)*2.0);        if( options_jump_shots ) dv.z = 0.0;//        dv      = vec_scale(vn, -(1.0+sqrt(1.0-loss)) );        dv_tot  = vec_add(dv_tot,dv);        /* ang mom change due to eccentric hit */        /* dL = eccentricity * F*dt = eccentricity * impact change = ecc * dv * M_BALL */        /* dw = dL/I *///        dw      = vec_scale(vec_cross(n, vec_proj(dv,ball->v)), -ball->d/2.0 * ball->m/ball->I );////        if( vec_mul(vec_unit(ball->w),dw)<-2.0*vec_abs(vec_proj(ball->w,dw)) ) dw=vec_scale(vec_proj(ball->w,dw),-2.0);        /* ang mom change due to friction (and appropriate speed change) */        dv      = vec_scale( vec_unit(vec_add(vec_cross(ball->w,vec_scale(n,-ball->d/2.0)),vp)), -vec_abs(dv)*MU_BANDE );        if( !options_jump_shots ) dv.z = 0.0;        dv_tot  = vec_add(dv_tot,dv);        dw      = vec_cross(vec_scale(dv,ball->m/2.0/ball->I),vec_scale(n,ball->d));        /* ... */        ball->v = vec_add(ball->v,dv_tot);        ball->w = vec_add(ball->w,dw);    } else if(wall->pnr==1){        n       = vec_unit( vec_diff( ball->r, wall->r1 ) );        dv      = vec_scale(n,vec_mul(n,ball->v)*2.0);        ball->v = vec_diff(ball->v,dv);    }#undef CUSHION_LOSS#undef CUSHION_LOSS_O1#undef MU_BANDE}#endifstatic void ball_wall_interaction( BallType * ball, BorderType * wall ){//#define CUSHION_LOSS         0.2     /* const loss of energy by cushion *///#define CUSHION_LOSS_O1      0.07    /* linear (in speed) loss of energy by cushion *///#define MU_BANDE             0.1     /* friction const between cusion an ball */#define CUSHION_LOSS_O0      (wall->loss0)       /* const loss of energy by cushion */#define CUSHION_MAX_LOSS     (wall->loss_max)    /* const loss of energy by cushion */#define CUSHION_LOSS_WSPEED  (wall->loss_wspeed) /* prop. halbwertsgeschwindigkeit */#define MU_BANDE             (wall->mu)          /* friction const between cusion an ball */    myvec dv, dw, dr, n, hit_normal;    if       (wall->pnr==3){        hit_normal=wall->n;    } else if(wall->pnr==2){        dr      = vec_diff( wall->r2, wall->r1 );        hit_normal = vec_diff( ball->r, wall->r1 );        hit_normal = vec_unit( vec_diff( hit_normal, vec_proj(hit_normal,dr) ) );    } else if(wall->pnr==1){        hit_normal = vec_unit( vec_diff( ball->r, wall->r1 ) );    }    if       (wall->pnr==3 || wall->pnr==2 || wall->pnr==1){        myvec vp, vn;        double loss;        vn      = vec_proj(ball->v, hit_normal);        vp      = vec_diff(ball->v, vn);        //        dv      = vec_scale(wall->n,vec_mul(wall->n,ball->v)*2.0);        /* normal component */        loss = CUSHION_LOSS_O0+               (CUSHION_MAX_LOSS-CUSHION_LOSS_O0)*(1.0-exp(-vec_abs(vn)/CUSHION_LOSS_WSPEED));//        loss    = CUSHION_LOSS;        dv      = vec_scale( vn, -(1.0+sqrt(1.0-loss)) );        ball->v = vec_add(ball->v,dv);/*        dv      = vec_scale( vn, -(1.0+sqrt( 1.0-(1.0-exp(-vec_abs(vn)*CUSHION_LOSS_O1)) )) );        ball->v = vec_add(ball->v,dv);*/        /* parallel component */        dv      = vec_scale( vec_unit(vec_add(perimeter_speed_normal(ball, hit_normal),vp)), -vec_abs(dv)*MU_BANDE );        dw      = vec_cross(vec_scale(dv,ball->m/2.0/ball->I),vec_scale(hit_normal,ball->d));        {            myvec dw2;            dw2 = vec_add(dw,vec_proj(ball->w,dw));            DPRINTF(" dw=%f,%f,%f\n  w=%f,%f,%f\n",dw.x,dw.y,dw.z,ball->w.x,ball->w.y,ball->w.z);            if( vec_mul(dw2,ball->w) < 0.0 ){                DPRINTF("cutting down dw,df\n");                dw=vec_diff(dw,dw2);                dv = vec_scale(vec_unit(dv),vec_abs(dw)*2.0*ball->I/ball->m/ball->d);            }        }        ball->w = vec_add(ball->w,dw);//        ball->w = vec_xyz(0.0,0.0,0.0);#if options_jump_shots#else        dv.z    = 0.0;#endif//        printf("dv=(%f,%f,%f)\n",vn.x,vn.y,vn.z);        ball->v = vec_add(ball->v,dv);//        fprintf(stderr,"dv=(%f,%f,%f)",dv.x,dv.y,dv.z);        /* maybe some angular momentum loss has to be implemented here */        /* ... */    } else if(wall->pnr==2){        dr      = vec_diff( wall->r2, wall->r1 );        n       = vec_diff( ball->r, wall->r1 );        n       = vec_unit( vec_diff( n, vec_proj(n,dr) ) );        dv      = vec_scale(n,vec_mul(n,ball->v)*2.0);        ball->v = vec_diff(ball->v,dv);        ball->w = vec_xyz(0.0,0.0,0.0);    } else if(wall->pnr==1){        n       = vec_unit( vec_diff( ball->r, wall->r1 ) );        dv      = vec_scale(n,vec_mul(n,ball->v)*2.0);        ball->v = vec_diff(ball->v,dv);    }#undef CUSHION_LOSS#undef CUSHION_LOSS_O1#undef MU_BANDE}#elsestatic void ball_wall_interaction( BallType * ball, BorderType * wall ){    myvec dv;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -