void QgsMarkerLineSymbolLayerV2::renderPolylineCentral( const QPolygonF& points, QgsSymbolV2RenderContext& context )
{
  if ( points.size() > 0 )
  {
    // calc length
    qreal length = 0;
    QPolygonF::const_iterator it = points.constBegin();
    QPointF last = *it;
    for ( ++it; it != points.constEnd(); ++it )
    {
      length += sqrt(( last.x() - it->x() ) * ( last.x() - it->x() ) +
                     ( last.y() - it->y() ) * ( last.y() - it->y() ) );
      last = *it;
    }

    // find the segment where the central point lies
    it = points.constBegin();
    last = *it;
    qreal last_at = 0, next_at = 0;
    QPointF next;
    int segment = 0;
    for ( ++it; it != points.constEnd(); ++it )
    {
      next = *it;
      next_at += sqrt(( last.x() - it->x() ) * ( last.x() - it->x() ) +
                      ( last.y() - it->y() ) * ( last.y() - it->y() ) );
      if ( next_at >= length / 2 )
        break; // we have reached the center
      last = *it;
      last_at = next_at;
      segment++;
    }

    // find out the central point on segment
    MyLine l( last, next ); // for line angle
    qreal k = ( length * 0.5 - last_at ) / ( next_at - last_at );
    QPointF pt = last + ( next - last ) * k;

    // draw the marker
    double origAngle = mMarker->angle();
    if ( mRotateMarker )
      mMarker->setAngle( origAngle + l.angle() * 180 / M_PI );
    mMarker->renderPoint( pt, context.feature(), context.renderContext(), -1, context.selected() );
    if ( mRotateMarker )
      mMarker->setAngle( origAngle );
  }
}
void QgsCoordinateTransform::transformPolygon( QPolygonF &poly, TransformDirection direction ) const
{
  if ( !d->mIsValid || d->mShortCircuit )
  {
    return;
  }

  //create x, y arrays
  int nVertices = poly.size();

  QVector<double> x( nVertices );
  QVector<double> y( nVertices );
  QVector<double> z( nVertices );
  double *destX = x.data();
  double *destY = y.data();
  double *destZ = z.data();

  const QPointF *polyData = poly.constData();
  for ( int i = 0; i < nVertices; ++i )
  {
    *destX++ = polyData->x();
    *destY++ = polyData->y();
    *destZ++ = 0;
    polyData++;
  }

  try
  {
    transformCoords( nVertices, x.data(), y.data(), z.data(), direction );
  }
  catch ( const QgsCsException & )
  {
    // rethrow the exception
    QgsDebugMsg( QStringLiteral( "rethrowing exception" ) );
    throw;
  }

  QPointF *destPoint = poly.data();
  const double *srcX = x.constData();
  const double *srcY = y.constData();
  for ( int i = 0; i < nVertices; ++i )
  {
    destPoint->rx() = *srcX++;
    destPoint->ry() = *srcY++;
    destPoint++;
  }
}
Beispiel #3
0
/**********************************************************************
 * Function: get handle point
 * Parameters: handle id, bound rect
 * Return: none
 **********************************************************************/
