//calculates angle+flighttime for a given velocity //returns true if shot possible, else false //There are 2 possible (angle,time) pairs for a given speed //works with negative speeds too bool CalculateAngle ( double StartVelocity, GLfloat &angle_deg1, GLfloat &time1, GLfloat &angle_deg2, GLfloat &time2, double gravity, double player_x, double player_y, double target_x, double target_y ) { //default values that will be returned if shot impossible angle_deg1=0; time1=0; angle_deg2=0; time2=0; double dX = target_x - player_x; double dY = target_y - player_y; double StartVelocitySquared = StartVelocity * StartVelocity; double StartVelocityQuad = StartVelocitySquared * StartVelocitySquared; double delta = StartVelocityQuad -gravity* dX * dX - 2 * dY * StartVelocitySquared; if ( delta<0 ) { cerr<<"impossible shot: delta<0"<<endl; return ( false ); } double num1 = StartVelocitySquared + sqrt ( delta ); double num2 = StartVelocitySquared - sqrt ( delta ); double denom = gravity * dX; double angle_rad1 = atan2 ( num1,denom ); double angle_rad2 = atan2 ( num2,denom ); //special add-on for negative speeds if ( StartVelocity < 0 ) { angle_rad1 += M_PI; angle_rad2 += M_PI; } double V0x1=StartVelocity * cos ( angle_rad1 ); double V0x2=StartVelocity * cos ( angle_rad2 ); if ( V0x1 == 0 ) { cerr<<"impossible shot: V0x1==0"<<endl; return ( false ); } time1 = dX / V0x1; if ( V0x2 == 0 ) { cerr<<"impossible shot: V0x2==0"<<endl; return ( false ); } time2 = dX / V0x2; angle_deg1 = limit_angle ( rad2deg ( angle_rad1 ) ); angle_deg2 = limit_angle ( rad2deg ( angle_rad2 ) ); //cout<<"a_deg1="<<a_deg1<<endl; //cout<<"a_deg2="<<a_deg2<<endl; return ( true ); }
void stations_update(station *stacje, int n) { float station_speed = 2e-4 * 2 * pi; // szybkość kątowa stacji unsigned char liczba_martwych = 0; for (int i = 0; i < n; i++) { if (!stacje[i].zywa) { liczba_martwych++; continue; } if (stacje[i].hp <= 0) { stacje[i].zywa = 0; liczba_martwych++; liczba_punktow -= 1000; continue; } stacje[i].a += station_speed; stacje[i].a = limit_angle(stacje[i].a); } }
void player_bullets_update(player p, player_bullet *b, int *liczba, char mb) // mb - wciśnięte przyciski myszy { // zasięg pocisków float bullet_reach = 2.0; // ustawienia pocisków float rot_speed = 1e-2 * 2 * pi; // prędkość kątowa animowanych obrotów float linear_speed = 1e-2; // prędkość postępowa // strzelanie - tworzenie nowych pocisków static char this_click_processed = 0; if ((!this_click_processed) && (mb & 0x1) && (*liczba < 100)) { b[*liczba] = player_bullet_init(p); (*liczba)++; this_click_processed = 1; liczba_punktow -= 1; } else if (this_click_processed && !(mb & 0x1)) this_click_processed = 0; // aktualizacje każdego z pocisków for (int i = 0; i < *liczba; i++) { if (b[i].h > bullet_reach) { destroy_player_bullet(b, i, liczba); continue; } // aktualizacja współrzędnych b[i].rot += rot_speed; b[i].h += linear_speed; b[i].a = limit_angle(b[i].a); b[i].rot = limit_angle(b[i].rot); } }
//calculates velocity+angle for a given flighttime (useful for bombs) //returns true if shot possible, else false //works with negative flighttimes too because it is equivalent to -vector(v0) bool CalculateVector ( double time, GLfloat &angle_deg, GLfloat &StartVelocity, double gravity, double player_x, double player_y, double target_x, double target_y ) { //default values that will be returned if shot impossible StartVelocity = 0; angle_deg = 0; double dX = target_x - player_x; double dY = target_y - player_y; double TimeSquared = time*time; double Ypart = dY - 0.5 * gravity * TimeSquared; if ( TimeSquared == 0 ) { cerr<<"impossible shot: TimeSquared==0"<<endl; return ( false ); } StartVelocity = sqrt ( ( dX * dX + Ypart * Ypart ) /TimeSquared ); double angle_rad = atan2 ( -Ypart,dX ); //-Ypart because the V0y=-V0*sin(a) angle_deg = limit_angle ( rad2deg ( angle_rad ) ); return ( true ); }
void sodinv(double lat1, double lon1, double lat2, double lon2, double re, int flbg21, double *gcd, double *brg12, double *brg21) { /* local variables */ double ln1, ln2, bsgn12, bsgn21, dlond; double lat1r, lat2r, sl1, cl1, sl2, cl2; double cdlon, srore, crore, rore; double dlon, cbrg12, cbrg21; /* process inputs */ lat1r = lat1 * D2R; lat2r = lat2 * D2R; sl1 = sin(lat1r); cl1 = cos(lat1r); sl2 = sin(lat2r); cl2 = cos(lat2r); ln1 = limit_angle(lon1,180.0) + 180.0; /* 0 to 360 */ dlond = lon2 - lon1; dlon = dlond * D2R; cdlon = cos(dlon); /* great circle distance between points 1 and 2 */ crore = sl2 * sl1 + cl2 * cl1 * cdlon; crore = limit(crore, -1.0, 1.0); rore = acos(crore); srore = sin(rore); *gcd = re * rore; /* bearing from point 1 to point 2 */ if (*gcd >= 1.0e-38) { cbrg12 = (sl2 - sl1 * crore) / (cl1 * srore); cbrg12 = limit(cbrg12, -1.0, 1.0); /* note: the acos function returns an angle between 0 and 180 degrees */ *brg12 = acos(cbrg12) * R2D; if (dlond > 180.0) { if (dlond >= 0.0) bsgn12 = -1.0; else bsgn12 = 1.0; } else if (dlond < 180.0) { if (dlond >= 0.0) bsgn12 = 1.0; else bsgn12 = -1.0; } else { bsgn12 = 1.0; } *brg12 = bsgn12 * (*brg12); /* bearing from point 2 to point 1 */ if (flbg21 == 1) { bsgn21 = -bsgn12; cbrg21 = (sl1 - sl2 * crore) / (cl2 * srore); cbrg21 = limit(cbrg21, -1.0, 1.0); *brg21 = acos(cbrg21) * R2D; *brg21 = bsgn21 * (*brg21); } } else { /* no bearings if great circle distance is zero */ /* because brg12 and brg21 may not both be used by the user user may pass a NULL character for one ... make sure you don't write to a NULL pointer -SFC */ if(brg12 != NULL) *brg12 = 0.0; if(brg21 != NULL) *brg21 = 0.0; *gcd = 0.0; } return; }