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 ] ); } }
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; }
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); } } }
/** * @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; }