QPointF QArcItem::getHandle(int iHandle, QRectF &qrcBondingRect) const
{
    QPointF qpPoint;

    if (iHandle > 8)
    {
        QList<QPolygonF> polygonfs = m_ArcPath.toSubpathPolygons();
        int iSize = polygonfs.size();
        if (iSize <= 0 || iSize > 1)
        {
            return qpPoint;
        }
        QPolygonF polygonf = polygonfs.at(0);
        int j = polygonf.size();
        if (j <= 1)
        {
            return qpPoint;;
        }

        /*Get the key points*/
        QPointF qpDimCenter;
        qpDimCenter = polygonf.at(0);
        switch (iHandle)
        {
        case 9:
            qpPoint = polygonf.at(1);
            qpPoint.rx() = (qpPoint.x() + qpDimCenter.x()) / 2;
            qpPoint.ry() = (qpPoint.y() + qpDimCenter.y()) / 2;
            break;
        case 10:
            qpPoint = polygonf.at(j - 1);
            qpPoint.rx() = (qpPoint.x() + qpDimCenter.x()) / 2;
            qpPoint.ry() = (qpPoint.y() + qpDimCenter.y()) / 2;
            break;
        default:
            break;
        }

        qpPoint = this->mapToScene(qpPoint);
        qpPoint.rx() = qpPoint.x();
        return qpPoint;
    }
    else
    {
        return SamDrawItemBase::getHandle(iHandle, qrcBondingRect);
    }
}
void QgsSimpleLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSymbolV2RenderContext& context )
{
  QPainter* p = context.renderContext().painter();
  if ( !p )
  {
    return;
  }

  double offset = 0.0;
  applyDataDefinedSymbology( context, mPen, mSelPen, offset );

  p->setPen( context.selected() ? mSelPen : mPen );

  // Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #2 points).
  if ( points.size() <= 2 && context.layer() && context.layer()->simplifyDrawingCanbeApplied( context.renderContext(), QgsVectorLayer::AntialiasingSimplification ) && QgsAbstractGeometrySimplifier::canbeGeneralizedByDeviceBoundingBox( points, context.layer()->simplifyMethod().threshold() ) && ( p->renderHints() & QPainter::Antialiasing ) )
  {
    p->setRenderHint( QPainter::Antialiasing, false );
    p->drawPolyline( points );
    p->setRenderHint( QPainter::Antialiasing, true );
    return;
  }

  if ( mDrawInsidePolygon )
  {
    //only drawing the line on the interior of the polygon, so set clip path for painter
    p->save();
    QPainterPath clipPath;
    clipPath.addPolygon( points );
    p->setClipPath( clipPath, Qt::IntersectClip );
  }

  if ( offset == 0 )
  {
    p->drawPolyline( points );
  }
  else
  {
    double scaledOffset = offset * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit );
    p->drawPolyline( ::offsetLine( points, scaledOffset ) );
  }

  if ( mDrawInsidePolygon )
  {
    //restore painter to reset clip path
    p->restore();
  }
}
Beispiel #5
0
//! Sutherland-Hodgman polygon clipping
QPolygonF GraphPolygonClipperF::clipPolygon(const QPolygonF &pa) const
{
    if ( contains( ::boundingRect(pa) ) )
        return pa;

    QPolygonF cpa(pa.size());

    clipEdge((Edge)0, pa, cpa);

    for ( uint edge = 1; edge < NEdges; edge++ ) 
    {
        const QPolygonF rpa = cpa;
        clipEdge((Edge)edge, rpa, cpa);
    }

    return cpa;
}
Beispiel #6
0
void QgsFillSymbolLayerV2::_renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context )
{
  if ( !p )
  {
    return;
  }

  // Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #5 points).
  if ( points.size() <= 5 &&
       ( context.renderContext().vectorSimplifyMethod().simplifyHints() & QgsVectorSimplifyMethod::AntialiasingSimplification ) &&
       QgsAbstractGeometrySimplifier::isGeneralizableByDeviceBoundingBox( points, context.renderContext().vectorSimplifyMethod().threshold() ) &&
       ( p->renderHints() & QPainter::Antialiasing ) )
  {
    p->setRenderHint( QPainter::Antialiasing, false );
    p->drawRect( points.boundingRect() );
    p->setRenderHint( QPainter::Antialiasing, true );
    return;
  }

  // polygons outlines are sometimes rendered wrongly with drawPolygon, when
  // clipped (see #13343), so use drawPath instead.
  if ( !rings && p->pen().style() == Qt::NoPen )
  {
    // simple polygon without holes
    p->drawPolygon( points );
  }
  else
  {
    // polygon with holes must be drawn using painter path
    QPainterPath path;
    QPolygonF outerRing = points;
    path.addPolygon( outerRing );

    if ( rings )
    {
      QList<QPolygonF>::const_iterator it = rings->constBegin();
      for ( ; it != rings->constEnd(); ++it )
      {
        QPolygonF ring = *it;
        path.addPolygon( ring );
      }
    }

    p->drawPath( path );
  }
}
Beispiel #7
0
QString ShortNavigation::buildWKTPolygon( const QPolygonF &rhomboid ) {


    QString WKTPolygon = "'POLYGON((";
    for ( int i = 0; i < rhomboid.size(); i++ ) {
        WKTPolygon.append( QString::number( rhomboid[i].x(), 'f', WKT_P));
        WKTPolygon.append( " ");
        WKTPolygon.append( QString::number( rhomboid[i].y(), 'f', WKT_P));
        WKTPolygon.append( ",");
    }
    WKTPolygon.append( QString::number( rhomboid.at(0).x(), 'f', WKT_P));
    WKTPolygon.append( " ");
    WKTPolygon.append( QString::number( rhomboid.at(0).y(), 'f', WKT_P));
    WKTPolygon.append( "))'");

    return WKTPolygon;
}
static SplineStore qwtSplinePathG1( 
    const QwtSplineCardinalG1 *spline, const QPolygonF &points ) 
{
    const int size = points.size();
    const int numTensions = spline->isClosing() ? size : size - 1;

    const QVector<QwtSplineCardinalG1::Tension> tensions2 = spline->tensions( points );
    if ( tensions2.size() != numTensions )
        return SplineStore();

    const QPointF *p = points.constData();
    const QwtSplineCardinalG1::Tension *t = tensions2.constData();

    SplineStore store;
    store.init( numTensions );
    store.start( p[0] );
    
    const QPointF &p0 = spline->isClosing() ? p[size-1] : p[0];
    QPointF vec1 = ( p[1] - p0 ) * 0.5;

    for ( int i = 0; i < size - 2; i++ )
    {
        const QPointF vec2 = ( p[i+2] - p[i] ) * 0.5;
        store.addCubic( p[i] + vec1 * t[i].t1, 
            p[i+1] - vec2 * t[i].t2, p[i+1] );
        
        vec1 = vec2;
    }   
    
    const QPointF &pn = spline->isClosing() ? p[0] : p[size-1];
    const QPointF vec2 = 0.5 * ( pn - p[size - 2] );

    store.addCubic( p[size - 2] + vec1 * t[size-2].t1,
        p[size - 1] - vec2 * t[size-2].t2, p[size - 1] );

    if ( spline->isClosing() )
    {
        const QPointF vec3 = 0.5 * ( p[1] - p[size-1] );
        store.addCubic( p[size-1] + vec2 * t[size-1].t1, 
            p[0] - vec3 * t[size-1].t2, p[0] );
    }

    return store;
}
/*!
  \param points Series of data points
  \return Curve points
*/
QPolygonF QwtWeedingCurveFitter::fitCurve( const QPolygonF &points ) const
{
    QPolygonF fittedPoints;

    if ( d_data->chunkSize == 0 )
    {
        fittedPoints = simplify( points );
    }
    else
    {
        for ( int i = 0; i < points.size(); i += d_data->chunkSize )
        {
            const QPolygonF p = points.mid( i, d_data->chunkSize );
            fittedPoints += simplify( p );
        }
    }

    return fittedPoints;
}
bool LinearFunction::apply(const QPolygonF& curveSamples, float x, float& y)
{
	const int nbSamples = curveSamples.size();
	for (int i=0; i<nbSamples; ++i)
	{
		const QPointF& point1 = curveSamples[i];
		if (i+1 < nbSamples)
		{
			const QPointF& point2 = curveSamples[i+1];
			if (point1.x()!=point2.x() && x>=point1.x() && x<=point2.x())
			{
				LinearFunction f(point1, point2);
				y = f(x);
				return true;
			}
		}
	}
	return false;
}
Beispiel #11
0
QString QTikzPicturePrivate::toTikzPath(const QPolygonF & polygon) const
{
    if (polygon.isEmpty()) return QString();

    const int end = polygon.size() - polygon.isClosed() ? 1 : 0;

    QString path;
    for (int i = 0; i < end; ++i) {
        if (i == 0) {
            path = toCoord(polygon[i]);
        } else if (i == end - 1) {
            path += " -- cycle";
        } else {
            path += " -- " + toCoord(polygon[i]);
        }
    }

    return path;
}
// Check whether a point is on the border
static bool isPointOnPathBorder(const QPolygonF& border, const QPointF& p)
{
    QPointF p1 = border.at(0);
    QPointF p2;

    for (int i = 1; i < border.size(); ++i) {
        p2 = border.at(i);
        if (areCollinear(p, p1, p2)
                // Once we know that the points are collinear we
                // only need to check one of the coordinates
                && (qAbs(p2.x() - p1.x()) > qAbs(p2.y() - p1.y()) ?
                        withinRange(p.x(), p1.x(), p2.x()) :
                        withinRange(p.y(), p1.y(), p2.y()))) {
            return true;
        }
        p1 = p2;
    }
    return false;
}
void QgsSimpleLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSymbolV2RenderContext& context )
{
  QPainter* p = context.renderContext().painter();
  if ( !p )
  {
    return;
  }

  //size scaling by field
  if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale )
  {
    applySizeScale( context, mPen, mSelPen );
  }

  double offset = mOffset;
  applyDataDefinedSymbology( context, mPen, mSelPen, offset );

  p->setPen( context.selected() ? mSelPen : mPen );

  // Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #2 points).
  if ( points.size() <= 2 &&
       ( context.renderContext().vectorSimplifyMethod().simplifyHints() & QgsVectorSimplifyMethod::AntialiasingSimplification ) &&
       QgsAbstractGeometrySimplifier::isGeneralizableByDeviceBoundingBox( points, context.renderContext().vectorSimplifyMethod().threshold() ) &&
       ( p->renderHints() & QPainter::Antialiasing ) )
  {
    p->setRenderHint( QPainter::Antialiasing, false );
    p->drawPolyline( points );
    p->setRenderHint( QPainter::Antialiasing, true );
    return;
  }

  if ( qgsDoubleNear( offset, 0 ) )
  {
    p->drawPolyline( points );
  }
  else
  {
    double scaledOffset = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), offset, mOffsetUnit, mOffsetMapUnitScale );
    QList<QPolygonF> mline = ::offsetLine( points, scaledOffset, context.feature() ? context.feature()->constGeometry()->type() : QGis::Line );
    for ( int part = 0; part < mline.count(); ++part )
      p->drawPolyline( mline[ part ] );
  }
}
/*!
  \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() );
    }
}
Beispiel #15
0
QPolygonF Shape::vertices() const
{
  QPolygonF result = vertices_;

  switch (type_) {
    case SEGMENT:
    case POLYLINE:
    case CLOSED_POLYLINE:
    case POLYGON:
      break;

    case RECTANGLE:
      if (result.size() == 2) {
        result = QPolygonF(QRectF(result[0], result[1]));
        result.pop_back();
      }
      break;
  }
  return result;
}
Beispiel #16
0
bool PathPlanner::pointInPolygon(const QPointF &point, const QPolygonF &polygon)
{
    int polyCorners = polygon.size();
    int i, j = polyCorners - 1;
    bool oddNodes = false;
    double x = point.x(), y = point.y();

    for (i=0; i < polyCorners; i++)
    {
        if ( ((polygon[i].y() < y && polygon[j].y() >= y) || (polygon[j].y() < y && polygon[i].y() >= y))
                && (polygon[i].x() <= x || polygon[j].x()<=x))
        {
            oddNodes ^= (polygon[i].x()+(y-polygon[i].y())/(polygon[j].y()-polygon[i].y())*(polygon[j].x()-polygon[i].x())<x);
        }

        j = i;
    }

    return oddNodes;
}
Beispiel #17
0
void EditPolygonTool::deleteNodes()
{
    if (mSelectedHandles.isEmpty())
        return;

    PointIndexesByObject p = groupIndexesByObject(mSelectedHandles);
    QMapIterator<MapObject*, RangeSet<int> > i(p);

    QUndoStack *undoStack = mapDocument()->undoStack();

    QString delText = tr("Delete %n Node(s)", "", mSelectedHandles.size());
    undoStack->beginMacro(delText);

    while (i.hasNext()) {
        MapObject *object = i.next().key();
        const RangeSet<int> &indexRanges = i.value();

        QPolygonF oldPolygon = object->polygon();
        QPolygonF newPolygon = oldPolygon;

        // Remove points, back to front to keep the indexes valid
        RangeSet<int>::Range it = indexRanges.end();
        RangeSet<int>::Range begin = indexRanges.begin();
        // assert: end != begin, since there is at least one entry
        do {
            --it;
            newPolygon.remove(it.first(), it.length());
        } while (it != begin);

        if (newPolygon.size() < 2) {
            // We've removed the entire object
            undoStack->push(new RemoveMapObject(mapDocument(), object));
        } else {
            undoStack->push(new ChangePolygon(mapDocument(), object,
                                              newPolygon,
                                              oldPolygon));
        }
    }

    undoStack->endMacro();
}
QPainterPath QwtSplinePleasing::pathP( const QPolygonF &points ) const
{
    const int size = points.size();
    if ( size <= 2 )
        return QwtSplineCardinalG1::pathP( points );

    using namespace QwtSplineCardinalG1P;

    PathStore store;
    switch( parametrization()->type() )
    {
        case QwtSplineParameter::ParameterX:
        {
            store = qwtSplinePathPleasing<PathStore>( points, 
                isClosing(), QwtSplineParameter::paramX() );
            break;
        }
        case QwtSplineParameter::ParameterUniform:
        {
            store = qwtSplinePathPleasing<PathStore>( points, 
                isClosing(), QwtSplineParameter::paramUniform() );
            break;
        }
        case QwtSplineParameter::ParameterChordal:
        {
            store = qwtSplinePathPleasing<PathStore>( points, 
                isClosing(), QwtSplineParameter::paramChordal() );
            break;
        }
        default:
        {
            store = qwtSplinePathPleasing<PathStore>( points, 
                isClosing(), QwtSplineParameter::param( parametrization() ) );
        }
    }

    if ( isClosing() )
        store.path.closeSubpath();

    return store.path;
}
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;
}
QPainterPath OrthogonalRenderer::shape(const MapObject *object) const
{
    QPainterPath path;

    if (object->tile()) {
        path.addRect(boundingRect(object));
    } else {
        switch (object->shape()) {
        case MapObject::Rectangle: {
            const QRectF bounds = object->bounds();
            const QRectF rect(tileToPixelCoords(bounds.topLeft()),
                              tileToPixelCoords(bounds.bottomRight()));

            if (rect.isNull()) {
                path.addEllipse(rect.topLeft(), 20, 20);
            } else {
                path.addRoundedRect(rect, 10, 10);
            }
            break;
        }
        case MapObject::Polygon:
        case MapObject::Polyline: {
            const QPointF &pos = object->position();
            const QPolygonF polygon = object->polygon().translated(pos);
            const QPolygonF screenPolygon = tileToPixelCoords(polygon);
            if (object->shape() == MapObject::Polygon) {
                path.addPolygon(screenPolygon);
            } else {
                for (int i = 1; i < screenPolygon.size(); ++i) {
                    path.addPolygon(lineToPolygon(screenPolygon[i - 1],
                                                  screenPolygon[i]));
                }
                path.setFillRule(Qt::WindingFill);
            }
            break;
        }
        }
    }

    return path;
}
static inline QVector<QwtSplineCardinalG1::Tension> qwtTensions( 
    const QPolygonF &points, bool isClosed, Param param ) 
{
    const int size = points.size();
    QVector<QwtSplineCardinalG1::Tension> tensions2( isClosed ? size : size - 1 );

    const QPointF *p = points.constData();
    QwtSplineCardinalG1::Tension *t = tensions2.data();

    const QPointF &p0 = isClosed ? p[size-1] : p[0];
    double d13 = param(p[0], p[2]);

    t[0] = qwtTension( param(p0, p[1]), param(p[0], p[1]), 
        d13, p0, p[0], p[1], p[2] );

    for ( int i = 1; i < size - 2; i++ )
    {
        const double d23 = param( p[i], p[i+1] );
        const double d24 = param( p[i], p[i+2] );

        t[i] = qwtTension( d13, d23, d24, p[i-1], p[i], p[i+1], p[i+2] );

        d13 = d24;
    }

    const QPointF &pn = isClosed ? p[0] : p[size-1];
    const double d24 = param( p[size-2], pn );

    t[size-2] = qwtTension( d13, param( p[size-2], p[size-1] ), d24,
        p[size - 3], p[size - 2], p[size - 1], pn );

    if ( isClosed )
    {
        const double d34 = param( p[size-1], p[0] );
        const double d35 = param( p[size-1], p[1] );

        t[size-1] = qwtTension( d24, d34, d35, p[size-2], p[size-1], p[0], p[1] );
    }

    return tensions2;
}
void Renderer::drawMesh()
{
  // render mesh as a wireframe

  QPainter p(&mImage);
  p.setRenderHint(QPainter::Antialiasing);
  p.setPen(QPen(QBrush(mCfg.mesh.mMeshColor),0.5));
  p.setFont(QFont(""));
  const Mesh::Elements& elems = mMesh->elements();
  for (int i=0; i < elems.count(); ++i)
  {
    const Element& elem = elems[i];
    if( elem.isDummy() )
        continue;

    // If the element is outside the view of the canvas, skip it
    if( elemOutsideView(i) )
        continue;

    QPolygonF pts = elementPolygonPixel(elem);
    p.drawPolyline(pts.constData(), pts.size());

    if (mCfg.mesh.mRenderMeshLabels)
    {
        double cx, cy;
        mMesh->elementCentroid(i, cx, cy);
        QString txt = QString::number(elem.id());
        QRect bb = p.fontMetrics().boundingRect(txt);
        QPointF xy = mtp.realToPixel(cx, cy);
        bb.moveTo(xy.x() - bb.width()/2.0, xy.y() - bb.height()/2.0);

        if (pts.containsPoint(bb.bottomLeft(), Qt::WindingFill) &&
            pts.containsPoint(bb.bottomRight(), Qt::WindingFill) &&
            pts.containsPoint(bb.topLeft(), Qt::WindingFill) &&
            pts.containsPoint(bb.topRight(), Qt::WindingFill))
        {
            p.drawText(bb, Qt::AlignCenter, txt);
        }
    }
  }
}
Beispiel #23
0
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;
}
void QgsCoordinateTransform::transformPolygon( QPolygonF& poly, TransformDirection direction ) const
{
    if ( mShortCircuit || !mInitialisedFlag )
    {
        return;
    }

    //create x, y arrays
    int nVertices = poly.size();

    QVector<double> x( nVertices );
    QVector<double> y( nVertices );
    QVector<double> z( nVertices );

    for ( int i = 0; i < nVertices; ++i )
    {
        const QPointF& pt = poly.at( i );
        x[i] = pt.x();
        y[i] = pt.y();
        z[i] = 0;
    }

    try
    {
        transformCoords( nVertices, x.data(), y.data(), z.data(), direction );
    }
    catch ( const QgsCsException & )
    {
        // rethrow the exception
        QgsDebugMsg( "rethrowing exception" );
        throw;
    }

    for ( int i = 0; i < nVertices; ++i )
    {
        QPointF& pt = poly[i];
        pt.rx() = x[i];
        pt.ry() = y[i];
    }
}
Beispiel #25
0
// ============================================================================
/// Checks if polygon is convex.
bool isPolygonConvex( const QPolygonF& p )
{
	int points = p.size();
	if ( points < 3 )
	{
		return true; // short circuit edge case
	}
	
	int negatives = 0;
	int positives = 0;
	
	for( int i = 0; i < points; i++ )
	{
		QPointF p1 = p[i];
		QPointF p2 = p[(i+1)%points];
		QPointF p3 = p[(i+2)%points];
		
		// TODO use b2Cross here
		
		// converts these points to 2 3d vectors
		double a1 = p2.x() - p1.x();
		double a2 = p2.y() - p1.y();
		// a3 = 0
		
		double b1 = p3.x() - p2.x();
		double b2 = p3.y() - p2.y();
		// b3 = 0;
		
		// now find cross product of these vectors
		// c = a x b
		// c1 = 0, c2 = 0
		double c3 = a1*b2 - a2*b1;
		
		
		if ( c3 < 0 ) negatives ++;
		else positives++;
	}
	
	return ( negatives == 0 ) || ( positives == 0 );
}
Beispiel #26
0
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 );
}
void LineDiagram::Private::paintPolyline(
    PaintContext* ctx,
    const QBrush& brush, const QPen& pen,
    const QPolygonF& points ) const
{
    ctx->painter()->setBrush( brush );
    ctx->painter()->setPen( PrintingParameters::scalePen(
        QPen( pen.color(),
              pen.width(),
              pen.style(),
              Qt::FlatCap,
              Qt::MiterJoin ) ) );
#if QT_VERSION > 0x040299
    ctx->painter()->drawPolyline( points );
#else
    // FIXME (Mirko) verify, this sounds reverse-logical
    // For Qt versions older than 4.3 drawPolyline is VERY slow
    // so we use traditional line segments drawing instead then.
    for (int i = 0; i < points.size()-1; ++i)
        ctx->painter()->drawLine( points.at(i), points.at(i+1) );
#endif
}
Beispiel #28
0
QPainterPath QwtSpline::pathP( const QPolygonF &points ) const
{
    const int n = points.size();

    QPainterPath path;
    if ( n == 0 )
        return path;

    if ( n == 1 )
    {
        path.moveTo( points[0] );
        return path;
    }

    if ( n == 2 )
    {
        path.addPolygon( points );
        return path;
    }

    const QVector<QLineF> controlPoints = bezierControlPointsP( points );
    if ( controlPoints.size() < n - 1 )
        return path;

    const QPointF *p = points.constData();
    const QLineF *l = controlPoints.constData();

    path.moveTo( p[0] );
    for ( int i = 0; i < n - 1; i++ )
        path.cubicTo( l[i].p1(), l[i].p2(), p[i+1] );

    if ( controlPoints.size() >= n )
    {
        path.cubicTo( l[n-1].p1(), l[n-1].p2(), p[0] );
        path.closeSubpath();
    }

    return path;
}
Beispiel #29
0
// Check whether a point is on the border
bool isPointOnPathBorder(const QPolygonF& border, const QPointF& p)
{
    QPointF p1 = border.at(0);
    QPointF p2;

    for (int i = 1; i < border.size(); ++i) {
        p2 = border.at(i);
        //  (x1<=x<=x2||x1=>x>=x2) && (y1<=y<=y2||y1=>y>=y2)  && (y2-y1)(x-x1) == (y-y1)(x2-x1)
        //  In which, (y2-y1)(x-x1) == (y-y1)(x2-x1) is from (y2-y1)/(x2-x1) == (y-y1)/(x-x1)
        //  it want to check the slope between p1 and p2 is same with slope between p and p1,
        //  if so then the three points lie on the same line.
        //  In which, (x1<=x<=x2||x1=>x>=x2) && (y1<=y<=y2||y1=>y>=y2) want to make sure p is
        //  between p1 and p2, not outside.
        if (((p.x() <= p1.x() && p.x() >= p2.x()) || (p.x() >= p1.x() && p.x() <= p2.x()))
            && ((p.y() <= p1.y() && p.y() >= p2.y()) || (p.y() >= p1.y() && p.y() <= p2.y()))
            && (p2.y() - p1.y()) * (p.x() - p1.x()) == (p.y() - p1.y()) * (p2.x() - p1.x())) {
            return true;
        }
        p1 = p2;
    }
    return false;
}
Beispiel #30
0
void GraphPolygonClipperF::clipEdge(Edge edge, 
    const QPolygonF &pa, QPolygonF &cpa) const
{
    if ( pa.count() == 0 )
    {
        cpa.resize(0);
        return;
    }

    unsigned int count = 0;

    GraphDoublePoint p1 = pa[0];
    if ( insideEdge(p1, edge) )
        addPoint(cpa, count++, p1);

    const uint nPoints = pa.size();
    for ( uint i = 1; i < nPoints; i++ )
    {
        const GraphDoublePoint p2 = pa[(int)i];
        if ( insideEdge(p2, edge) )
        {
            if ( insideEdge(p1, edge) )
                addPoint(cpa, count++, p2);
            else
            {
                addPoint(cpa, count++, intersectEdge(p1, p2, edge));
                addPoint(cpa, count++, p2);
            }
        }
        else
        {
            if ( insideEdge(p1, edge) )
                addPoint(cpa, count++, intersectEdge(p1, p2, edge));
        }
        p1 = p2;
    }
    cpa.resize(count);
}