Beispiel #1
0
/**
 * Calculate course, distance and reachability from the current position
 * to the elements contained in the limited list. If a glider is defined
 * the glide path is taken into account and the arrival altitude is
 * calculated too.
 */
void ReachableList::calculateDataInList()
{
  // QTime t;
  // t.start();
  int counter = 0;
  setInitValues();
  arrivalAltMap.clear();
  distanceMap.clear();

  for (int i = 0; i < count(); i++)
    {
      // recalculate Distance
      ReachablePoint& p = (*this)[i];
      WGSPoint pt = p.getWaypoint()->wgsPoint;
      Altitude arrivalAlt;
      Distance distance;
      Speed bestSpeed;

      distance.setKilometers( MapCalc::dist(&lastPosition, &pt) );

      if ( lastPosition == pt || distance.getMeters() <= 100.0 )
        {
          // @AP: there is nearly no difference between the two points,
          // therefore we have no distance and no bearing
          distance.setMeters(0.0);
          p.setDistance( distance );
          p.setBearing( 0 );
          p.setArrivalAlt( calculator->getAltitudeCollection().gpsAltitude  );
        }
      else
        {
          p.setDistance( distance );

          // recalculate Bearing
          p.setBearing( short (rint(MapCalc::getBearingWgs(lastPosition, pt) * 180/M_PI)) );

          // Calculate glide path. Returns false, if no glider is known.
          calculator->glidePath( p.getBearing(), p.getDistance(),
                                 Altitude(p.getElevation()),
                                 arrivalAlt, bestSpeed );

          // Save arrival altitude. Is set to invalid, if no glider is defined in calculator.
          p.setArrivalAlt( arrivalAlt );
        }

      if ( arrivalAlt.isValid() )
        {
          // add only valid altitudes to the map
          arrivalAltMap[ coordinateString ( pt ) ] = (int) arrivalAlt.getMeters() + safetyAlt;
        }

      distanceMap[ coordinateString ( pt ) ] = distance;

      if ( arrivalAlt.getMeters() > 0 )
        {
          counter++;
        }
    }

  // sorting of items depends on the glider selection
  if ( calculator->glider() )
    {
      modeAltitude = true; // glider is known, sort by arrival altitudes
    }
  else
    {
      modeAltitude = false; // glider is unknown, sort by distances
    }

  qSort( begin(), end() );
  // qDebug("Number of reachable sites (arriv >0): %d", counter );
  // qDebug("Time for glide path calculation: %d msec", t.restart() );
  emit newReachList();
}
Beispiel #2
0
QVector<float> TransformationMatrix::getFullMapTransformationMatrix(
        const Distance& wallWidth,
        QPair<double, double> physicalMazeSize,
        QPair<int, int> fullMapPosition,
        QPair<int, int> fullMapSize,
        QPair<int, int> windowSize) {

    // The purpose of this function is to produce a 4x4 matrix which, when
    // applied to the physical coordinate within the vertex shader, transforms
    // it into an OpenGL coordinate for the full map. In this case, the zoomed
    // map always contains the entirety of the maze.

    // Step 1: The physical point (0,0) corresponds to the middle of the
    // bottom-left corner piece:
    //                                 |       |
    //                                 +-------+---
    //                                 |       |
    //                                 |   X   |
    //                                 |       |
    //                                 +-------+---
    //
    // However, we want to make sure that the entire maze is visible within the
    // map window. To ensure this, we first have to translate the physical
    // positions so that (0,0) actually refers to the bottom-left corner of the
    // bottom-left corner:
    //
    //                                 |       |
    //                                 +-------+---
    //                                 |       |
    //                                 |       |
    //                                 |       |
    //                                 X-------+---
    //
    QVector<float> initialTranslationMatrix = {
        1.0, 0.0, 0.0, static_cast<float>(0.5 * wallWidth.getMeters()),
        0.0, 1.0, 0.0, static_cast<float>(0.5 * wallWidth.getMeters()),
        0.0, 0.0, 1.0,                                             0.0,
        0.0, 0.0, 0.0,                                             1.0,
    };

    // Ensure that the maze width and height always appear equally scaled.
    double physicalWidth = physicalMazeSize.first;
    double physicalHeight = physicalMazeSize.second;

    // Note that this is not literally the number of pixels per meter of the
    // screen. Rather, it's our desired number of pixels per simulation meter.
    double pixelsPerMeter = std::min(fullMapSize.first / physicalWidth, fullMapSize.second / physicalHeight);
    double pixelWidth = pixelsPerMeter * physicalWidth;
    double pixelHeight = pixelsPerMeter * physicalHeight;

    QPair<double, double> openGlOrigin =
        mapPixelCoordinateToOpenGlCoordinate({0, 0}, windowSize);
    QPair<double, double> openGlMazeSize =
        mapPixelCoordinateToOpenGlCoordinate({pixelWidth, pixelHeight}, windowSize);

    double openGlWidth = openGlMazeSize.first - openGlOrigin.first;
    double openGlHeight = openGlMazeSize.second - openGlOrigin.second;

    double horizontalScaling = openGlWidth / physicalWidth;
    double verticalScaling = openGlHeight / physicalHeight;

    QVector<float> scalingMatrix = {
        static_cast<float>(horizontalScaling),                                 0.0, 0.0, 0.0,
                                          0.0, static_cast<float>(verticalScaling), 0.0, 0.0,
                                          0.0,                                 0.0, 1.0, 0.0,
                                          0.0,                                 0.0, 0.0, 1.0,
    };
    
    // Step 3: Construct the translation matrix. Note that here we ensure that
    // the maze is centered within the map boundaries.
    double pixelLowerLeftCornerX = fullMapPosition.first + 0.5 * (fullMapSize.first - pixelWidth);
    double pixelLowerLeftCornerY = fullMapPosition.second + 0.5 * (fullMapSize.second - pixelHeight);
    QPair<double, double> openGlLowerLeftCorner =
        mapPixelCoordinateToOpenGlCoordinate({pixelLowerLeftCornerX, pixelLowerLeftCornerY}, windowSize);
    QVector<float> translationMatrix = {
        1.0, 0.0, 0.0,  static_cast<float>(openGlLowerLeftCorner.first),
        0.0, 1.0, 0.0, static_cast<float>(openGlLowerLeftCorner.second),
        0.0, 0.0, 1.0,                                              0.0,
        0.0, 0.0, 0.0,                                              1.0,
    };

    // Step 4: Compose the matrices
    QVector<float> transformationMatrix =
        multiply4x4Matrices(translationMatrix,
        multiply4x4Matrices(scalingMatrix,
                            initialTranslationMatrix));
    return transformationMatrix;
}