void afterrotate(int dummy) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.3f,0.6f,1.0f); glBegin(GL_LINE_LOOP); glVertex2d(-5,-320); glVertex2d(5,-320); glVertex2d(5,0); glVertex2d(-5,0); glEnd(); glColor3f(1.0f,0.3f,0.6f); glBegin(GL_POINTS); glVertex2d(0,0); glEnd(); glColor3f(0.3f,1.0f,0.6f); glBegin(GL_LINES); glVertex2d(0,0); glVertex2d(nx[0],ny[0]); glVertex2d(0,0); glVertex2d(nx[1],ny[1]); glVertex2d(0,0); glVertex2d(nx[2],ny[2]); glVertex2d(0,0); glVertex2d(ny[3],ny[3]); glEnd(); glFlush(); myRotate(nx,ny); glutTimerFunc(1000,afterrotate,1); }
//This function is the display function that calls draw functions. void display() { glClearColor(1.0, 1.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glColor3f(0.0, 0.0, 0.0); //Draw cube away from origin initMat(curMatrix); myScale(20, 40, 20); myTranslate(50, -30, -40); myRotate(45, 0, 1, 0); myCube(); glFlush(); }
void GameEntity::MomentumHit(GameEntity &g1,GameEntity &g2) { //只适用于两个圆 //参考flash //确定已经碰撞后 double vx1,vy1,vr1; double vx2,vy2,vr2; //2014-3-15 double vx1o,vy1o,vr1o; double vx2o,vy2o,vr2o; g1.GetVelocity(vx1o,vy1o,vr1o); g2.GetVelocity(vx2o,vy2o,vr2o); //用于粗暴调整位置 g1.GetVelocity(vx1,vy1,vr1); g2.GetVelocity(vx2,vy2,vr2); double r1=g1.GetCircle().r,r2=g2.GetCircle().r; double dx=g2.GetCircle().x-g1.GetCircle().x; double dy=g2.GetCircle().y-g1.GetCircle().y; double dist=sqrt(dx*dx+dy*dy); double angle=atan2(dy,dx); double s=sin(angle); double c=cos(angle); Point pos1; pos1.x=0; pos1.y=0; //g2变成g1坐标系 Point pos2=myRotate(dx,dy,s,c,true); //g1速度调整 Point vel1=myRotate(vx1,vy1,s,c,true); //g2速度调整 Point vel2=myRotate(vx2,vy2,s,c,true); //这样只有vx起作用,vy法向速度不用考虑 //碰撞反应 double vxTotal=vel1.x-vel2.x; //考虑质量的做法 //vel1.x=((mass1-mass2)*vel1.x+2*mass2*vel2.x)/(mass1+mass2); //vel2.x=vxTotal+vel1.x; //我质量都相等 vel1.x=vel2.x; vel2.x=vxTotal+vel1.x; //更新位置,防止吸住 //3_11,防除数为零 double absV=abs(vel1.x)+abs(vel2.x); if(absV==0) { double overlap=(r1+r2)-abs(pos1.x-pos2.x); //如果我所有Robot(Bullet不发生动量碰撞)半径都一样又可简化 double tmp=pos1.x>pos2.x ? 1 : -1; pos1.x+=tmp*overlap; pos2.x+=-tmp*overlap; } else { double overlap=(r1+r2)-abs(pos1.x-pos2.x); //如果我所有Robot(Bullet不发生动量碰撞)半径都一样又可简化 pos1.x+=vel1.x/absV*overlap; pos2.x+=vel2.x/absV*overlap; } //旋转回去 Point pos1F=myRotate(pos1.x,pos1.y,s,c,false); Point pos2F=myRotate(pos2.x,pos2.y,s,c,false); /* //调整到屏幕坐标系 g2.SetX(g1.GetCircle().x+pos2F.x); g2.SetY(g1.GetCircle().y+pos2F.y); g1.SetX(g1.GetCircle().x+pos1F.x); g1.SetY(g1.GetCircle().y+pos1F.y); */ //把速度旋转回去 Point vel1F=myRotate(vel1.x,vel1.y,s,c,false); Point vel2F=myRotate(vel2.x,vel2.y,s,c,false); //2014-3-15粗暴调整位置 g2.SetX(g2.GetCircle().x-vx2o); g2.SetY(g2.GetCircle().y-vy2o); g1.SetX(g1.GetCircle().x-vx1o); g1.SetY(g1.GetCircle().y-vy1o); /* //20150509 Vector2D g1_pos(g1.circle.x,g1.circle.y); Vector2D g2_pos(g2.circle.x,g2.circle.y); Vector2D g1_to_g2(g2_pos - g1_pos); //double mov_length = (g1_to_g2.Length() - (g1.circle.r + g2.circle.r) ) / 2; g1_to_g2.Normalize(); g1_pos -= 3 * g1_to_g2; g2_pos += 3 * g1_to_g2; g2.SetX(g2_pos.x); g2.SetY(g2_pos.y); g1.SetX(g1_pos.x); g1.SetY(g1_pos.y); */ //这里直接设定vx,vy会有问题(对蜘蛛和毁灭者) //因为操纵vxvy时是直接设定值而非叠加 g1.SetVX(vel1F.x); g1.SetVY(vel1F.y); g2.SetVX(vel2F.x); g2.SetVY(vel2F.y); }
void GameEntity::MomentumHit_Half(GameEntity &g1,GameEntity &g2) { //只适用于两个圆 //g2固定物体,只要反一下相对坐标系中g1的速度 //参考flash //确定已经碰撞后 double vx1,vy1,vr1; g1.GetVelocity(vx1,vy1,vr1); double r1=g1.GetCircle().r,r2=g2.GetCircle().r; double dx=g2.GetCircle().x-g1.GetCircle().x; double dy=g2.GetCircle().y-g1.GetCircle().y; double dist=sqrt(dx*dx+dy*dy); double angle=atan2(dy,dx); double s=sin(angle); double c=cos(angle); Point pos1; pos1.x=0; pos1.y=0; //g2变成g1坐标系 Point pos2=myRotate(dx,dy,s,c,true); //g1速度调整 Point vel1=myRotate(vx1,vy1,s,c,true); //这样只有vx起作用,vy法向速度不用考虑 //我质量都相等 vel1.x=-vel1.x; /* //更新位置,防止吸住 double absV=abs(vel1.x); double overlap=(r1+r2)-abs(pos1.x-pos2.x); //如果我所有Robot(Bullet不发生动量碰撞)半径都一样又可简化 pos1.x+=vel1.x/absV*overlap; */ double tmp=vel1.x>0 ? 1 : -1; //防vel1.x=0的情况 double overlap=(r1+r2)-abs(pos1.x-pos2.x); pos1.x+=tmp*overlap; //旋转回去 Point pos1F=myRotate(pos1.x,pos1.y,s,c,false); //调整到屏幕坐标系 g1.SetX(g1.GetCircle().x+pos1F.x); g1.SetY(g1.GetCircle().y+pos1F.y); //把速度旋转回去 Point vel1F=myRotate(vel1.x,vel1.y,s,c,false); g1.SetVX(vel1F.x); g1.SetVY(vel1F.y); }