Exemplo n.º 1
0
void QgsCircularString::addToPainterPath( QPainterPath &path ) const
{
  int nPoints = numPoints();
  if ( nPoints < 1 )
  {
    return;
  }

  if ( path.isEmpty() || path.currentPosition() != QPointF( mX[0], mY[0] ) )
  {
    path.moveTo( QPointF( mX[0], mY[0] ) );
  }

  for ( int i = 0; i < ( nPoints - 2 ) ; i += 2 )
  {
    QgsPointSequence pt;
    segmentize( QgsPointV2( mX[i], mY[i] ), QgsPointV2( mX[i + 1], mY[i + 1] ), QgsPointV2( mX[i + 2], mY[i + 2] ), pt );
    for ( int j = 1; j < pt.size(); ++j )
    {
      path.lineTo( pt.at( j ).x(), pt.at( j ).y() );
    }
    //arcTo( path, QPointF( mX[i], mY[i] ), QPointF( mX[i + 1], mY[i + 1] ), QPointF( mX[i + 2], mY[i + 2] ) );
  }

  //if number of points is even, connect to last point with straight line (even though the circular string is not valid)
  if ( nPoints % 2 == 0 )
  {
    path.lineTo( mX[ nPoints - 1 ], mY[ nPoints - 1 ] );
  }
}
Exemplo n.º 2
0
QgsLineString *QgsCircularString::curveToLine( double tolerance, SegmentationToleranceType toleranceType ) const
{
  QgsLineString *line = new QgsLineString();
  QgsPointSequence points;
  int nPoints = numPoints();

  for ( int i = 0; i < ( nPoints - 2 ) ; i += 2 )
  {
    segmentize( pointN( i ), pointN( i + 1 ), pointN( i + 2 ), points, tolerance, toleranceType );
  }

  line->setPoints( points );
  return line;
}
Exemplo n.º 3
0
void OGRCircularString::segmentize( double dfMaxLength )
{
    if( !IsValidFast() || nPointCount == 0 )
        return;

    // So as to make sure that the same line followed in both directions
    // result in the same segmentized line.
    if( paoPoints[0].x < paoPoints[nPointCount - 1].x ||
        (paoPoints[0].x == paoPoints[nPointCount - 1].x &&
         paoPoints[0].y < paoPoints[nPointCount - 1].y) )
    {
        reversePoints();
        segmentize(dfMaxLength);
        reversePoints();
    }

    std::vector<OGRRawPoint> aoRawPoint;
    std::vector<double> adfZ;
    for( int i = 0; i < nPointCount - 2; i += 2 )
    {
        const double x0 = paoPoints[i].x;
        const double y0 = paoPoints[i].y;
        const double x1 = paoPoints[i+1].x;
        const double y1 = paoPoints[i+1].y;
        const double x2 = paoPoints[i+2].x;
        const double y2 = paoPoints[i+2].y;
        double R = 0.0;
        double cx = 0.0;
        double cy = 0.0;
        double alpha0 = 0.0;
        double alpha1 = 0.0;
        double alpha2 = 0.0;

        aoRawPoint.push_back(OGRRawPoint(x0, y0));
        if( padfZ )
            adfZ.push_back(padfZ[i]);

        // We have strong constraints on the number of intermediate points
        // we can add.

        if( OGRGeometryFactory::GetCurveParmeters(x0, y0, x1, y1, x2, y2,
                                                  R, cx, cy,
                                                  alpha0, alpha1, alpha2) )
        {
            // It is an arc circle.
            const double dfSegmentLength1 = fabs(alpha1 - alpha0) * R;
            const double dfSegmentLength2 = fabs(alpha2 - alpha1) * R;
            if( dfSegmentLength1 > dfMaxLength ||
                dfSegmentLength2 > dfMaxLength )
            {
                const double dfVal =
                    1 + 2 * std::floor(dfSegmentLength1 / dfMaxLength / 2.0);
                if ( dfVal >= std::numeric_limits<int>::max() ||
                     dfVal < 0.0 ||
                     CPLIsNan(dfVal) )
                {
                    CPLError(
                        CE_Failure, CPLE_AppDefined,
                        "segmentize nIntermediatePoints invalid: %lf", dfVal);
                    break;
                }
                const int nIntermediatePoints = static_cast<int>(dfVal);
                const double dfStep =
                    (alpha1 - alpha0) / (nIntermediatePoints + 1);
                for( int j = 1; j <= nIntermediatePoints; ++j )
                {
                    double alpha = alpha0 + dfStep * j;
                    const double x = cx + R * cos(alpha);
                    const double y = cy + R * sin(alpha);
                    aoRawPoint.push_back(OGRRawPoint(x, y));
                    if( padfZ )
                    {
                        const double z =
                            padfZ[i] +
                            (padfZ[i+1] - padfZ[i]) * (alpha - alpha0) /
                            (alpha1 - alpha0);
                        adfZ.push_back(z);
                    }
                }
            }
            aoRawPoint.push_back(OGRRawPoint(x1, y1));
            if( padfZ )
                adfZ.push_back(padfZ[i+1]);

            if( dfSegmentLength1 > dfMaxLength ||
                dfSegmentLength2 > dfMaxLength )
            {
                const double dfVal =
                    1 + 2 * std::floor(dfSegmentLength2 / dfMaxLength / 2.0);
                if ( dfVal >= std::numeric_limits<int>::max() ||
                     dfVal < 0.0 ||
                     CPLIsNan(dfVal) )
                {
                    CPLError(
                        CE_Failure, CPLE_AppDefined,
                        "segmentize nIntermediatePoints invalid 2: %lf", dfVal);
                    break;
                }
                int nIntermediatePoints = static_cast<int>(dfVal);
                const double dfStep =
                    (alpha2 - alpha1) / (nIntermediatePoints + 1);
                for( int j = 1; j <= nIntermediatePoints; ++j )
                {
                    const double alpha = alpha1 + dfStep * j;
                    const double x = cx + R * cos(alpha);
                    const double y = cy + R * sin(alpha);
                    aoRawPoint.push_back(OGRRawPoint(x, y));
                    if( padfZ )
                    {
                        const double z =
                            padfZ[i+1] +
                            (padfZ[i+2] - padfZ[i+1]) *
                            (alpha - alpha1) / (alpha2 - alpha1);
                        adfZ.push_back(z);
                    }
                }
            }
        }
        else
        {
            // It is a straight line.
            const double dfSegmentLength1 = dist(x0, y0, x1, y1);
            const double dfSegmentLength2 = dist(x1, y1, x2, y2);
            if( dfSegmentLength1 > dfMaxLength ||
                dfSegmentLength2 > dfMaxLength )
            {
                const double dfVal =
                    1 + 2 * std::ceil(dfSegmentLength1 / dfMaxLength / 2.0);
                if ( dfVal >= std::numeric_limits<int>::max() ||
                     dfVal < 0.0 ||
                     CPLIsNan(dfVal) )
                {
                    CPLError(
                        CE_Failure, CPLE_AppDefined,
                        "segmentize nIntermediatePoints invalid 2: %lf", dfVal);
                    break;
                }
                int nIntermediatePoints = static_cast<int>(dfVal);
                for( int j = 1; j <= nIntermediatePoints; ++j )
                {
                    aoRawPoint.push_back(OGRRawPoint(
                            x0 + j * (x1-x0) / (nIntermediatePoints + 1),
                            y0 + j * (y1-y0) / (nIntermediatePoints + 1)));
                    if( padfZ )
                        adfZ.push_back(padfZ[i] + j * (padfZ[i+1]-padfZ[i]) /
                                       (nIntermediatePoints + 1));
                }
            }

            aoRawPoint.push_back(OGRRawPoint(x1, y1));
            if( padfZ )
                adfZ.push_back(padfZ[i+1]);

            if( dfSegmentLength1 > dfMaxLength ||
                dfSegmentLength2 > dfMaxLength )
            {
                const double dfVal =
                    1 + 2 * std::ceil(dfSegmentLength2 / dfMaxLength / 2.0);
                if ( dfVal >= std::numeric_limits<int>::max() ||
                     dfVal < 0.0 ||
                     CPLIsNan(dfVal) )
                {
                    CPLError(
                        CE_Failure, CPLE_AppDefined,
                        "segmentize nIntermediatePoints invalid 3: %lf", dfVal);
                     break;
                }
                const int nIntermediatePoints = static_cast<int>(dfVal);

                for( int j = 1; j <= nIntermediatePoints; ++j )
                {
                    aoRawPoint.push_back(OGRRawPoint(
                            x1 + j * (x2-x1) / (nIntermediatePoints + 1),
                            y1 + j * (y2-y1) / (nIntermediatePoints + 1)));
                    if( padfZ )
                        adfZ.push_back(padfZ[i+1] + j * (padfZ[i+2]-padfZ[i+1])
                                       / (nIntermediatePoints + 1));
                }
            }
        }
    }
    aoRawPoint.push_back(paoPoints[nPointCount-1]);
    if( padfZ )
        adfZ.push_back(padfZ[nPointCount-1]);

    CPLAssert(aoRawPoint.empty() ||
              (aoRawPoint.size() >= 3 && (aoRawPoint.size() % 2) == 1));
    if( padfZ )
    {
        CPLAssert(adfZ.size() == aoRawPoint.size());
    }

    // Is there actually something to modify?
    if( nPointCount < static_cast<int>(aoRawPoint.size()) )
    {
        nPointCount = static_cast<int>(aoRawPoint.size());
        paoPoints = static_cast<OGRRawPoint *>(
                CPLRealloc(paoPoints, sizeof(OGRRawPoint) * nPointCount));
        memcpy(paoPoints, &aoRawPoint[0], sizeof(OGRRawPoint) * nPointCount);
        if( padfZ )
        {
            padfZ = static_cast<double *>(
                CPLRealloc(padfZ, sizeof(double) * aoRawPoint.size()));
            memcpy(padfZ, &adfZ[0], sizeof(double) * nPointCount);
        }
    }
}
Exemplo n.º 4
0
/**
 * @brief Generates tracks for some number of azimuthal angles and track spacing
 * @details Computes the effective angles and track spacing. Computes the
 *          number of Tracks for each azimuthal angle, allocates memory for
 *          all Tracks at each angle and sets each Track's starting and ending
 *          Points, azimuthal angle, and azimuthal angle quadrature weight.
 */
