float Player::computeAzimuth (AudioObj* obj) const { float Azimuth; float xTemp=obj->getLocation().getX() - location.getX(); float yTemp=obj->getLocation().getY() - location.getY(); if (xTemp == 0) { Azimuth = (yTemp>=0)?0:180; } else if (yTemp == 0) { Azimuth = (xTemp>0)?90:-90; } else { Azimuth = atan(fabs(xTemp/yTemp))*R2D; if(yTemp<0)Azimuth = 180-Azimuth; if(xTemp<0)Azimuth = -Azimuth; } Azimuth = Azimuth - getBearing(); if (Azimuth > 180) { while (Azimuth > 180) { Azimuth -=360; } } else if (Azimuth <= -180) { while (Azimuth <= -180) { Azimuth += 360; } } return Azimuth; }
/** * Calculates the direction of the vector pointing to the outside * of the area spanned by the two vectors. */ double outsideVector(QPoint center, QPoint p1, QPoint p2){ double v1=getBearing(center, p1); double v2=getBearing(center, p2); double res1=(v1+v2)/2; double res2=res1+M_PI; res1=normalize(res1); res2=normalize(res2); if(res1-std::min(v1,v2)<0.5 * M_PI) { return res1; } else { return res2; } }
int main(int argc, const char * argv[]) { if(argc < 5 || argc > 5) { printf("Usage: ./bikehelper start_long start_lat end_long end_lat (in degrees) \n"); exit(1); } int h; for( h = 1; h < argc; h++) { checkInputError(h, argv); } if(-180 > atof(argv[1]) || atof(argv[1]) > 180.0) { printf("Longtitude between -180 and 180 only \n"); exit(1); } if(-180 > atof(argv[3]) || atof(argv[3]) > 180.0) { printf("Longtitude between -180 and 180 only \n"); exit(1); } if(-90 > atof(argv[2]) || atof(argv[2]) > 90 ) { printf("Latitude between -90 and 90 only \n"); exit(1); } if(-90 > atof(argv[4]) || atof(argv[4]) > 90) { printf("Latitude between -90 and 90 only \n"); exit(1); } char *first_bikestop; char *destination_file; int file_size = (int)loadToMemory("/usr/local/unnc/ae1prg/npb/stops.txt" , &destination_file); char *second_bikestop; double longtitude_bus[3]; double latitude_bus[3]; char busStop_name[3][40]; char *direction[3]; int bearing[3]; printf("Starting from %s %s \n", argv[1], argv[2]); /* ---------------------------------- First part of the output ----------------------------------- */ char *stop = toBikeStop(destination_file, atof(argv[1]), atof(argv[2]), file_size, &first_bikestop); sscanf(first_bikestop, "%lf %lf %s", &longtitude_bus[0], &latitude_bus[0], busStop_name[0]); bearing[0] = getBearing(atof(argv[1]), atof(argv[2]), longtitude_bus[0], latitude_bus[0]); getDirection(bearing[0], &direction[0]); printf("Walk %s to %s at %f, %f \n", direction[0], busStop_name[0], longtitude_bus[0], latitude_bus[0]); /* ---------------------------------- Second part of the output ----------------------------------- */ char * stop1 = toBikeStop(destination_file, atof(argv[3]), atof(argv[4]), file_size, &second_bikestop); sscanf(second_bikestop, "%lf %lf %s", &longtitude_bus[1], &latitude_bus[1], busStop_name[1]); bearing[1] = getBearing(longtitude_bus[0], latitude_bus[0], longtitude_bus[1], latitude_bus[1]); getDirection(bearing[1], &direction[1]); printf("Cycle %s to %s at %f, %f \n", direction[1], busStop_name[1], longtitude_bus[1],latitude_bus[1]); /* ---------------------------------- Third part of the output ----------------------------------- */ bearing[2] = getBearing(longtitude_bus[1], latitude_bus[1], atof(argv[3]), atof(argv[4])), getDirection(bearing[2], &direction[2]); printf("Walk %s to your destination at %f, %f \n",direction[2],atof(argv[3]), atof(argv[4])); free(stop); free(stop1); free(destination_file); return 0; }
void OsmAnd::RoutePlanner::splitRoadsAndAttachRoadSegments( OsmAnd::RoutePlannerContext::CalculationContext* context, QVector< std::shared_ptr<RouteSegment> >& route ) { for(auto itSegment = iteratorOf(route); itSegment; ++itSegment) { auto segment = *itSegment; /*TODO:GC if (ctx.checkIfMemoryLimitCritical(ctx.config.memoryLimitation)) { ctx.unloadUnusedTiles(ctx.config.memoryLimitation); } */ //TODO:GC:checkAndInitRouteRegion(context, segment->road); const bool isIncrement = segment->startPointIndex < segment->endPointIndex; for(auto pointIdx = segment->startPointIndex; pointIdx != segment->endPointIndex; isIncrement ? pointIdx++ : pointIdx--) { const auto nextIdx = (isIncrement ? pointIdx + 1 : pointIdx - 1); if (pointIdx == segment->startPointIndex) attachRouteSegments(context, route, itSegment.current, pointIdx, isIncrement); if (nextIdx != segment->endPointIndex) attachRouteSegments(context, route, itSegment.current, nextIdx, isIncrement); if (nextIdx < 0 || nextIdx >= segment->attachedRoutes.size()) continue; if (nextIdx >= 0 && nextIdx < segment->attachedRoutes.size() && nextIdx != segment->endPointIndex && !segment->road->isRoundabout()) { const auto& attachedRoutes = segment->attachedRoutes[qAbs(static_cast<int64_t>(nextIdx) - segment->startPointIndex)]; auto before = segment->getBearing(nextIdx, !isIncrement); auto after = segment->getBearing(nextIdx, isIncrement); auto straight = qAbs(Utilities::normalizedAngleDegrees(before + 180.0 - after)) < (double)MinTurnAngle; auto isSplit = false; // split if needed for(const auto& attachedSegment : constOf(attachedRoutes)) { auto diff = Utilities::normalizedAngleDegrees(before + 180.0 - attachedSegment->getBearingBegin()); if (qAbs(diff) <= (double)MinTurnAngle) isSplit = true; else if (!straight && qAbs(diff) < 100.0) isSplit = true; } if (isSplit) { std::shared_ptr<RouteSegment> split(new RouteSegment(segment->road, nextIdx, segment->endPointIndex)); //TODO:split.copyPreattachedRoutes(segment, qAbs(nextIdx - segment->startPointIndex));? segment->_endPointIndex = nextIdx; segment->_attachedRoutes.resize(qAbs(static_cast<int64_t>(segment->_endPointIndex) - static_cast<int64_t>(segment->_startPointIndex)) + 1); itSegment.set(route.insert((++itSegment).current, split)); itSegment.update(route); // switch current segment to the splited segment = split; } } } } }
/** * Order of actions: * a) transition of human into infected * b) giving birth to children - changes input * c) making love - changes input * d) movement */ static void simulateStep2(WorldPtr input, WorldPtr output) { simClock clock = output->clock; // notice that we iterate over xx and yy // and the real x and y are randomly switched between two directions double xxDir = randomDouble(); double yyDir = randomDouble(); // we want to force static scheduling because we suppose that the load // is distributed evenly over the map and we need to have predictable locking #ifdef _OPENMP // at least three columns per thread int threads = omp_get_max_threads(); int numThreads = MIN(MAX(input->localWidth / 3, 1), threads); #pragma omp parallel for num_threads(numThreads) schedule(static) #endif for (int xx = input->xStart; xx <= input->xEnd; xx++) { int x = (xxDir < 0.5) ? xx : (input->xEnd + input->xStart - xx); // stats are counted per column and summed at the end Stats stats = NO_STATS; lockColumn(output, x); for (int yy = input->yStart; yy <= input->yEnd; yy++) { int y = (yyDir < 0.5) ? yy : (input->yEnd + input->yStart - yy); Entity entity = GET_CELL(input, x, y); if (entity.type == NONE) { continue; } // Convert Human to Infected if (entity.type == HUMAN) { int zombieCount = countNeighbouringZombies(input, x, y); double infectionChance = zombieCount * PROBABILITY_INFECTION; if (randomDouble() <= infectionChance) { if (entity.gender == FEMALE) { stats.humanFemalesBecameInfected++; } else { stats.humanMalesBecameInfected++; } toInfected(&entity, clock); LOG_EVENT("A Human became infected\n"); } } // Here are performed natural processed of humans and infected if (entity.type == HUMAN || entity.type == INFECTED) { // giving birth if (entity.gender == FEMALE && entity.children > 0) { if (entity.origin + entity.borns <= clock) { if (entity.type == HUMAN) { stats.humanFemalesGivingBirth++; } else { stats.infectedFemalesGivingBirth++; } Entity * freePtr; while (entity.children > 0 && (freePtr = getFreeAdjacent(input, output, x, y)) != NULL) { Entity child = giveBirth(&entity, clock); if (child.type == HUMAN) { if (child.gender == FEMALE) { stats.humanFemalesBorn++; } else { stats.humanMalesBorn++; } } else { if (child.gender == FEMALE) { stats.infectedFemalesBorn++; } else { stats.infectedMalesBorn++; } } *freePtr = child; LOG_EVENT("A %s child was born\n", child.type == HUMAN ? "Human" : "Infected"); } } else { if (entity.type == HUMAN) { stats.humanFemalesPregnant++; } else { stats.infectedFemalesPregnant++; } } } // making love if (entity.gender == FEMALE && entity.children == 0 && clock >= entity.origin + entity.fertilityStart && clock < entity.origin + entity.fertilityEnd) { // can have baby EntityPtr adjacentMale = findAdjacentFertileMale(input, x, y, clock); if (adjacentMale != NULL) { stats.couplesMakingLove++; makeLove(&entity, adjacentMale, clock, input->stats); stats.childrenConceived += entity.children; LOG_EVENT("A couple made love\n"); } } } if (entity.type == HUMAN) { if (entity.gender == FEMALE) { stats.humanFemales++; } else { stats.humanMales++; } } else if (entity.type == INFECTED) { if (entity.gender == FEMALE) { stats.infectedFemales++; } else { stats.infectedMales++; } } else { stats.zombies++; } // MOVEMENT bearing bearing_ = getBearing(input, x, y); // optimal bearing bearing_ += getRandomBearing() * BEARING_FLUCTUATION; Direction dir = bearingToDirection(bearing_); if (dir != STAY) { double bearingRandomQuotient = (randomDouble() - 0.5) * BEARING_ABS_QUOTIENT_VARIANCE + BEARING_ABS_QUOTIENT_MEAN; entity.bearing = bearing_ / cabsf(bearing_) * bearingRandomQuotient; } else { entity.bearing = bearing_; } // some randomness in direction // the entity will never go in the opposite direction if (dir != STAY) { if (randomDouble() < getMaxSpeed(&entity, clock)) { double dirRnd = randomDouble(); if (dirRnd < DIRECTION_MISSED) { dir = DIRECTION_CCW(dir); // turn counter-clock-wise } else if (dirRnd < DIRECTION_MISSED * 2) { dir = DIRECTION_CW(dir); // turn clock-wise } else if (dirRnd > DIRECTION_FOLLOW + DIRECTION_MISSED * 2) { dir = STAY; } } else { dir = STAY; } } else { // if the entity would STAY, we'll try again to make it move // to make the entity bearing variable in terms of absolute value double bearingRandomQuotient = (randomDouble() - 0.5) * BEARING_ABS_QUOTIENT_VARIANCE + BEARING_ABS_QUOTIENT_MEAN; bearing_ += getRandomBearing() * bearingRandomQuotient; dir = bearingToDirection(bearing_); } // we will try to find the cell in the chosen direction CellPtr destPtr = NULL; if (dir != STAY) { destPtr = IF_CAN_MOVE_TO(x, y, dir); if (randomDouble() < MOVEMENT_TRY_ALTERNATIVE) { if (destPtr == NULL) { destPtr = IF_CAN_MOVE_TO(x, y, DIRECTION_CCW(dir)); } if (destPtr == NULL) { destPtr = IF_CAN_MOVE_TO(x, y, DIRECTION_CW(dir)); } } } if (destPtr == NULL) { destPtr = GET_CELL_PTR(output, x, y); } // actual assignment of entity to its destination *destPtr = entity; } unlockColumn(output, x); #ifdef _OPENMP #pragma omp critical (StatsCriticalRegion2) #endif { mergeStats(&output->stats, stats, true); } } }
/** * Function interprets incoming message, extracts relevant data based on message type * and fills apropriate object variables with this data. * * Basestation SBS format message is basically single comma-separated-values (CSV) record. * Basestation produces four different SBS message types. This type is determined by first field of csv record. * Fields of which message consists are determined by this type. * * ------------------------------ * -----NEW AIRCRAFT MESSAGE----- * ------------------------------ * This message is broadcasted when SBS-1 picks up a signal for an aircraft that isn't currently tracking, * i.e. it's when a new aircraft appers on the aircraft list. Structure of this type: * * 1 AIR * 2 [null] * 3 System-generated sessionID * 4 System-generated aircraftID * 5 ICAO24 hex ident * 6 System generated flightID * 7 Date message detected * 8 Time message detected * 9 Date message logged * 10 Time message logged * * * -------------------- * -----ID MESSAGE----- * -------------------- * This message is broadcasted when a callsign is first received, or is changed. * * 1 ID * 2 [null] * 3 System-generated sessionID * 4 System-generated aircraftID * 5 ICAO24 hex ident * 6 System generated flightID * 7 Date message detected * 8 Time message detected * 9 Date message logged * 10 Time message logged * 11 Callsign * * * ---------------------------------- * -----SELECTION CHANGE MESSAGE----- * ---------------------------------- * This is rather internal Basestation system message with no new information value. * It is broadcasted when user changes the selection, or in special cases, it can be broadcasted, * when new aircraft has been added (due to implementation). * * 1 SEL * 2 [null] * 3 System-generated sessionID * 4 System-generated aircraftID * 5 ICAO24 hex ident * 6 System generated flightID * 7 Date message detected * 8 Time message detected * 9 Date message logged * 10 Time message logged * 11 Callsign * * * ------------------------------ * -----TRANSMISSION MESSAGE----- * ------------------------------ * Finally, most important message. It is basically rebroadcasting of every ADS-B message * received from aircraft - in decoded format. * This format is produced by most ADS-B decoders as text based decoded format. It is convenient * to use Basestation format for further use, due to computational complexity of decoding raw bitwise * ADS-B messages. * * 1 MSG * 2 Transmission Type * 3 System generated sessionID * 4 System generated aircraftID * 5 ICAO24 hex ident * 6 System generated flightID * 7 Date message detected * 8 Time message detected * 9 Date message logged * 10 Time message logged * 11 Callsign * 12 Altitude * 13 Ground Speed * 14 Track * 15 Lat * 16 Lon * 17 Vertical speed * 18 Squawk * 19 Alert * 20 Emergency * 21 SPI * 22 IsOnGround * * Based on second field - Transmission Type, we can distinguish a few more transmission types, * of which each sets different fields: * * Transmission Type: * 1 = ID message ----------------------- (Callsign) * 2 = Surface position message --------- (Altitude, GroundSpeed, Track, Lat, Lon) * 3 = Airborne position message -------- (Altitude, Lat, Lon, Alert, Emergency, SPI) * 4 = Airborne velocity message -------- (GroundSpeed, Rate, VerticalSpeed) * 5 = Surveillance Altitude message ---- (Altitude, Alert, SPI) * 6 = Surveillance ID (Squawk) message - (Altitude, Squawk, Alert, Emergency, SPI) * 8 = Air-Call Reply / TCAS Acquisition Squitter (None) * * * Dump1090 emulates Basestation message broadcast. It outputs only MSG (Transmission) messages, * as it rebroadcasts decoded ADS-B messages and there is no need to emulate internal SBS messages. * This function takes single transmission message and processes containing info for statistical purposes. * * [ Thanks to Mr Dave Reid for comprehensive information on this topic ] * * @param message - incoming message converted to std::string * @return 1 or 3 based on type of processed message, zero for discarded message. */ int data::processMessage(std::string message) { // Split message into individual csv fields std::vector<std::string> fields = split(message, ','); tFStamp stamp; // Switch based on message type switch (std::stoi(fields[1])) { case 1: // ID message (hex+callsign available) if ((fields[4] != "") && (fields[10] != "")) { stamp.hex = fields[4]; stamp.callsign = fields[10]; stamp.timestamp = std::time(nullptr); if (! isInFBuffer(stamp)) { std::locale loc; std::string company = stamp.callsign.substr(0,3); if ((std::isalpha(company[0])) && (std::isalpha(company[1])) && (std::isalpha(company[2])) && (std::isdigit(stamp.callsign[3]))) { if ( companyPlot.find(company) == companyPlot.end() ) { companyPlot[company] = 1; } else { companyPlot[company]++; } } flightBuffer.push_back(stamp); } } return 1; break; case 3: // Airborne position message (Altitude+lat/lon available) if ((fields[14] != "") && (fields[15] != "")) { tCoords mPos; mPos.lat = std::stod(fields[14]); mPos.lon = std::stod(fields[15]); int bearing = (int) round(getBearing(ref, mPos)); double distance = getDistance(ref, mPos); tCoords maxPos = polarRange[bearing]; double maxDistance = getDistance(ref, maxPos); if (distance > maxDistance) { polarRange[bearing] = mPos; } char buf[32]; sprintf(buf, "%d%d", (int) round(mPos.lat * 100), (int) round(mPos.lon * 100)); std::string sIntPos = buf; int intPos = std::stoi(sIntPos); if (heatMap.find(intPos) == heatMap.end()) { heatMap[intPos] = 1; } else { heatMap[intPos]++; } } if (fields[11] != "") { int fl = std::stoi(fields[11]) / 100; // Convert altitude to FL if (fl <= 500) { altPlot[fl]++; } } return 3; break; } return 0; }