void LineItem::creationPolygonChanged(View::CreationEvent event) { if (event == View::MousePress) { const QPolygonF poly = mapFromScene(parentView()->creationPolygon(View::MousePress)); setPos(poly.first().x(), poly.first().y()); setViewRect(QRectF(0.0, 0.0, 0.0, sizeOfGrip().height())); parentView()->scene()->addItem(this); //setZValue(1); return; } if (event == View::MouseMove) { const QPolygonF poly = mapFromScene(parentView()->creationPolygon(View::MouseMove)); if (!rect().isEmpty()) { rotateTowards(line().p2(), poly.last()); } QRectF r = rect(); r.setSize(QSizeF(QLineF(line().p1(), poly.last()).length(), r.height())); setViewRect(r); return; } if (event == View::MouseRelease) { const QPolygonF poly = mapFromScene(parentView()->creationPolygon(View::MouseRelease)); parentView()->disconnect(this, SLOT(deleteLater())); //Don't delete ourself parentView()->disconnect(this, SLOT(creationPolygonChanged(View::CreationEvent))); parentView()->setMouseMode(View::Default); maybeReparent(); emit creationComplete(); return; } }
void LineHandler::adjust() { QPolygonF line = mEdge->line(); NodeElement *src = mEdge->src(); NodeElement *dst = mEdge->dst(); if (src && src->isSelected() && dst && dst->isSelected() && !mEdge->isLoop()) { QPointF offset = mEdge->mapFromItem(src, src->portPos(mEdge->fromPort())) - line.first(); mEdge->setPos(mEdge->pos() + offset); return; } if (src) { line.first() = mEdge->mapFromItem(src, src->portPos(mEdge->fromPort())); } if (dst) { line.last() = mEdge->mapFromItem(dst, dst->portPos(mEdge->toPort())); } mEdge->setLine(line); if (mEdge->isLoop()) { mEdge->createLoopEdge(); } }
void ClipPainterPrivate::labelPosition(const QPolygonF &polygon, QVector<QPointF> &labelNodes, LabelPositionFlags labelPositionFlags) const { if ( labelPositionFlags.testFlag( LineCenter ) ) { // The Label at the center of the polyline: if ( polygon.size() > 0 ) { const int labelPosition = polygon.size() / 2; // implied: 0 <= labelPosition < polygon.size() labelNodes << polygon.at( labelPosition ); } } if ( polygon.size() > 0 && labelPositionFlags.testFlag( LineStart ) ) { if ( pointAllowsLabel( polygon.first() ) ) { labelNodes << polygon.first(); } // The Label at the start of the polyline: for ( int it = 1; it < polygon.size(); ++it ) { const bool currentAllowsLabel = pointAllowsLabel(polygon.at(it)); if ( currentAllowsLabel ) { // As polygon.size() > 0 it's ensured that it-1 exists. QPointF node = interpolateLabelPoint( polygon.at( it -1 ), polygon.at( it ), labelPositionFlags ); if ( node != QPointF( -1.0, -1.0 ) ) { labelNodes << node; } break; } } } if ( polygon.size() > 1 && labelPositionFlags.testFlag( LineEnd ) ) { if ( pointAllowsLabel( polygon.at( polygon.size() - 1 ) ) ) { labelNodes << polygon.at( polygon.size() - 1 ); } // The Label at the end of the polyline: for ( int it = polygon.size() - 2; it > 0; --it ) { const bool currentAllowsLabel = pointAllowsLabel(polygon.at(it)); if ( currentAllowsLabel ) { QPointF node = interpolateLabelPoint( polygon.at( it + 1 ), polygon.at( it ), labelPositionFlags ); if ( node != QPointF( -1.0, -1.0 ) ) { labelNodes << node; } break; } } } }
void SMDItem::createItem(QGraphicsItemGroup* inOutItem, bool inIsMainNotGround) { auto main = new QGraphicsPolygonItem; QPolygonF poly; for (auto point : mComponent->rect().points) { poly << QPointF(point.x, - point.y); } poly << poly.first(); main->setPolygon(poly); QColor color = inIsMainNotGround ? gSettings().layerColor(mComponent->layer()) : gSettings().backgroundColor(); QBrush br(color); main->setBrush(br); QPen p(color); if (!inIsMainNotGround) { p.setColor(color); p.setWidthF(mComponent->groundPlaneDistance() * 2); p.setJoinStyle(Qt::MiterJoin); } main->setPen(p); inOutItem->addToGroup(main); }
void DiveCalculatedCeiling::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { // We don't have enougth data to calculate things, quit. if (!shouldCalculateStuff(topLeft, bottomRight)) return; AbstractProfilePolygonItem::modelDataChanged(topLeft, bottomRight); // Add 2 points to close the polygon. QPolygonF poly = polygon(); if (poly.isEmpty()) return; QPointF p1 = poly.first(); QPointF p2 = poly.last(); poly.prepend(QPointF(p1.x(), vAxis->posAtValue(0))); poly.append(QPointF(p2.x(), vAxis->posAtValue(0))); setPolygon(poly); QLinearGradient pat(0, polygon().boundingRect().top(), 0, polygon().boundingRect().bottom()); pat.setColorAt(0, getColor(CALC_CEILING_SHALLOW)); pat.setColorAt(1, getColor(CALC_CEILING_DEEP)); setPen(QPen(QBrush(Qt::NoBrush), 0)); setBrush(pat); gradientFactor->setX(poly.boundingRect().width() / 2 + poly.boundingRect().x()); DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance(); if (plannerModel->isPlanner()) { struct diveplan &diveplan = plannerModel->getDiveplan(); gradientFactor->setText(QString("GF %1/%2").arg(diveplan.gflow).arg(diveplan.gfhigh)); } else { gradientFactor->setText(QString("GF %1/%2").arg(prefs.gflow).arg(prefs.gfhigh)); } }
void QgsMarkerLineSymbolLayerV2::renderOffsetVertexAlongLine( const QPolygonF &points, int vertex, double distance, QgsSymbolV2RenderContext& context ) { if ( points.isEmpty() ) return; QgsRenderContext& rc = context.renderContext(); double origAngle = mMarker->angle(); if ( distance == 0 ) { // rotate marker (if desired) if ( mRotateMarker ) { bool isRing = false; if ( points.first() == points.last() ) isRing = true; double angle = markerAngle( points, isRing, vertex ); mMarker->setAngle( origAngle + angle * 180 / M_PI ); } mMarker->renderPoint( points[vertex], context.feature(), rc, -1, context.selected() ); return; } int pointIncrement = distance > 0 ? 1 : -1; QPointF previousPoint = points[vertex]; int startPoint = distance > 0 ? qMin( vertex + 1, points.count() - 1 ) : qMax( vertex - 1, 0 ); int endPoint = distance > 0 ? points.count() - 1 : 0; double distanceLeft = qAbs( distance ); for ( int i = startPoint; pointIncrement > 0 ? i <= endPoint : i >= endPoint; i += pointIncrement ) { const QPointF& pt = points[i]; if ( previousPoint == pt ) // must not be equal! continue; // create line segment MyLine l( previousPoint, pt ); if ( distanceLeft < l.length() ) { //destination point is in current segment QPointF markerPoint = previousPoint + l.diffForInterval( distanceLeft ); // rotate marker (if desired) if ( mRotateMarker ) { mMarker->setAngle( origAngle + ( l.angle() * 180 / M_PI ) ); } mMarker->renderPoint( markerPoint, context.feature(), rc, -1, context.selected() ); return; } distanceLeft -= l.length(); previousPoint = pt; } //didn't find point return; }
//! [4] void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { if (myStartItem->collidesWithItem(myEndItem)) return; QPen myPen = pen(); myPen.setColor(myColor); qreal arrowSize = 20; painter->setPen(myPen); painter->setBrush(myColor); //! [4] //! [5] QLineF centerLine(myStartItem->pos(), myEndItem->pos()); QPolygonF endPolygon = myEndItem->polygon(); QPointF p1 = endPolygon.first() + myEndItem->pos(); QPointF p2; QPointF intersectPoint; QLineF polyLine; for (int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i) + myEndItem->pos(); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &intersectPoint); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } setLine(QLineF(intersectPoint, myStartItem->pos())); //! [5] //! [6] double angle = ::acos(line().dx() / line().length()); if (line().dy() >= 0) angle = (Pi * 2) - angle; QPointF arrowP1 = line().p1() + QPointF(sin(angle + Pi / 3) * arrowSize, cos(angle + Pi / 3) * arrowSize); QPointF arrowP2 = line().p1() + QPointF(sin(angle + Pi - Pi / 3) * arrowSize, cos(angle + Pi - Pi / 3) * arrowSize); arrowHead.clear(); arrowHead << line().p1() << arrowP1 << arrowP2; //! [6] //! [7] painter->drawLine(line()); painter->drawPolygon(arrowHead); if (isSelected()) { painter->setPen(QPen(myColor, 1, Qt::DashLine)); QLineF myLine = line(); myLine.translate(0, 4.0); painter->drawLine(myLine); myLine.translate(0,-8.0); painter->drawLine(myLine); } }
/*! \brief Complete a polygon to be a closed polygon including the area between the original polygon and the baseline. \param painter Painter \param xMap X map \param yMap Y map \param polygon Polygon to be completed */ void QwtPlotCurve::closePolyline( QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, QPolygonF &polygon ) const { if ( polygon.size() < 2 ) return; const bool doAlign = QwtPainter::roundingAlignment( painter ); double baseline = d_data->baseline; if ( orientation() == Qt::Vertical ) { if ( yMap.transformation()->type() == QwtScaleTransformation::Log10 ) { if ( baseline < QwtScaleMap::LogMin ) baseline = QwtScaleMap::LogMin; } double refY = yMap.transform( baseline ); if ( doAlign ) refY = qRound( refY ); polygon += QPointF( polygon.last().x(), refY ); polygon += QPointF( polygon.first().x(), refY ); } else { if ( xMap.transformation()->type() == QwtScaleTransformation::Log10 ) { if ( baseline < QwtScaleMap::LogMin ) baseline = QwtScaleMap::LogMin; } double refX = xMap.transform( baseline ); if ( doAlign ) refX = qRound( refX ); polygon += QPointF( refX, polygon.last().y() ); polygon += QPointF( refX, polygon.first().y() ); } }
//! Internal, used by the Outline style. void QwtPlotHistogram::flushPolygon( QPainter *painter, double baseLine, QPolygonF &polygon ) const { if ( polygon.size() == 0 ) return; if ( orientation() == Qt::Horizontal ) polygon += QPointF( baseLine, polygon.last().y() ); else polygon += QPointF( polygon.last().x(), baseLine ); if ( d_data->brush.style() != Qt::NoBrush ) { painter->setPen( Qt::NoPen ); painter->setBrush( d_data->brush ); if ( orientation() == Qt::Horizontal ) { polygon += QPointF( polygon.last().x(), baseLine ); polygon += QPointF( polygon.first().x(), baseLine ); } else { polygon += QPointF( baseLine, polygon.last().y() ); polygon += QPointF( baseLine, polygon.first().y() ); } QwtPainter::drawPolygon( painter, polygon ); int resize = polygon.size(); if ( resize > 1 ) resize -= 2; polygon.resize( resize ); } if ( d_data->pen.style() != Qt::NoPen ) { painter->setBrush( Qt::NoBrush ); painter->setPen( d_data->pen ); QwtPainter::drawPolyline( painter, polygon ); } polygon.clear(); }
void CircleItem::creationPolygonChanged(View::CreationEvent event) { if (event == View::EscapeEvent) { ViewItem::creationPolygonChanged(event); return; } if (event == View::MousePress) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MousePress)); setPos(poly.first().x(), poly.first().y()); setViewRect(QRectF(0.0, 0.0, 0.0, sizeOfGrip().height())); setRect(-2,-2,4,4); view()->scene()->addItem(this); return; } if (event == View::MouseMove) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MouseMove)); qreal dx = poly.last().x(); qreal dy = poly.last().y(); qreal r = qMax(qreal(2.0),sqrt(dx*dx + dy*dy)); QRectF newRect(-r, -r, 2.0*r, 2.0*r); setViewRect(newRect); return; } if (event == View::MouseRelease) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MouseRelease)); view()->disconnect(this, SLOT(deleteLater())); //Don't delete ourself view()->disconnect(this, SLOT(creationPolygonChanged(View::CreationEvent))); view()->setMouseMode(View::Default); updateViewItemParent(); emit creationComplete(); return; } }
void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { if(!myStartItem || !myEndItem) { return; } if(myEndItem->sceneBoundingRect().contains(p1())) { return; } QPen myPen = pen(); myPen.setColor(myColor); qreal arrowSize = 5; painter->setPen(myPen); painter->setBrush(myColor); QLineF centerLine(p1(), p2()); QPolygonF endPolygon = myEndItem->mapToScene(myEndItem->shape()).toFillPolygon(); QPointF p1 = endPolygon.first(); QPointF p2; QPointF intersectPoint; QLineF polyLine; for (int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &intersectPoint); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } setLine(QLineF(intersectPoint, this->p1())); double angle = ::acos(line().dx() / line().length()); if (line().dy() >= 0) angle = (Pi * 2) - angle; QPointF arrowP1 = line().p1() + QPointF(sin(angle + Pi / 3) * arrowSize, cos(angle + Pi / 3) * arrowSize); QPointF arrowP2 = line().p1() + QPointF(sin(angle + Pi - Pi / 3) * arrowSize, cos(angle + Pi - Pi / 3) * arrowSize); arrowHead.clear(); arrowHead << line().p1() << arrowP1 << arrowP2; painter->drawLine(line()); painter->drawPolygon(arrowHead); }
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; 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 ) { 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 ); }
qreal PathSorter::getDistance(const QPolygonF &p1, const QPolygonF &p2) { qreal testx1 = p1.last().x(); qreal testy1 = p1.last().y(); qreal testx2 = p2.first().x(); qreal testy2 = p2.first().y(); qreal a = 0.0; qreal b = 0.0; double c = 0.0; if(testx1 >= testx2) a = testx1 - testx2; else a = testx2 - testx1; if(testy1 >= testy2) b = testy1 - testy2; else b = testy2 - testy1; c = sqrt((double)(a*a+b*b)); return (qreal) c; }
QPolygonF QwtSplineC1::polygonX( int numPoints, const QPolygonF &points ) const { if ( points.size() <= 2 ) return points; QPolygonF fittedPoints; const QVector<double> m = slopesX( points ); if ( m.size() != points.size() ) return fittedPoints; const QPointF *p = points.constData(); const double *s = m.constData(); const double x1 = points.first().x(); const double x2 = points.last().x(); const double delta = ( x2 - x1 ) / ( numPoints - 1 ); double x0, y0; QwtSplinePolynom polynom; for ( int i = 0, j = 0; i < numPoints; i++ ) { double x = x1 + i * delta; if ( x > x2 ) x = x2; if ( i == 0 || x > p[j + 1].x() ) { while ( x > p[j + 1].x() ) j++; polynom = QwtSplinePolynom::fromSlopes( p[j], s[j], p[j + 1], s[j + 1] ); x0 = p[j].x(); y0 = p[j].y(); } const double y = y0 + polynom.value( x - x0 ); fittedPoints += QPointF( x, y ); } return fittedPoints; }
QLineF::IntersectType getIntersection (const QLineF& l, const QPolygonF& p, QPointF* intersectPoint) { QPointF p1 = p.first(); QPointF p2; QLineF polyLine; for ( int i = 1; i < p.count(); ++i) { p2 = p.at(i); polyLine = QLineF( p1, p2); QLineF::IntersectType intersectType = polyLine.intersect( l, intersectPoint); if ( intersectType == QLineF::BoundedIntersection) { return QLineF::BoundedIntersection; } p1 = p2; } return QLineF::NoIntersection; }
void QgsNodeEditor::zoomToNode( int idx ) { double x = mSelectedFeature->vertexMap().at( idx )->point().x(); double y = mSelectedFeature->vertexMap().at( idx )->point().y(); QgsPoint newCenter( x, y ); QgsCoordinateTransform t( mLayer->crs(), mCanvas->mapSettings().destinationCrs() ); QgsPoint tCenter = t.transform( newCenter ); QPolygonF ext = mCanvas->mapSettings().visiblePolygon(); //close polygon ext.append( ext.first() ); QgsGeometry extGeom( QgsGeometry::fromQPolygonF( ext ) ); QgsGeometry nodeGeom( QgsGeometry::fromPoint( tCenter ) ); if ( !nodeGeom.within( extGeom ) ) { mCanvas->setCenter( tCenter ); mCanvas->refresh(); } }
QPolygonF polygonFromPath(potrace_path_t *path, int bezierPrecision) { QPolygonF poly; if(!path) return poly; int n = path->curve.n; int *tag = path->curve.tag; potrace_dpoint_t (*c)[3] = path->curve.c; for(int i = 0; i < n; ++i) { switch (tag[i]) { case POTRACE_CORNER: poly << QPointF(c[i][1].x, c[i][1].y) << QPointF(c[i][2].x, c[i][2].y); break; case POTRACE_CURVETO: { QPointF pa, pb, pc, pd; pa = poly.isEmpty()? QPointF(c[n-1][2].x, c[n-1][2].y) : poly.last(); pb = QPointF(c[i][0].x, c[i][0].y); pc = QPointF(c[i][1].x, c[i][1].y); pd = QPointF(c[i][2].x, c[i][2].y); for(int i = 1; i <= bezierPrecision; ++i) { poly << bezier(pa, pb, pc, pd, static_cast<qreal>(i)/bezierPrecision); } } break; } } if(!poly.isEmpty() && poly.first() == poly.last()) { poly.remove(poly.size()-1); } return poly; }
QPolygonF Shape::polygon() const { QPolygonF result = vertices_; switch (type_) { case SEGMENT: case POLYLINE: break; case CLOSED_POLYLINE: case POLYGON: result.append(result.first()); break; case RECTANGLE: if (result.size() == 2) result = QPolygonF(QRectF(result[0], result[1])); break; } return result; }
static PyObject *meth_QPolygonF_first(PyObject *sipSelf, PyObject *sipArgs) { PyObject *sipParseErr = NULL; { QPolygonF *sipCpp; if (sipParseArgs(&sipParseErr, sipArgs, "B", &sipSelf, sipType_QPolygonF, &sipCpp)) { QPointF*sipRes; sipRes = &sipCpp->first(); return sipConvertFromType(sipRes,sipType_QPointF,NULL); } } /* Raise an exception if the arguments couldn't be parsed. */ sipNoMethod(sipParseErr, sipName_QPolygonF, sipName_first, doc_QPolygonF_first); return NULL; }
void testDuplicates() { QwtSplineLocal spline( QwtSplineLocal::Cardinal ); spline.setParametrization( QwtSplineParametrization::ParameterChordal ); QPolygonF points; points += QPointF( 1, 6 ); points += QPointF( 2, 7 ); points += QPointF( 3, 5); points += QPointF( 2, 4 ); points += QPointF( 0, 3 ); // inserting duplicates QPolygonF points1; for ( int i = 0; i < points.size(); i++ ) { points1 += points[i]; points1 += points[i]; } testPaths( "Duplicates", spline, points, points1 ); spline.setBoundaryType( QwtSpline::ClosedPolygon ); testPaths( "Duplicates", spline, points, points1 ); QPolygonF points2 = points; points2.append( points[0] ); testPaths( "First point also at End", spline, points, points2 ); QPolygonF points3 = points; points3.prepend( points.first() ); testPaths( "First point twice", spline, points, points3 ); QPolygonF points4 = points; points4.append( points.last() ); testPaths( "Last point twice", spline, points, points4 ); }
/** * Splits the selected segments by inserting new nodes in the middle. The * selected segments are defined by each pair of consecutive \a indexRanges. * * This method can deal with both polygons as well as polylines. For polygons, * pass <code>true</code> for \a closed. */ static QPolygonF splitPolygonSegments(const QPolygonF &polygon, const RangeSet<int> &indexRanges, bool closed) { if (indexRanges.isEmpty()) return polygon; const int n = polygon.size(); QPolygonF result = polygon; RangeSet<int>::Range firstRange = indexRanges.begin(); RangeSet<int>::Range it = indexRanges.end(); // assert: firstRange != it if (closed) { RangeSet<int>::Range lastRange = it; --lastRange; // We know there is at least one range // Handle the case where the first and last nodes are selected if (firstRange.first() == 0 && lastRange.last() == n - 1) { const QPointF splitPoint = (result.first() + result.last()) / 2; result.append(splitPoint); } } do { --it; for (int i = it.last(); i > it.first(); --i) { const QPointF splitPoint = (result.at(i) + result.at(i - 1)) / 2; result.insert(i, splitPoint); } } while (it != firstRange); return result; }
void LineHandler::deleteLoop(QPolygonF &line, int startPos) { for (int i = startPos; i < line.size() - 3; ++i) { bool isCut = false; for (int j = i + 2; j < line.size() - 1; ++j) { QPointF cut; if (QLineF(line[i], line[i + 1]).intersect(QLineF(line[j], line[j + 1]), &cut) == QLineF::BoundedIntersection) { if ((i != 0) || !((j == line.size() - 2) && (QLineF(line.first(), line.last()).length() < (kvadratik * 2)))) { QPainterPath path; QPainterPathStroker ps; ps.setWidth(kvadratik); for (int k = 0; k < line.size() - 1; ++k) { path.moveTo(line[k]); path.lineTo(line[k + 1]); if (ps.createStroke(path).contains(cut)) { line.insert(k + 1, cut); break; } } line.remove(i + 2, j - i); deleteLoop(line, i); isCut = true; break; } } } if (isCut) { break; } } }
void IsometricRenderer::drawMapObject(QPainter *painter, const MapObject *object, const QColor &color) const { painter->save(); QPen pen(Qt::black); pen.setCosmetic(true); const Cell &cell = object->cell(); if (!cell.isEmpty()) { const Tile *tile = cell.tile; const QSize imgSize = tile->size(); const QPointF pos = pixelToScreenCoords(object->position()); const QPointF tileOffset = tile->offset(); CellRenderer(painter).render(cell, pos, object->size(), CellRenderer::BottomCenter); if (testFlag(ShowTileObjectOutlines)) { QRectF rect(QPointF(pos.x() - imgSize.width() / 2 + tileOffset.x(), pos.y() - imgSize.height() + tileOffset.y()), imgSize); pen.setStyle(Qt::SolidLine); painter->setPen(pen); painter->drawRect(rect); pen.setStyle(Qt::DotLine); pen.setColor(color); painter->setPen(pen); painter->drawRect(rect); } } else { const qreal lineWidth = objectLineWidth(); const qreal scale = painterScale(); const qreal shadowOffset = (lineWidth == 0 ? 1 : lineWidth) / scale; QColor brushColor = color; brushColor.setAlpha(50); QBrush brush(brushColor); pen.setJoinStyle(Qt::RoundJoin); pen.setCapStyle(Qt::RoundCap); pen.setWidth(lineWidth); QPen colorPen(pen); colorPen.setColor(color); painter->setPen(pen); painter->setRenderHint(QPainter::Antialiasing); // TODO: Do something sensible to make null-sized objects usable switch (object->shape()) { case MapObject::Ellipse: { QPolygonF polygon = pixelRectToScreenPolygon(object->bounds()); float tw = map()->tileWidth(); float th = map()->tileHeight(); QPointF transformScale(1, 1); if (tw > th) transformScale = QPointF(1, th/tw); else transformScale = QPointF(tw/th, 1); QPointF l1 = polygon.at(1) - polygon.at(0); QPointF l2 = polygon.at(3) - polygon.at(0); QTransform trans; trans.scale(transformScale.x(), transformScale.y()); trans.rotate(45); QTransform iTrans = trans.inverted(); QPointF l1x = iTrans.map(l1); QPointF l2x = iTrans.map(l2); QSizeF ellipseSize(l1x.manhattanLength(), l2x.manhattanLength()); if (ellipseSize.width() > 0 && ellipseSize.height() > 0) { painter->save(); painter->setPen(pen); painter->translate(polygon.at(0)); painter->scale(transformScale.x(), transformScale.y()); painter->rotate(45); painter->drawEllipse(QRectF(QPointF(0, 0), ellipseSize)); painter->restore(); } painter->setBrush(Qt::NoBrush); painter->drawPolygon(polygon); painter->setPen(colorPen); painter->setBrush(Qt::NoBrush); painter->translate(QPointF(0, -shadowOffset)); painter->drawPolygon(polygon); painter->setBrush(brush); if (ellipseSize.width() > 0 && ellipseSize.height() > 0) { painter->save(); painter->translate(polygon.at(0)); painter->scale(transformScale.x(), transformScale.y()); painter->rotate(45); painter->drawEllipse(QRectF(QPointF(0, 0), ellipseSize)); painter->restore(); } break; } case MapObject::Rectangle: { QPolygonF polygon = pixelRectToScreenPolygon(object->bounds()); painter->drawPolygon(polygon); painter->setPen(colorPen); painter->setBrush(brush); polygon.translate(0, -shadowOffset); painter->drawPolygon(polygon); break; } case MapObject::Polygon: { const QPointF &pos = object->position(); const QPolygonF polygon = object->polygon().translated(pos); QPolygonF screenPolygon = pixelToScreenCoords(polygon); QPen thickPen(pen); QPen thickColorPen(colorPen); thickPen.setWidthF(thickPen.widthF() * 4); thickColorPen.setWidthF(thickColorPen.widthF() * 4); painter->drawPolygon(screenPolygon); painter->setPen(thickPen); painter->drawPoint(screenPolygon.first()); painter->setPen(colorPen); painter->setBrush(brush); screenPolygon.translate(0, -shadowOffset); painter->drawPolygon(screenPolygon); painter->setPen(thickColorPen); painter->drawPoint(screenPolygon.first()); break; } case MapObject::Polyline: { const QPointF &pos = object->position(); const QPolygonF polygon = object->polygon().translated(pos); QPolygonF screenPolygon = pixelToScreenCoords(polygon); QPen thickPen(pen); QPen thickColorPen(colorPen); thickPen.setWidthF(thickPen.widthF() * 4); thickColorPen.setWidthF(thickColorPen.widthF() * 4); painter->drawPolyline(screenPolygon); painter->setPen(thickPen); painter->drawPoint(screenPolygon.first()); pen.setColor(color); painter->setPen(pen); screenPolygon.translate(0, -shadowOffset); painter->drawPolyline(screenPolygon); painter->setPen(thickColorPen); painter->drawPoint(screenPolygon.first()); break; } } } painter->restore(); }
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 ); }
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 ); }
QPolygonF straightArrow( QPointF po, QPointF pd, qreal startWidth, qreal width, qreal headSize, QgsArrowSymbolLayer::HeadType headType, qreal offset ) { QPolygonF polygon; // implicitly shared // vector length qreal length = euclidian_distance( po, pd ); // shift points if there is not enough room for the head(s) if (( headType == QgsArrowSymbolLayer::HeadSingle ) && ( length < headSize ) ) { po = pd - ( pd - po ) / length * headSize; length = headSize; } else if (( headType == QgsArrowSymbolLayer::HeadReversed ) && ( length < headSize ) ) { pd = po + ( pd - po ) / length * headSize; length = headSize; } else if (( headType == QgsArrowSymbolLayer::HeadDouble ) && ( length < 2 * headSize ) ) { QPointF v = ( pd - po ) / length * headSize; QPointF npo = ( po + pd ) / 2.0 - v; QPointF npd = ( po + pd ) / 2.0 + v; po = npo; pd = npd; length = 2 * headSize; } qreal bodyLength = length - headSize; // unit vector QPointF unitVec = ( pd - po ) / length; // perpendicular vector QPointF perpVec( -unitVec.y(), unitVec.x() ); // set offset po += perpVec * offset; pd += perpVec * offset; if ( headType == QgsArrowSymbolLayer::HeadDouble ) { // first head polygon << po; polygon << po + unitVec * headSize + perpVec * headSize; polygon << po + unitVec * headSize + perpVec * ( width * 0.5 ); polygon << po + unitVec * bodyLength + perpVec * ( width * 0.5 ); // second head polygon << po + unitVec * bodyLength + perpVec * headSize; polygon << pd; polygon << po + unitVec * bodyLength - perpVec * headSize; polygon << po + unitVec * bodyLength - perpVec * ( width * 0.5 ); // end of the first head polygon << po + unitVec * headSize - perpVec * ( width * 0.5 ); polygon << po + unitVec * headSize - perpVec * headSize; } else if ( headType == QgsArrowSymbolLayer::HeadSingle ) { polygon << po - perpVec * ( startWidth * 0.5 ); polygon << po + perpVec * ( startWidth * 0.5 ); polygon << po + unitVec * bodyLength + perpVec * ( width * 0.5 ); polygon << po + unitVec * bodyLength + perpVec * headSize; polygon << pd; polygon << po + unitVec * bodyLength - perpVec * headSize; polygon << po + unitVec * bodyLength - perpVec * ( width * 0.5 ); } else if ( headType == QgsArrowSymbolLayer::HeadReversed ) { // first head polygon << po; polygon << po + unitVec * headSize + perpVec * headSize; polygon << po + unitVec * headSize + perpVec * ( width * 0.5 ); polygon << pd + perpVec * ( startWidth * 0.5 ); polygon << pd - perpVec * ( startWidth * 0.5 ); polygon << po + unitVec * headSize - perpVec * ( width * 0.5 ); polygon << po + unitVec * headSize - perpVec * headSize; } // close the polygon polygon << polygon.first(); return polygon; }
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; }
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 ); } mMarker->renderPoint( points.at( i ), context.feature(), rc, -1, context.selected() ); } // restore original rotation mMarker->setAngle( origAngle ); }
void GraphicsTransition::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){ //If the collide no need to draw an arrow if (mCurrentState->collidesWithItem(mNextState)) return; QPen myPen = pen(); myPen.setColor(Qt::white); qreal arrowSize = 20; painter->setPen(myPen); painter->setBrush(Qt::white); QLineF centerLine(mCurrentState->getCenterPoint(), mNextState->getCenterPoint()); QPolygonF endPolygon = mNextState->boundingRect(); QPointF p1 = endPolygon.first() + mNextState->pos(); QPointF p2; QPointF intersectPoint; QLineF polyLine; for (int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i) + mNextState->pos(); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &intersectPoint); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } setLine(QLineF(intersectPoint, mCurrentState->getCenterPoint())); double angle = ::acos(line().dx() / line().length()); if (line().dy() >= 0) angle = (PI * 2) - angle; QPointF arrowP1 = line().p1() + QPointF(sin(angle + PI / 3) * arrowSize, cos(angle + PI / 3) * arrowSize); QPointF arrowP2 = line().p1() + QPointF(sin(angle + PI - PI / 3) * arrowSize, cos(angle + PI - PI / 3) * arrowSize); mArrowHead.clear(); mArrowHead << line().p1() << arrowP1 << arrowP2; painter->drawLine(line()); painter->drawPolygon(mArrowHead); //painter->drawEllipse(line().p1(), 10,10); //Selection square if (isSelected()) { painter->setPen(QPen(Qt::yellow, 3, Qt::DashLine)); QLineF myLine = line(); myLine.translate(0, 4.0); painter->drawLine(myLine); myLine.translate(0,-8.0); painter->drawLine(myLine); } }
//---------------------------------------------------------------------------------------------- void GraphEdgeView::paint(QPainter *p_painter, const QStyleOptionGraphicsItem *p_option, QWidget *p_widget) { if (m_startNode->collidesWithItem(m_endNode)) return; QPen myPen = pen(); myPen.setColor(isSelected() ? m_selectedColor : m_color); qreal arrowSize = m_arrowSize; p_painter->setPen(myPen); p_painter->setBrush(isSelected() ? m_selectedColor : m_color); QLineF centerLine(m_startNode->mapToScene(m_startNode->rect().center()), m_endNode->mapToScene(m_endNode->rect().center())); QPolygonF endPolygon; QPointF p1; QPointF p2; QPointF intersectPoint1; QPointF intersectPoint2; QLineF polyLine; endPolygon = QPolygonF(m_endNode->rect()); p1 = endPolygon.first() + m_endNode->pos(); for (int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i) + m_endNode->pos(); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &intersectPoint1); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } endPolygon = QPolygonF(m_startNode->rect()); p1 = endPolygon.first() + m_startNode->pos(); for (int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i) + m_startNode->pos(); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &intersectPoint2); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } setLine(QLineF(intersectPoint1, intersectPoint2)); double angle = ::acos(this->line().dx() / this->line().length()); if (this->line().dy() >= 0) angle = (Pi * 2) - angle; QPointF arrowP1 = this->line().p1() + QPointF(sin(angle + Pi / 3) * arrowSize, cos(angle + Pi / 3) * arrowSize); QPointF arrowP2 = this->line().p1() + QPointF(sin(angle + Pi - Pi / 3) * arrowSize, cos(angle + Pi - Pi / 3) * arrowSize); m_arrowHead.clear(); m_arrowHead << this->line().p1() << arrowP1 << arrowP2; p_painter->drawLine(this->line()); p_painter->drawPolygon(m_arrowHead); //if (isSelected()) //{ // p_painter->setPen(QPen(m_selectedColor, 2, Qt::DotLine)); // QLineF normal = this->line().unitVector().normalVector(); // qreal dx = normal.dx(); // qreal dy = normal.dy(); // QLineF myLine; // // myLine = this->line(); // myLine.translate(dx * 4, dy * 4); // p_painter->drawLine(myLine); // myLine = this->line(); // myLine.translate(-dx * 4,-dy * 4); // p_painter->drawLine(myLine); //} }