void TrackGenerator::generateTracks() {

  if (_geometry == NULL)
    log_printf(ERROR, "Unable to generate Tracks since no Geometry "
               "has been set for the TrackGenerator");

  /* Deletes Tracks arrays if Tracks have been generated */
  if (_contains_tracks) {
    delete [] _num_tracks;
    delete [] _num_segments;
    delete [] _num_x;
    delete [] _num_y;
    delete [] _azim_weights;

    for (int i = 0; i < _num_azim; i++)
      delete [] _tracks[i];

    delete [] _tracks;
  }

  initializeTrackFileDirectory();

  /* If not Tracks input file exists, generate Tracks */
  if (_use_input_file == false) {

    /* Allocate memory for the Tracks */
    try {
      _num_tracks = new int[_num_azim];
      _num_x = new int[_num_azim];
      _num_y = new int[_num_azim];
      _azim_weights = new FP_PRECISION[_num_azim];
      _tracks = new Track*[_num_azim];
    }
    catch (std::exception &e) {
      log_printf(ERROR, "Unable to allocate memory for TrackGenerator. "
                 "Backtrace:\n%s", e.what());
    }

    /* Check to make sure that height, width of the Geometry are nonzero */
    if (_geometry->getHeight() <= 0 || _geometry->getHeight() <= 0)
      log_printf(ERROR, "The total height and width of the Geometry must be "
                 "nonzero for Track generation. Create a CellFill which "
                 "is filled by the entire geometry and bounded by XPlanes "
                 "and YPlanes to enable the Geometry to determine the total "
                 "width and height of the model.");

    /* Generate Tracks, perform ray tracing across the geometry, and store
     * the data to a Track file */
    try {
      initializeTracks();
      recalibrateTracksToOrigin();
      segmentize();
      dumpTracksToFile();
    }
    catch (std::exception &e) {
      log_printf(ERROR, "Unable to allocate memory needed to generate "
                 "Tracks. Backtrace:\n%s", e.what());
    }
  }

  initializeBoundaryConditions();
  return;
}