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

📄 billmove.c

📁 这是一个相当棒的Linux下的台球游戏
💻 C
📖 第 1 页 / 共 3 页
字号:
    dv      = vec_scale(wall->n,vec_mul(wall->n,ball->v)*(1.0+sqrt(1.0-CUSHION_LOSS)));    ball->v = vec_diff(ball->v,dv);    /* maybe some angular momentum loss has to be implemented here */    /* ... */}#endif#define MU_OMEGA             0.1      /* transmitted ang. mom. ratio (at hit) */#define MU_BALL              0.1      /* friction const between ball and ball */static void ball_ball_interaction( BallType * b1, BallType * b2 ){    BallType b1s, b2s;  /* balls in coord system of b1 */    myvec dvec, duvec, dvn, dvp, dw1, dw2;    myvec dw1max, dw2max;    myvec dpp, dpn, fric_dir,perimeter_speed_b1, perimeter_speed_b2;    dvec = vec_diff(b1->r,b2->r);    duvec = vec_unit(dvec);    /* stoss */    b1s=*b1; b2s=*b2;    b2s.v.x-=b1s.v.x;   b2s.v.y-=b1s.v.y;   b2s.v.z-=b1s.v.z;    b1s.v.x=0.0;        b1s.v.y=0.0;        b1s.v.z=0.0;    dvn   = vec_scale(duvec,vec_mul(duvec,b2s.v));    dvp   = vec_diff( b2s.v, dvn );    b2s.v = vec_diff( b2s.v, dvn );    b2s.v = vec_add ( b2s.v, vec_scale(dvn,(b2s.m-b1s.m)/(b1s.m+b2s.m)) );    b1s.v = vec_scale( dvn, 2.0*b2s.m/(b1s.m+b2s.m) );  /* (momentum transfer)/m1 */    b2->v = vec_add( b1->v, b2s.v );    b1->v = vec_add( b1->v, b1s.v );//    dw1 = vec_scale(b1->w,MU_OMEGA);//    dw2 = vec_scale(b2->w,MU_OMEGA);    /* angular momentum transfer */    dpn  = vec_scale(b1s.v,b1s.m); /* momentum transfer from ball2 to ball1 */    perimeter_speed_b1=vec_cross( b1->w, vec_scale(duvec,-b1->d/2.0) );    perimeter_speed_b2=vec_cross( b2->w, vec_scale(duvec, b2->d/2.0) );    fric_dir = vec_unit(vec_add(vec_diff(perimeter_speed_b2,perimeter_speed_b1),dvp));    dpp = vec_scale(fric_dir,-vec_abs(dpn)*MU_BALL);  /* dp parallel of ball2 */    dw2 = vec_scale( vec_cross(dpp,duvec), b2->d/b2->I );    dw1 = vec_scale( vec_cross(dpp,duvec), b1->d/b1->I );    dw2max = vec_scale(vec_proj(vec_diff(b2->w,b1->w),dw2),0.5);    dw1max = vec_scale(vec_proj(vec_diff(b1->w,b2->w),dw2),0.5);    if( vec_abs(dw1)>vec_abs(dw1max) || vec_abs(dw2)>vec_abs(dw2max) ){        /* correct momentum transfer to max */        dpp = vec_scale(dpp,vec_abs(dw2max)/vec_abs(dw2));        /* correct amg mom transfer to max */        dw2=dw2max;        dw1=dw1max;    }    b1->w = vec_diff( b1->w,dw1 );    b2->w = vec_diff( b2->w,dw2 );    /* parallel momentum transfer due to friction between balls */    {        myvec dv1, dv2;        dv1   = vec_scale(dpp,-b1->m);        dv2   = vec_scale(dpp, b2->m);        dv1.z=0.0;        dv2.z=0.0;        b1->v = vec_add( b1->v, dv1 );        b2->v = vec_add( b2->v, dv2 );    }//    b1->w = vec_diff( vec_diff(b1->w,dw1), vec_scale(dw2,(b2->I)/(b1->I)) );//    b2->w = vec_diff( vec_diff(b2->w,dw2), vec_scale(dw1,(b1->I)/(b2->I)) );}#define  D_MIN               1.0E-5      /* 1E-5 = 1/100 mm */#define  V_MIN               1.0E-2      /* 1E-3 = 1 mm/s */#define  SLIDE_THRESH_SPEED  1.0E-2      /* 1E-2 = 1 cm/s */static int ball_in_hole(BallType *ball, BordersType *borders){    int i;    for(i=0;i<borders->holenr;i++){        if( vec_abs(vec_diff(borders->hole[i].pos,ball->r)) <            borders->hole[i].r/* - ball->d/2.0*/ ){            return i+1;        }    }    return 0;}int ball_outside( BallType *ball, BordersType *borders ){    int rval=0;    int i;    for(i=0;i<borders->nr;i++){        rval = rval || BALL_WALL_DIST_I(ball[0],borders->border[i])<0.0;    }    return rval;}void remove_balls_from_game( BallsType *balls, BordersType *borders ){    int i;    for(i=0;i<balls->nr;i++){/*        if( ball_in_hole(&balls->ball[i], borders) ){            balls->ball[i].v.z-=        }*//*        if( ball_outside(&balls->ball[i],borders) ){*/        if( balls->ball[i].r.z < -0.1 ){            balls->ball[i].in_game=0;            balls->ball[i].in_hole=0;            balls->ball[i].v = vec_xyz( 0.0, 0.0, 0.0 );            balls->ball[i].r = vec_xyz( 0.0, 0.0, 0.0 );            if( balls->ball[i].nr==0 ) move_log.out_white=1;            if( balls->ball[i].nr==8 ) move_log.out_black=1;            if( balls->ball[i].nr<8 && balls->ball[i].nr!=0 ) move_log.out_full++;            if( balls->ball[i].nr>8 && balls->ball[i].nr!=0 ) move_log.out_half++;/*            move_log.event[move_log.eventnr].event=BALL_out;            move_log.event[move_log.eventnr].ballnr=balls->ball[i].nr;            move_log.event[move_log.eventnr].ballnr2=0;            move_log.event[move_log.eventnr].pos=balls->ball[i].r;            move_log.event[move_log.eventnr].timestep_nr=move_log.timestep_nr;            move_log.eventnr++;*/            record_move_log_event( BALL_out, balls->ball[i].nr, 0, balls, 0.0 );        }    }}static int proceed_dt_euler(BallsType *balls, BordersType *borders, BMfloat dt, int depth)/* this one does not remove fallen balls */{    myvec dx;    BMfloat dphi, dt1;    int i,j,k;    int rnd[100];    int collided=0;//    if (depth>500) return 0;//    fprintf(stderr,"proceed_dt_euler: depth=%d\n",depth);    /* move all balls */    for(i=0;i<balls->nr;i++){        /* translate ball */        dx = vec_scale(balls->ball[i].v,dt);        balls->ball[i].r = vec_add(balls->ball[i].r,dx);        /* perform rotation */        dphi = vec_abs(balls->ball[i].w)*dt;        //        rot_ax( balls->ball[i].w, balls->ball[i].b, 3, -dphi );        if( dphi > 1.0E-30 )            rot_ax( balls->ball[i].w, balls->ball[i].b, 3, dphi );    }    calc_rand_table(rnd,balls->nr);    /* checks */    for(i=0;i<balls->nr;i++) if(balls->ball[i].in_game){ /* check for one collision */        /* check wall collisions */        for(j=0;j<borders->nr;j++){//            fprintf(stderr,"1:bwdist=%f\n",BALL_WALL_DIST(balls->ball[i],borders->border[j]));            if( BALL_WALL_DIST(balls->ball[i],borders->border[j]) < balls->ball[i].d/2.0 && !ball_in_hole(&(balls->ball[i]),borders) ){//                fprintf(stderr,"found ball-border collision\n");                dt1=calc_wall_collision_time(&balls->ball[i],&borders->border[j]);                /* dt1 should be negative *///#endif//                fprintf(stderr,"dt1=%f j=%d\n",dt1,j);                if( dt1>0.0 || fabs(dt)>dt ){                    if( dt1>0.0 ){//                        fprintf(stderr,"wall: dt1>0 !!!\n");                    }                    if( fabs(dt)>dt ){//                        fprintf(stderr,"wall: |dt1| > dt\n");                    }                } else {                    proceed_dt_euler(balls,borders,dt1,depth+1); /* move back to coll. *///                    fprintf(stderr,"bwdist=%f\n",fabs(BALL_WALL_DIST(balls->ball[i],borders->border[j])));                    if ( fabs(BALL_WALL_DIST(balls->ball[i],borders->border[j])-balls->ball[i].d/2.0) < 1E-5 /*1E-5 = 1/100 mm*/ ){                        /* only if ball still interacts */                        /* (ball may seem to collide with wall but when stepping back out of */                        /* wall region (wall border)) */                        ball_wall_interaction(&balls->ball[i],&borders->border[j]);                        collided=1;                    }                    proceed_dt_euler(balls,borders,-dt1,depth+1); /* move rest *///                    if( collided ) break;                    /*break;*/ /* no break because of second freeze bug */                }            }        }        /* check ball collision */        if (!collided) for(j=0,k=rnd[0];j<balls->nr;j++,k=rnd[j]) if(k!=i){            if( BALL_BALL_DIST( balls->ball[i], balls->ball[k] ) < (balls->ball[i].d+balls->ball[k].d)/2.0 ){//                fprintf(stderr,"found ball-ball collision\n");                dt1=calc_ball_collision_time(&balls->ball[i],&balls->ball[k]); /* dt1 should be negative */                if( dt1>0.0 || fabs(dt)>dt ){                    if( dt1>0.0 ){//                        fprintf(stderr,"ball: dt1>0 !!!\n");                    }                    if( fabs(dt)>dt ){//                        fprintf(stderr,"ball: |dt1| > dt\n");                    }                } else {                    proceed_dt_euler(balls,borders,dt1,depth+1); /* move back to coll. */                    if ( fabs( BALL_BALL_DIST( balls->ball[i], balls->ball[k] ) - (balls->ball[i].d+balls->ball[k].d)/2.0 ) < 1E-5 /*1E-5 = 1/100 mm*/ ){                        /* only if balls still interact */                        ball_ball_interaction(&balls->ball[i],&balls->ball[k]);                    }                    proceed_dt_euler(balls,borders,-dt1,depth+1); /* move rest */                    break;                }            }        }    }//    fprintf(stderr,"proceed_dt_euler: end: depth=%d\n",depth);    return(0);}static void proceed_dt_only(BallsType *balls, BordersType *borders, BMfloat dt){    myvec dx;    BMfloat dphi;    int i;    for(i=0;i<balls->nr;i++){        /* translate ball */        dx = vec_scale(balls->ball[i].v,dt);        balls->ball[i].r = vec_add(balls->ball[i].r,dx);        /* perform rotation */        dphi = vec_abs(balls->ball[i].w)*dt;        //        rot_ax( balls->ball[i].w, balls->ball[i].b, 3, -dphi );        if( dphi > 1.0E-30 )            rot_ax( balls->ball[i].w, balls->ball[i].b, 3, dphi );    }}static int wall_dv_pos( BallType * ball, BorderType * wall, BMfloat dt )/* returns 1 if border and ball strobe away fromeach other, 0 else (at time dt) */{    static VMvect ballpos;    if       ( wall->pnr == 3 ){        return( vec_mul(ball->v,wall->n) > 0.0 );    } else if( wall->pnr == 2 ){        ballpos = vec_add(ball->r,vec_scale(ball->v,dt));        return(                vec_mul(ball->v,                        vec_ncomp(                                  vec_diff(ballpos, wall->r1),                                  vec_diff(wall->r2,wall->r1)                                 )                       ) > 0.0              );    } else if( wall->pnr == 1 ){        ballpos = vec_add(ball->r,vec_scale(ball->v,dt));        return( vec_mul(vec_diff(ballpos,wall->r1),ball->v) > 0.0 );    }    return 1;}static int ball_dv_pos( BallType * b1, BallType * b2, BMfloat dt )/* returns 1 if balls strobe away fromeach other, 0 else (at time dt) */{    static VMvect b1pos, b2pos;    b1pos = vec_add(b1->r,vec_scale(b1->v,dt));    b2pos = vec_add(b2->r,vec_scale(b2->v,dt));    return( vec_mul(vec_diff(b2pos,b1pos),vec_diff(b2->v,b1->v)) > 0.0 );}static int proceed_dt_euler_new(BallsType *balls, BordersType *borders, BMfloat dt, int depth)/* this one does not remove fallen balls */{    static BMfloat logtime;    BMfloat dt1, dtmin;    int i,j;//    int rnd[100];//    int collided=0;//    int overlapnr,walloverlap,ball1overlap,ball2overlap;    int colltype, collnr, collnr2;#define COLLTYPE_WALL 1#define COLLTYPE_BALL 2#define COLLTYPE_NONE 0    if(depth==0){        logtime=dt;    } else {        logtime+=dt;    }//    if (depth>500) return 0;//    fprintf(stderr,"proceed_dt_euler: depth=%d\n",depth);    /* move all balls *///    fprintf(stderr,"proceed_dt_euler: dt=%f depth=%d\n",dt, depth);    proceed_dt_only(balls,borders,dt);    /* checks */    colltype=COLLTYPE_NONE; collnr=-1; collnr2=-1;    dtmin=0.0;    for(i=0;i<balls->nr;i++) if(balls->ball[i].in_game){ /* check for one collision */        /* check wall collisions */        for(j=0;j<borders->nr;j++){            dt1=calc_wall_collision_time(&balls->ball[i],&borders->border[j]);            if( dt1<dtmin && dt1>-dt ){                if( !wall_dv_pos(&balls->ball[i],&borders->border[j],-dt*1.0) ){ /* dont strobe apart */                    dtmin=dt1; colltype=COLLTYPE_WALL; collnr=j; collnr2=i;                }            }        }        /* check ball collisions */        for(j=0;j<balls->nr;j++) if( j!=i && balls->ball[j].in_game ){            dt1=calc_ball_collision_time(&balls->ball[i],&balls->ball[j]); /* dt1 should be negative */            if( dt1<dtmin && dt1>-dt ){                if( !ball_dv_pos(&balls->ball[j],&balls->ball[i],-dt*1.0) ){ /* dont strobe apart */                    dtmin=dt1; colltype=COLLTYPE_BALL; collnr=j; collnr2=i;                }            }        }    }    if( colltype==COLLTYPE_NONE ){    } else if( colltype==COLLTYPE_WALL ){//        fprintf(stderr,"proceed_dt_euler: wall collision dtmin=%f\n",dtmin);//        if( !wall_dv_pos(&balls->ball[collnr2],&borders->border[collnr]) ){ /* dont strobe apart *//*            record_move_log_event(BALL_wall,                                  collnr,                                  balls->ball[collnr2].nr,                                  vec_xyz(0,0,0),                                  balls->ball[collnr2].r);*//*            move_log.event[move_log.eventnr].event=BALL_wall;            move_log.event[move_log.eventnr].ballnr=collnr;            move_log.event[move_log.eventnr].ballnr2=balls->ball[collnr2].nr;            move_log.event[move_log.eventnr].pos2=balls->ball[collnr2].r;            move_log.event[move_log.eventnr].timestep_nr=move_log.timestep_nr;            move_log.eventnr++;*/            record_move_log_event( BALL_wall, collnr, balls->ball[collnr2].nr, balls, logtime+dtmin );            logtime+=dtmin;            proceed_dt_only(balls,borders,dtmin);            ball_wall_interaction(&balls->ball[collnr2],&borders->border[collnr]);            proceed_dt_euler_new(balls,borders,-dtmin,depth+1);//        }    } else if( colltype==COLLTYPE_BALL ){//        fprintf(stderr,"proceed_dt_euler: ball collision\n");//        if( !ball_dv_pos(&balls->ball[collnr],&balls->ball[collnr2]) ){ /* dont strobe apart *//*            move_log.event[move_log.eventnr].event=BALL_ball;            move_log.event[move_log.eventnr].ballnr=balls->ball[collnr].nr;            move_log.event[move_log.eventnr].ballnr2=balls->ball[collnr2].nr;            move_log.event[move_log.eventnr].pos=balls->ball[collnr].r;            move_log.event[move_log.eventnr].pos2=balls->ball[collnr2].r;            move_log.event[move_log.eventnr].timestep_nr=move_log.timestep_nr;            move_log.eventnr++;*/            record_move_log_event( BALL_ball, balls->ball[collnr].nr, balls->ball[collnr2].nr, balls, logtime+dtmin );            logtime+=dtmin;            proceed_dt_only(balls,borders,dtmin);            ball_ball_interaction(&balls->ball[collnr],&balls->ball[collnr2]);            proceed_dt_euler_new(balls,borders,-dtmin,depth+1);//        }    }/*    if(depth!=0){        logtime-=dt;    }*/    return(0);}#define GRAVITY            9.81      /* m/s^2 *///#define MU_ROLL            0.01      /* table  roll-friction const *///#define MU_SLIDE           0.1       /* table slide-friction const *///#define SPOT_R             6.0e-3    /* 3mm radius der auflageflaeche - not used for rollmom (only rotational-friction around spot) */#define MU_ROLL            0.03      /* table  roll-friction const */#define MU_SLIDE           0.2       /* table slide-friction const */#define SPOT_R             12.0e-3    /* 3mm radius der auflageflaeche - not used for rollmom (only rotational-friction around spot) *///#define  OMEGA_MIN           M_PI/8.0   /* 22.5

⌨️ 快捷键说明

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