本文整理汇总了C++中QPolygonF::last方法的典型用法代码示例。如果您正苦于以下问题:C++ QPolygonF::last方法的具体用法?C++ QPolygonF::last怎么用?C++ QPolygonF::last使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QPolygonF
的用法示例。
在下文中一共展示了QPolygonF::last方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: polygonP
QPolygonF QwtSpline::polygonP( const QPolygonF &points,
double delta, bool withNodes ) const
{
if ( delta <= 0.0 )
return QPolygonF();
const int n = points.size();
if ( n <= 1 )
return points;
if ( n == 2 )
{
// TODO
return points;
}
QPolygonF path;
const QVector<QLineF> controlPoints = bezierControlPointsP( points );
if ( controlPoints.size() < n - 1 )
return path;
path += points.first();
double t = delta;
for ( int i = 0; i < n - 1; i++ )
{
#if 1
const double l = d_parameter->value( points[i], points[i+1] );
#endif
while ( t < l )
{
path += qwtBezierPoint( points[i], controlPoints[i].p1(),
controlPoints[i].p2(), points[i+1], t / l );
t += delta;
}
if ( withNodes )
{
if ( qFuzzyCompare( path.last().x(), points[i+1].x() ) )
path.last() = points[i+1];
else
path += points[i+1];
t = delta;
}
else
{
t -= l;
}
}
if ( controlPoints.size() >= n )
{
const double l = d_parameter->value( points[n-1], points[0] );
while ( t < l )
{
path += qwtBezierPoint( points[n-1], controlPoints[n-1].p1(),
controlPoints[n-1].p2(), points[0], t / l );
t += delta;
}
if ( qFuzzyCompare( path.last().x(), points[0].x() ) )
path.last() = points[0];
else
path += points[0];
}
return path;
}
示例2: if
void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context, Placement placement )
{
if ( points.isEmpty() )
return;
QgsRenderContext& rc = context.renderContext();
double origAngle = mMarker->angle();
double angle;
int i, maxCount;
bool isRing = false;
if ( placement == FirstVertex )
{
i = 0;
maxCount = 1;
}
else if ( placement == LastVertex )
{
i = points.count() - 1;
maxCount = points.count();
}
else
{
i = 0;
maxCount = points.count();
if ( points.first() == points.last() )
isRing = true;
}
for ( ; i < maxCount; ++i )
{
const QPointF& pt = points[i];
// rotate marker (if desired)
if ( mRotateMarker )
{
if ( i == 0 )
{
if ( !isRing )
{
// use first segment's angle
const QPointF& nextPt = points[i+1];
if ( pt == nextPt )
continue;
angle = MyLine( pt, nextPt ).angle();
}
else
{
// closed ring: use average angle between first and last segment
const QPointF& prevPt = points[points.count() - 2];
const QPointF& nextPt = points[1];
if ( prevPt == pt || nextPt == pt )
continue;
angle = _averageAngle( prevPt, pt, nextPt );
}
}
else if ( i == points.count() - 1 )
{
if ( !isRing )
{
// use last segment's angle
const QPointF& prevPt = points[i-1];
if ( pt == prevPt )
continue;
angle = MyLine( prevPt, pt ).angle();
}
else
{
// don't draw the last marker - it has been drawn already
continue;
}
}
else
{
// use average angle
const QPointF& prevPt = points[i-1];
const QPointF& nextPt = points[i+1];
if ( prevPt == pt || nextPt == pt )
continue;
angle = _averageAngle( prevPt, pt, nextPt );
}
mMarker->setAngle( origAngle + angle * 180 / M_PI );
}
mMarker->renderPoint( points.at( i ), context.feature(), rc, -1, context.selected() );
}
// restore original rotation
mMarker->setAngle( origAngle );
}
示例3: mouseMoved
void CreateObjectTool::mouseMoved(const QPointF &pos,
Qt::KeyboardModifiers modifiers)
{
AbstractObjectTool::mouseMoved(pos, modifiers);
if (!mNewMapObjectItem)
return;
const MapRenderer *renderer = mapDocument()->renderer();
bool snapToGrid = Preferences::instance()->snapToGrid();
if (modifiers & Qt::ControlModifier)
snapToGrid = !snapToGrid;
switch (mMode) {
case CreateRectangle:
case CreateEllipse: {
const QPointF tileCoords = renderer->pixelToTileCoords(pos);
// Update the size of the new map object
const QPointF objectPos = mNewMapObjectItem->mapObject()->position();
QSizeF newSize(qMax(qreal(0), tileCoords.x() - objectPos.x()),
qMax(qreal(0), tileCoords.y() - objectPos.y()));
if (snapToGrid)
newSize = newSize.toSize();
// Holding shift creates circle or square
if (modifiers & Qt::ShiftModifier) {
qreal max = qMax(newSize.width(), newSize.height());
newSize.setWidth(max);
newSize.setHeight(max);
}
mNewMapObjectItem->resize(newSize);
break;
}
case CreateTile: {
const QSize imgSize = mNewMapObjectItem->mapObject()->tile()->size();
const QPointF diff(-imgSize.width() / 2, imgSize.height() / 2);
QPointF tileCoords = renderer->pixelToTileCoords(pos + diff);
if (snapToGrid)
tileCoords = tileCoords.toPoint();
mNewMapObjectItem->mapObject()->setPosition(tileCoords);
mNewMapObjectItem->syncWithMapObject();
break;
}
case CreatePolygon:
case CreatePolyline: {
QPointF tileCoords = renderer->pixelToTileCoords(pos);
if (snapToGrid)
tileCoords = tileCoords.toPoint();
tileCoords -= mNewMapObjectItem->mapObject()->position();
QPolygonF polygon = mOverlayPolygonObject->polygon();
polygon.last() = tileCoords;
mOverlayPolygonItem->setPolygon(polygon);
break;
}
}
}
示例4: mousePressed
void CreateObjectTool::mousePressed(QGraphicsSceneMouseEvent *event)
{
// Check if we are already creating a new map object
if (mNewMapObjectItem) {
switch (mMode) {
case CreateRectangle:
case CreateTile:
case CreateEllipse:
if (event->button() == Qt::RightButton)
cancelNewMapObject();
break;
case CreatePolygon:
case CreatePolyline:
if (event->button() == Qt::RightButton) {
// The polygon needs to have at least three points and a
// polyline needs at least two.
int min = mMode == CreatePolygon ? 3 : 2;
if (mNewMapObjectItem->mapObject()->polygon().size() >= min)
finishNewMapObject();
else
cancelNewMapObject();
} else if (event->button() == Qt::LeftButton) {
QPolygonF current = mNewMapObjectItem->mapObject()->polygon();
QPolygonF next = mOverlayPolygonObject->polygon();
// If the last position is still the same, ignore the click
if (next.last() == current.last())
return;
// Assign current overlay polygon to the new object
mNewMapObjectItem->setPolygon(next);
// Add a new editable point to the overlay
next.append(next.last());
mOverlayPolygonItem->setPolygon(next);
}
break;
}
return;
}
if (event->button() != Qt::LeftButton) {
AbstractObjectTool::mousePressed(event);
return;
}
ObjectGroup *objectGroup = currentObjectGroup();
if (!objectGroup || !objectGroup->isVisible())
return;
const MapRenderer *renderer = mapDocument()->renderer();
QPointF tileCoords;
if (mMode == CreateTile) {
if (!mTile)
return;
const QPointF diff(-mTile->width() / 2, mTile->height() / 2);
tileCoords = renderer->pixelToTileCoords(event->scenePos() + diff);
} else {
tileCoords = renderer->pixelToTileCoords(event->scenePos());
}
bool snapToGrid = Preferences::instance()->snapToGrid();
if (event->modifiers() & Qt::ControlModifier)
snapToGrid = !snapToGrid;
if (snapToGrid)
tileCoords = tileCoords.toPoint();
startNewMapObject(tileCoords, objectGroup);
}
示例5: drawOverview
void MaGraphOverview::drawOverview(QPainter &p) {
if (displaySettings->orientation == MaGraphOverviewDisplaySettings::FromTopToBottom) {
// transform coordinate system
p.translate( 0, height());
p.scale(1, -1);
}
p.fillRect(cachedConsensus.rect(), Qt::white);
if (editor->getAlignmentLen() == 0) {
return;
}
p.setPen(displaySettings->color);
p.setBrush(displaySettings->color);
if (graphCalculationTaskRunner.getResult().isEmpty() && !editor->isAlignmentEmpty() && !isBlocked) {
sl_drawGraph();
return;
}
QPolygonF resultPolygon = graphCalculationTaskRunner.getResult();
if (!editor->isAlignmentEmpty() && resultPolygon.last().x() != width()) {
sl_drawGraph();
return;
}
// area graph
if (displaySettings->type == MaGraphOverviewDisplaySettings::Area) {
p.drawPolygon( resultPolygon );
}
// line graph
if (displaySettings->type == MaGraphOverviewDisplaySettings::Line) {
p.drawPolyline( resultPolygon );
}
// hystogram
if (displaySettings->type == MaGraphOverviewDisplaySettings::Hystogram) {
int size = graphCalculationTaskRunner.getResult().size();
for (int i = 0; i < size; i++) {
const QPointF point = resultPolygon.at(i);
QPointF nextPoint;
if (i != size - 1) {
nextPoint = resultPolygon.at(i + 1);
} else {
nextPoint = QPointF(width(), point.y());
}
p.drawRect( point.x(), point.y(),
static_cast<int>(nextPoint.x() - point.x()) - 2 * (width() > 2 * size),
height() - point.y());
}
}
// gray frame
p.setPen(Qt::gray);
p.setBrush(Qt::transparent);
p.drawRect( rect().adjusted( 0, (displaySettings->orientation == MaGraphOverviewDisplaySettings::FromTopToBottom),
-1, -1 * (displaySettings->orientation == MaGraphOverviewDisplaySettings::FromBottomToTop)));
}
示例6: clipPolyObject
void ClipPainterPrivate::clipPolyObject ( const QPolygonF & polygon,
QVector<QPolygonF> & clippedPolyObjects,
bool isClosed )
{
// mDebug() << "ClipPainter enabled." ;
// Only create a new polyObject as soon as we know for sure that
// the current point is on the screen.
QPolygonF clippedPolyObject = QPolygonF();
const QVector<QPointF>::const_iterator itStartPoint = polygon.constBegin();
const QVector<QPointF>::const_iterator itEndPoint = polygon.constEnd();
QVector<QPointF>::const_iterator itPoint = itStartPoint;
// We use a while loop to be able to cover linestrings as well as linear rings:
// Linear rings require to tessellate the path from the last node to the first node
// which isn't really convenient to achieve with a for loop ...
bool processingLastNode = false;
while ( itPoint != itEndPoint ) {
m_currentPoint = (*itPoint);
// mDebug() << "m_currentPoint.x()" << m_currentPoint.x() << "m_currentPOint.y()" << m_currentPoint.y();
// Figure out the sector of the current point.
m_currentSector = sector( m_currentPoint );
// Initialize the variables related to the previous point.
if ( itPoint == itStartPoint && processingLastNode == false ) {
if ( isClosed ) {
m_previousPoint = polygon.last();
// Figure out the sector of the previous point.
m_previousSector = sector( m_previousPoint );
}
else {
m_previousSector = m_currentSector;
}
}
// If the current point reaches a new sector, take care of clipping.
if ( m_currentSector != m_previousSector ) {
if ( m_currentSector == 4 || m_previousSector == 4 ) {
// In this case the current or the previous point is visible on the
// screen but not both. Hence we only need to clip once and require
// only one interpolation for both cases.
clipOnce( clippedPolyObject, clippedPolyObjects, isClosed );
}
else {
// This case mostly deals with lines that reach from one
// sector that is located off screen to another one that
// is located off screen. In this situation the line
// can get clipped once, twice, or not at all.
clipMultiple( clippedPolyObject, clippedPolyObjects, isClosed );
}
m_previousSector = m_currentSector;
}
// If the current point is onscreen, just add it to our final polygon.
if ( m_currentSector == 4 ) {
clippedPolyObject << m_currentPoint;
#ifdef MARBLE_DEBUG
++(m_debugNodeCount);
#endif
}
m_previousPoint = m_currentPoint;
// Now let's handle the case where we have a (closed) polygon and where the
// last point of the polyline is outside the viewport and the start point
// is inside the viewport. This needs special treatment
if ( processingLastNode ) {
break;
}
++itPoint;
if ( itPoint == itEndPoint && isClosed ) {
itPoint = itStartPoint;
processingLastNode = true;
}
}
// Only add the pointer if there's node data available.
if ( !clippedPolyObject.isEmpty() ) {
clippedPolyObjects << clippedPolyObject;
}
}
示例7: if
void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context, Placement placement )
{
if ( points.isEmpty() )
return;
QgsRenderContext& rc = context.renderContext();
double origAngle = mMarker->angle();
int i, maxCount;
bool isRing = false;
double offsetAlongLine = mOffsetAlongLine;
QgsExpression* offsetAlongLineExpression = expression( "offset_along_line" );
if ( offsetAlongLineExpression )
{
offsetAlongLine = offsetAlongLineExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
}
if ( offsetAlongLine != 0 )
{
//scale offset along line
offsetAlongLine *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( rc, mOffsetAlongLineUnit, mOffsetAlongLineMapUnitScale );
}
if ( placement == FirstVertex )
{
i = 0;
maxCount = 1;
}
else if ( placement == LastVertex )
{
i = points.count() - 1;
maxCount = points.count();
}
else
{
i = 0;
maxCount = points.count();
if ( points.first() == points.last() )
isRing = true;
}
if ( offsetAlongLine > 0 && ( placement == FirstVertex || placement == LastVertex ) )
{
double distance;
distance = placement == FirstVertex ? offsetAlongLine : -offsetAlongLine;
renderOffsetVertexAlongLine( points, i, distance, context );
// restore original rotation
mMarker->setAngle( origAngle );
return;
}
for ( ; i < maxCount; ++i )
{
if ( isRing && placement == Vertex && i == points.count() - 1 )
{
continue; // don't draw the last marker - it has been drawn already
}
// rotate marker (if desired)
if ( mRotateMarker )
{
double angle = markerAngle( points, isRing, i );
mMarker->setAngle( origAngle + angle * 180 / M_PI );
}
mMarker->renderPoint( points.at( i ), context.feature(), rc, -1, context.selected() );
}
// restore original rotation
mMarker->setAngle( origAngle );
}
示例8: if
void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context, Placement placement )
{
if ( points.isEmpty() )
return;
QgsRenderContext& rc = context.renderContext();
double origAngle = mMarker->angle();
int i, maxCount;
bool isRing = false;
double offsetAlongLine = mOffsetAlongLine;
if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET_ALONG_LINE ) )
{
context.setOriginalValueVariable( mOffsetAlongLine );
offsetAlongLine = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET_ALONG_LINE, context, mOffsetAlongLine ).toDouble();
}
if ( offsetAlongLine != 0 )
{
//scale offset along line
offsetAlongLine = QgsSymbolLayerV2Utils::convertToPainterUnits( rc, offsetAlongLine, mOffsetAlongLineUnit, mOffsetAlongLineMapUnitScale );
}
if ( offsetAlongLine == 0 && context.renderContext().geometry()
&& context.renderContext().geometry()->hasCurvedSegments() && ( placement == Vertex || placement == CurvePoint ) )
{
const QgsCoordinateTransform* ct = context.renderContext().coordinateTransform();
const QgsMapToPixel& mtp = context.renderContext().mapToPixel();
QgsVertexId vId;
QgsPointV2 vPoint;
double x, y, z;
QPointF mapPoint;
while ( context.renderContext().geometry()->nextVertex( vId, vPoint ) )
{
if (( placement == Vertex && vId.type == QgsVertexId::SegmentVertex )
|| ( placement == CurvePoint && vId.type == QgsVertexId::CurveVertex ) )
{
//transform
x = vPoint.x(), y = vPoint.y(); z = vPoint.z();
if ( ct )
{
ct->transformInPlace( x, y, z );
}
mapPoint.setX( x ); mapPoint.setY( y );
mtp.transformInPlace( mapPoint.rx(), mapPoint.ry() );
if ( mRotateMarker )
{
double angle = context.renderContext().geometry()->vertexAngle( vId );
mMarker->setAngle( angle * 180 / M_PI );
}
mMarker->renderPoint( mapPoint, context.feature(), rc, -1, context.selected() );
}
}
return;
}
if ( placement == FirstVertex )
{
i = 0;
maxCount = 1;
}
else if ( placement == LastVertex )
{
i = points.count() - 1;
maxCount = points.count();
}
else if ( placement == Vertex )
{
i = 0;
maxCount = points.count();
if ( points.first() == points.last() )
isRing = true;
}
else
{
return;
}
if ( offsetAlongLine > 0 && ( placement == FirstVertex || placement == LastVertex ) )
{
double distance;
distance = placement == FirstVertex ? offsetAlongLine : -offsetAlongLine;
renderOffsetVertexAlongLine( points, i, distance, context );
// restore original rotation
mMarker->setAngle( origAngle );
return;
}
for ( ; i < maxCount; ++i )
{
if ( isRing && placement == Vertex && i == points.count() - 1 )
{
continue; // don't draw the last marker - it has been drawn already
}
// rotate marker (if desired)
if ( mRotateMarker )
{
double angle = markerAngle( points, isRing, i );
mMarker->setAngle( origAngle + angle * 180 / M_PI );
//.........这里部分代码省略.........
示例9: digitalPattern_Rotate
bool DataConverter::digitalPattern_Rotate(QPolygonF &points, qreal angle)
{
if (angle == 0.0)
return true;
if (angle < -180.0 || angle > 180.0)
{
qDebug("[DataConverter::digitalPattern_Rotate] Error: Angle: [%f]", angle);
return false;
}
if (points.size() < 10)
{
qDebug("[DataConverter::digitalPattern_Rotate] Error: Polygon Point Count: [%d]", points.size());
return false;
}
//
QTransform transform;
transform.rotate(angle);
points = transform.map(points);
//
int bottomIndex = 0;
{
qreal tmpX = -9999.99;
for (int i = 0; i < points.size(); i++)
{
if (points.at(i).y() < 0.0)
continue;
if (points.at(i).x() > 0.0)
continue;
if (points.at(i).x() > tmpX)
{
tmpX = points.at(i).x();
bottomIndex = i;
}
}
}
qDebug("** bottomIndex: [%d]", bottomIndex);
if (bottomIndex > 0)
{
QPointF tmpPoint;
for (int i = points.size() - 1; i >= bottomIndex; i--)
{
tmpPoint = points.last();
points.pop_back();
points.push_front(tmpPoint);
}
}
return true;
}
示例10: mouseMoved
void CreateObjectTool::mouseMoved(const QPointF &pos,
Qt::KeyboardModifiers modifiers)
{
AbstractObjectTool::mouseMoved(pos, modifiers);
if (!mNewMapObjectItem)
return;
const MapRenderer *renderer = mapDocument()->renderer();
bool snapToGrid = Preferences::instance()->snapToGrid();
bool snapToFineGrid = Preferences::instance()->snapToFineGrid();
if (modifiers & Qt::ControlModifier) {
snapToGrid = !snapToGrid;
snapToFineGrid = false;
}
switch (mMode) {
case CreateRectangle:
case CreateEllipse: {
const QPointF pixelCoords = renderer->screenToPixelCoords(pos);
// Update the size of the new map object
const QPointF objectPos = mNewMapObjectItem->mapObject()->position();
QPointF newSize(qMax(qreal(0), pixelCoords.x() - objectPos.x()),
qMax(qreal(0), pixelCoords.y() - objectPos.y()));
QPointF newTileSize = renderer->pixelToTileCoords(newSize);
if (snapToFineGrid) {
int gridFine = Preferences::instance()->gridFine();
newTileSize = (newTileSize * gridFine).toPoint();
newTileSize /= gridFine;
} else if (snapToGrid)
newTileSize = newTileSize.toPoint();
// Holding shift creates circle or square
if (modifiers & Qt::ShiftModifier) {
qreal max = qMax(newTileSize.x(), newTileSize.y());
newTileSize.setX(max);
newTileSize.setY(max);
}
newSize = renderer->tileToPixelCoords(newTileSize);
mNewMapObjectItem->resizeObject(QSizeF(newSize.x(), newSize.y()));
break;
}
case CreateTile: {
const QSize imgSize = mNewMapObjectItem->mapObject()->cell().tile->size();
const QPointF diff(-imgSize.width() / 2, imgSize.height() / 2);
QPointF tileCoords = renderer->screenToTileCoords(pos + diff);
if (snapToFineGrid) {
int gridFine = Preferences::instance()->gridFine();
tileCoords = (tileCoords * gridFine).toPoint();
tileCoords /= gridFine;
} else if (snapToGrid)
tileCoords = tileCoords.toPoint();
QPointF pixelCoords = renderer->tileToPixelCoords(tileCoords);
mNewMapObjectItem->mapObject()->setPosition(pixelCoords);
mNewMapObjectItem->syncWithMapObject();
mNewMapObjectItem->setZValue(10000); // sync may change it
break;
}
case CreatePolygon:
case CreatePolyline: {
QPointF tileCoords = renderer->screenToTileCoords(pos);
if (snapToFineGrid) {
int gridFine = Preferences::instance()->gridFine();
tileCoords = (tileCoords * gridFine).toPoint();
tileCoords /= gridFine;
} else if (snapToGrid)
tileCoords = tileCoords.toPoint();
QPointF pixelCoords = renderer->tileToPixelCoords(tileCoords);
pixelCoords -= mNewMapObjectItem->mapObject()->position();
QPolygonF polygon = mOverlayPolygonObject->polygon();
polygon.last() = pixelCoords;
mOverlayPolygonItem->setPolygon(polygon);
break;
}
}
}
示例11: clipPolyline
void _PolyClipper::clipPolyline(const QPolygonF& poly)
{
// exit if fewer than 2 points in polygon
if ( poly.size() < 2 )
return;
// output goes here
QPolygonF pout;
QPolygonF::const_iterator polyiter = poly.begin();
QPointF lastpt = *polyiter;
polyiter++;
for( ; polyiter != poly.end(); ++polyiter )
{
QPointF p1 = lastpt;
QPointF p2 = *polyiter;
bool plotline = _clipper.clipLine(p1, p2);
if( plotline )
{
if( pout.isEmpty() )
{
// add first line
pout << p1;
if( ! smallDelta(p1, p2) )
pout << p2;
}
else
{
if( p1 == pout.last() )
{
if( ! smallDelta(p1, p2) )
// extend polyline
pout << p2;
}
else
{
// paint existing line
if( pout.size() >= 2 )
emitPolyline(pout);
// start new line
pout.clear();
pout << p1;
if( ! smallDelta(p1, p2) )
pout << p2;
}
}
}
else
{
// line isn't in region, so ignore results from clip function
// paint existing line
if( pout.size() >= 2 )
emitPolyline(pout);
// cleanup
pout.clear();
}
lastpt = *polyiter;
}
if( pout.size() >= 2 )
emitPolyline(pout);
}
示例12: assertPolygonIsClosed
void assertPolygonIsClosed(QPolygonF polygon)
{
ASSERT_RETURN(polygon.isEmpty() || polygon.first() == polygon.last());
}
示例13: shiftPolygonSimple
QPolygonF minigis::shiftPolygonSimple(const QPolygonF &origin, qreal delta, bool closed)
{
QPolygonF path = origin;
QPolygonF norm;
// ----------------- Поиск нормалей к оригинальному полигону
int N = path.size();
for (int i = 1; i < N; ++i) {
QPointF vect = path.at(i) - path.at(i-1);
double len = lengthR2(vect);
if (qFuzzyIsNull(len)) {
path.remove(i);
--N;
--i;
continue;
}
vect /= len;
norm.append(QPointF(vect.y() * delta, -vect.x() * delta));
}
// ----
if (closed) {
QPointF vect = path.first() - path.last();
double len = lengthR2(vect);
if (qFuzzyIsNull(len))
path.remove(path.size() - 1);
else {
vect /= len;
norm.append(QPointF(vect.y() * delta, -vect.x() * delta));
}
}
// ------------------
QVector<QLineF> lines;
// -------------------------- Построение смещенных линий
for (int i = 1; i < path.size(); ++i)
lines.append(QLineF(path.at(i) + norm.at(i-1), path.at(i-1) + norm.at(i-1)));
// ----
if (closed)
lines.append(QLineF(path.first() + norm.last(), path.last() + norm.last()));
// ------------------
QPolygonF shell;
if (lines.isEmpty())
return shell;
// -------------------------- Построение смещенного полигона
N = lines.size();
for (int i = 1; i < N; ++i) {
QPointF tmp;
QLineF::IntersectType type = lines.at(i-1).intersect(lines.at(i), &tmp);
double ang = lines.at(i-1).angleTo(lines.at(i));
if (type != QLineF::NoIntersection)
shell.append(tmp);
else {
if (qFuzzyCompare(ang, 180.))
shell.append(lines.at(i).p2() - 2 * norm.at(i));
shell.append(lines.at(i).p2());
}
}
// ----
if (closed) {
QPointF tmp;
QLineF::IntersectType type = lines.last().intersect(lines.first(), &tmp);
double ang = lines.last().angleTo(lines.first());
if (type != QLineF::NoIntersection)
shell.append(tmp);
else {
if (qFuzzyCompare(ang, 180.))
shell.append(lines.first().p2() - 2 * norm.first());
shell.append(lines.first().p2());
}
shell.append(shell.first());
}
else {
shell.prepend(lines.first().p2());
shell.append(lines.last().p1());
}
// ------------------
return shell;
}
示例14: shiftPolygonDifficult
QPolygonF minigis::shiftPolygonDifficult(const QPolygonF &origin, qreal delta, bool closed)
{
if (qFuzzyIsNull(delta))
return origin;
QPolygonF path = origin;
QPolygonF norm;
// ----------------- Поиск нормалей к оригинальному полигону
int N = path.size();
for (int i = 1; i < N; ++i) {
QPointF vect = path.at(i) - path.at(i-1);
double len = lengthR2(vect);
if (qFuzzyIsNull(len)) {
path.remove(i);
--N;
--i;
continue;
}
vect /= len;
norm.append(QPointF(vect.y() * delta, -vect.x() * delta));
}
// ----
if (closed) {
QPointF vect = path.first() - path.last();
double len = lengthR2(vect);
if (qFuzzyIsNull(len))
path.remove(path.size() - 1);
else {
vect /= len;
norm.append(QPointF(vect.y() * delta, -vect.x() * delta));
}
}
// ------------------
QVector<QLineF> lines;
// -------------------------- Построение смещенных линий
for (int i = 1; i < path.size(); ++i)
lines.append(QLineF(path.at(i) + norm.at(i-1), path.at(i-1) + norm.at(i-1)));
// ----
if (closed)
lines.append(QLineF(path.first() + norm.last(), path.last() + norm.last()));
// ------------------
QPolygonF shell;
if (lines.isEmpty())
return shell;
// -------------------------- Построение смещенного полигона
N = lines.size();
for (int i = 1; i < N; ++i) {
QPointF tmp;
QLineF::IntersectType type = lines.at(i-1).intersect(lines.at(i), &tmp);
qreal ang = lines.at(i-1).angleTo(lines.at(i));
if (type != QLineF::NoIntersection)
shell.append(tmp);
else {
if (qFuzzyCompare(ang, qreal(180)))
shell.append(lines.at(i).p2() - 2 * norm.at(i));
shell.append(lines.at(i).p2());
}
}
// ----
if (closed) {
QPointF tmp;
QLineF::IntersectType type = lines.last().intersect(lines.first(), &tmp);
qreal ang = lines.last().angleTo(lines.first());
if (type != QLineF::NoIntersection)
shell.append(tmp);
else {
if (qFuzzyCompare(ang, qreal(180)))
shell.append(lines.first().p2() - 2 * norm.first());
shell.append(lines.first().p2());
}
shell.append(shell.first());
}
else {
shell.prepend(lines.first().p2());
shell.append(lines.last().p1());
}
// ------------------
// -------------------------- обрезание острых углов
int k = 0;
N = lines.size();
for (int i = 1; i < N; ++i) {
double ang = lines.at(i-1).angleTo(lines.at(i));
bool first = (120 < ang && ang < 180 && delta < 0) || (180 < ang && ang < 240 && delta > 0);
bool second = (120 < ang && ang < 180 && delta > 0) || (180 < ang && ang < 240 && delta < 0);
if (first) {
int num = closed ? 1 : 0;
QPointF v = shell.at(i + k - num) - path.at(i);
v /= lengthR2(v);
QPointF start = path.at(i) + v * qAbs(delta);
QLineF tmp(start, start + QPointF(-v.y(), v.x()));
QPointF a;
if (tmp.intersect(lines.at(i ), &a) != QLineF::NoIntersection)
shell.replace(i + k - num, a);
if (tmp.intersect(lines.at(i-1), &a) != QLineF::NoIntersection)
//.........这里部分代码省略.........
示例15: reducePoints
/**
* Try to reduce the point size of a polyline.
*
* \param range Corridor beside the course line in meters.
*
* \param mwList list of polylines to be processed.
*
* \return list with reduced polylines.
*/
QList<QPolygonF> reducePoints( const double range,
QList<QPolygonF>& mwList,
const bool verbose )
{
QPointF startP;
QPointF lastP;
double startBearing;
QList<QPolygonF> retList;
QList<QPointF> ignoreList;
int sum = 0;
for( int i = 0; i < mwList.size(); i++ )
{
const QPolygonF& plIn = mwList.at(i);
QPolygonF plOut;
for( int j = 0; j < plIn.size(); j++ )
{
const QPointF& p = plIn.at(j);
if( j == 0 )
{
// Set start point for filtering
startP = p;
plOut.append(p);
continue;
}
if( j == 1 )
{
startBearing = getBearingWgs( startP, p );
lastP = p;
continue;
}
// calculate bearing from start point
double bearing = getBearingWgs( startP, p );
// calculate distance from start point
double dist = distP(startP.x(), startP.y(), p.x(), p.y());
// calculate sector angle from start point.
const double delta = atan( range / dist );
if( fabs( startBearing - bearing ) < delta )
{
// Ignore point, it is laying inside the corridor.
ignoreList.append(p);
lastP = p;
continue;
}
#if 0
printf( "j=%d, Start=%.1f, Entf=%.0f, Kurs=%.1f, Winkel=%.1f, Diff=%.1f°\n",
j, startBearing, dist, bearing, delta,
fabs( startBearing - bearing) * 180.0 / M_PI );
#endif
// Add points from the ignore list to get a better turn
int start = ignoreList.size() - 2;
if( start < 0 )
{
start = 0;
}
if( start < ignoreList.size() )
{
// qDebug() << "IgnoreList" << ignoreList.size() << "is used";
}
for( int k=start; k < ignoreList.size(); k++ )
{
// plOut.append( ignoreList.at(k) );
}
ignoreList.clear();
startBearing = bearing;
plOut.append(lastP);
startP = lastP;
lastP = p;
}
if( plOut.size() > 0 && lastP != plOut.last() )
{
// Add last start point to the segment list.
plOut.append(lastP);
}
if( plOut.size() < 2 )
//.........这里部分代码省略.........