📄 billmove.c
字号:
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 + -