Esempio n. 1
0
/*!
  Draw dots

  \param painter Painter
  \param xMap x map
  \param yMap y map
  \param canvasRect Contents rect of the canvas
  \param from index of the first point to be painted
  \param to index of the last point to be painted

  \sa draw(), drawCurve(), drawSticks(), drawLines(), drawSteps()
*/
void QwtPlotCurve::drawDots( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect, int from, int to ) const
{
    const bool doFill = d_data->brush.style() != Qt::NoBrush;
    const bool doAlign = QwtPainter::roundingAlignment( painter );

    QPolygonF polyline;
    if ( doFill )
        polyline.resize( to - from + 1 );

    QPointF *points = polyline.data();

    for ( int i = from; i <= to; i++ )
    {
        const QPointF sample = d_series->sample( i );
        double xi = xMap.transform( sample.x() );
        double yi = yMap.transform( sample.y() );
        if ( doAlign )
        {
            xi = qRound( xi );
            yi = qRound( yi );
        }

        QwtPainter::drawPoint( painter, QPointF( xi, yi ) );

        if ( doFill )
        {
            points[i - from].rx() = xi;
            points[i - from].ry() = yi;
        }
    }

    if ( doFill )
        fillCurve( painter, xMap, yMap, canvasRect, polyline );
}
void QgsComposerItem::sizeChangedByRotation( double& width, double& height )
{
  if ( mRotation == 0.0 )
  {
    return;
  }

  //vector to p1
  double x1 = -width / 2.0;
  double y1 = -height / 2.0;
  rotate( mRotation, x1, y1 );
  //vector to p2
  double x2 = width / 2.0;
  double y2 = -height / 2.0;
  rotate( mRotation, x2, y2 );
  //vector to p3
  double x3 = width / 2.0;
  double y3 = height / 2.0;
  rotate( mRotation, x3, y3 );
  //vector to p4
  double x4 = -width / 2.0;
  double y4 = height / 2.0;
  rotate( mRotation, x4, y4 );

  //double midpoint
  QPointF midpoint( width / 2.0, height / 2.0 );

  QPolygonF rotatedRectPoly;
  rotatedRectPoly << QPointF( midpoint.x() + x1, midpoint.y() + y1 );
  rotatedRectPoly << QPointF( midpoint.x() + x2, midpoint.y() + y2 );
  rotatedRectPoly << QPointF( midpoint.x() + x3, midpoint.y() + y3 );
  rotatedRectPoly << QPointF( midpoint.x() + x4, midpoint.y() + y4 );
  QRectF boundingRect = rotatedRectPoly.boundingRect();
  width = boundingRect.width();
  height = boundingRect.height();
}
void paintElements( AbstractDiagram::Private *diagramPrivate, PaintContext* ctx,
                    const LabelPaintCache& lpc, const LineAttributesInfoList& lineList )
{
    AbstractDiagram* diagram = diagramPrivate->diagram;
    // paint all lines and their attributes
    const PainterSaver painterSaver( ctx->painter() );
    ctx->painter()->setRenderHint( QPainter::Antialiasing, diagram->antiAliasing() );

    QBrush curBrush;
    QPen curPen;
    QPolygonF points;
    KDAB_FOREACH ( const LineAttributesInfo& lineInfo, lineList ) {
        const QModelIndex& index = lineInfo.index;
        const ThreeDLineAttributes td = threeDLineAttributes( diagram, index );

        if ( td.isEnabled() ) {
            PaintingHelpers::paintThreeDLines( ctx, diagram, index, lineInfo.value,
                                               lineInfo.nextValue, td, &diagramPrivate->reverseMapper );
        } else {
            const QBrush brush( diagram->brush( index ) );
            const QPen pen( diagram->pen( index ) );

            // line goes from lineInfo.value to lineInfo.nextValue
            diagramPrivate->reverseMapper.addLine( lineInfo.index.row(), lineInfo.index.column(),
                                                   lineInfo.value, lineInfo.nextValue );

            if ( points.count() && points.last() == lineInfo.value && curBrush == brush && curPen == pen ) {
                // continue the current run of lines
            } else {
                // different painter settings or discontinuous line: start a new run of lines
                if ( points.count() ) {
                    PaintingHelpers::paintPolyline( ctx, curBrush, curPen, points );
                }
                curBrush = brush;
                curPen = pen;
                points.clear();
                points << lineInfo.value;
            }
            points << lineInfo.nextValue;
        }
    }
    if ( points.count() ) {
        // the last run of lines is yet to be painted - do it now
        PaintingHelpers::paintPolyline( ctx, curBrush, curPen, points );
    }

    KDAB_FOREACH ( const LineAttributesInfo& lineInfo, lineList ) {
        const ValueTrackerAttributes vt = valueTrackerAttributes( diagram, lineInfo.index );
        if ( vt.isEnabled() ) {
            PaintingHelpers::paintValueTracker( ctx, vt, lineInfo.nextValue );
        }
    }

    // paint all data value texts and the point markers
    diagramPrivate->paintDataValueTextsAndMarkers( ctx, lpc, true );
}
Esempio n. 4
0
QRectF IsometricRenderer::boundingRect(const MapObject *object) const
{
    const int nameHeight = object->name().isEmpty() ? 0 : 15;

    if (object->tile()) {
        const QPointF bottomCenter = tileToPixelCoords(object->position());
        const QPixmap &img = object->tile()->image();
        return QRectF(bottomCenter.x() - img.width() / 2,
                      bottomCenter.y() - img.height(),
                      img.width(),
                      img.height()).adjusted(-1, -1 - nameHeight, 1, 1);
    } else if (!object->polygon().isEmpty()) {
        const QPointF &pos = object->position();
        const QPolygonF polygon = object->polygon().translated(pos);
        const QPolygonF screenPolygon = tileToPixelCoords(polygon);
        return screenPolygon.boundingRect().adjusted(-2, -2 - nameHeight, 3, 3);
    } else {
        // Take the bounding rect of the projected object, and then add a few
        // pixels on all sides to correct for the line width.
        const QRectF base = tileRectToPolygon(object->bounds()).boundingRect();

        return base.adjusted(-2, -3 - nameHeight, 2, 2);
    }
}
Esempio n. 5
0
/*!
  \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() )
            baseline = yMap.transformation()->bounded( baseline );

        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() )
            baseline = xMap.transformation()->bounded( baseline );

        double refX = xMap.transform( baseline );
        if ( doAlign )
            refX = qRound( refX );

        polygon += QPointF( refX, polygon.last().y() );
        polygon += QPointF( refX, polygon.first().y() );
    }
}
Esempio n. 6
0
void GraphDraw::drawStaticParEq()
{
    QList< QList<Point> > *list;
    QPolygonF polygon;
    Point point;
    ColorSaver *colorSaver;

    pen.setWidth(graphSettings.curvesThickness);
    painter.setRenderHint(QPainter::Antialiasing, graphSettings.smoothing && !moving);
    painter.setPen(pen);

    for(int i = 0; i < parEqs->size(); i++)
    {
        if(!parEqs->at(i)->getDrawState() || parEqs->at(i)->isAnimated())
            continue;

        list = parEqs->at(i)->getPointsList();
        colorSaver = parEqs->at(i)->getColorSaver();

        for(int curve = 0; curve < list->size(); curve++)
        {
            pen.setColor(colorSaver->getColor(curve));
            painter.setPen(pen);

            polygon.clear();

            for(int pos = 0 ; pos < list->at(curve).size(); pos ++)
            {
                point = list->at(curve).at(pos);
                polygon << QPointF(point.x * uniteX, - point.y * uniteY);
            }

            painter.drawPolyline(polygon);
        }
    }
}
Esempio n. 7
0
/*!
  Draw symbols

  \param painter Painter
  \param symbol Curve symbol
  \param xMap x map
  \param yMap y map
  \param canvasRect Contents rectangle of the canvas
  \param from Index of the first point to be painted
  \param to Index of the last point to be painted

  \sa setSymbol(), drawSeries(), drawCurve()
*/
void QwtPlotCurve::drawSymbols( QPainter *painter, const QwtSymbol &symbol,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect, int from, int to ) const
{
    QwtPointMapper mapper;
    mapper.setFlag( QwtPointMapper::RoundPoints, 
        QwtPainter::roundingAlignment( painter ) );
    mapper.setFlag( QwtPointMapper::WeedOutPoints, 
        testPaintAttribute( QwtPlotCurve::FilterPoints ) );
    mapper.setBoundingRect( canvasRect );

    const int chunkSize = 500;

    for ( int i = from; i <= to; i += chunkSize )
    {
        const int n = qMin( chunkSize, to - i + 1 );

        const QPolygonF points = mapper.toPointsF( xMap, yMap,
            data(), i, i + n - 1 );

        if ( points.size() > 0 )
            symbol.drawSymbols( painter, points );
    }
}
Esempio n. 8
0
bool isSelfintersectingPolygon(QPolygonF polygon)
{
  assertPolygonIsClosed(polygon);
  int n = polygon.size() - 1;  // cut off last vertex
  for (int i1 = 0; i1 < n; i1++) {
    int i2 = (i1 + 1) % n;
    for (int j1 = 0; j1 < n; j1++) {
      int j2 = (j1 + 1) % n;
      if (i1 != j1 && i1 != j2 && i2 != j1
          && testSegmentsCross(polygon[i1], polygon[i2], polygon[j1], polygon[j2]))
        return true;
    }
  }
  return false;
}
qreal FlyThroughTask::calculateFlightPerformance(const QList<Position> &positions,
                                                 const QPolygonF &geoPoly,
                                                 const UAVParameters &)
{
    //First, see if one of the points is within the polygon
    foreach(const Position& pos, positions)
    {
        if (geoPoly.containsPoint(pos.lonLat(), Qt::OddEvenFill))
            return this->maxTaskPerformance();
    }

    //if that fails, take the distance to the last point
    Position goalPos(geoPoly.boundingRect().center(),
                     positions.first().altitude());

    const Position& last = positions.last();
    QVector3D enuPos = Conversions::lla2enu(last, goalPos);
    qreal dist = enuPos.length();

    const qreal stdDev = 90.0;
    qreal toRet = 100*FlightTask::normal(dist,stdDev,2000);

    return qMin<qreal>(toRet,this->maxTaskPerformance());
}
Esempio n. 10
0
void PathPaintEngine::drawPath(const QPainterPath& path)
{
	if (!dev)
		return;

	if(!isCosmetic)
	{
		QList<QPolygonF> polys = path.toSubpathPolygons();
		for (int i = 0; i < polys.size(); ++i)
		{
			if(dashPattern.empty()) dev->addPath(transform.map(polys[i]));
			else
			{
				QPolygonF polytemp = transform.map(polys[i]), newpoly;
				int  dashtoggle = 1, dashi=0, j = 0;
				qreal actualdashsize = dashPattern[dashi];
				QPointF origin = QPointF(polytemp[j]), testp;
				j++; 
				do
				{
					newpoly = QPolygonF();
					newpoly.append(origin);
					do
					{
						testp = polytemp[j];
						origin = QPointF(getPointAtLenght(QPointF(origin), polytemp[j], actualdashsize));
						if (essentiallyEqual(origin.x(), polytemp[j].x(), 0.01 ) && approximatelyEqual(origin.y(), polytemp[j].y(),0.01) && j+1 < polytemp.size()) 
						{
							origin = polytemp[j];
							j++;
							testp =  polytemp[j];
						}
						newpoly.append(origin);
					
					}while(definitelyGreaterThan(actualdashsize,0.0,0.1) && testp!=origin);
					if(dashtoggle == 1)
					{
						dev->addPath(newpoly);
					}
					dashtoggle = dashtoggle * -1;
					dashi++;
					if(dashi >= dashPattern.size()) dashi=0;
					actualdashsize = dashPattern[dashi];
				}while(!essentiallyEqual(origin.x(), polytemp[j].x(), 0.001 ) || !essentiallyEqual(origin.y(), polytemp[j].y(),0.001));
			}
		}
	}
}
Esempio n. 11
0
void cubic_subdivide(QPolygonF& p, size_t j, int recurse = 1)
{
  assert(j > 0);
  assert(j < uint(p.size()) - 1);


  cubic_average(p, j);

  if(--recurse >= 0) {
    point_insert(p, j + 1);
    point_insert(p, j);
    cubic_subdivide(p, j + 1, recurse);
    cubic_subdivide(p, j, recurse);
  }

}
Esempio n. 12
0
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();
  }
}
Esempio n. 13
0
void Polygon::_constrainVertex(const QPolygonF& polygon, int i, QPointF& v)
{
    // Weird, but nothing to do.
    if (polygon.size() <= 3)
        return;

    // Save previous position of vertex.
    QPointF prevV = polygon.at(i);

    // Look at the two adjunct segments to vertex i and see if they
    // intersect with any non-adjacent segments.

    // Construct the list of segments (with the new candidate vertex).
    QVector<QLineF> segments = _getSegments(polygon);
    int prev = wrapAround(i - 1, segments.size());
    int next = wrapAround(i + 1, segments.size());
    segments[prev] = QLineF(polygon.at(prev), v);
    segments[i]    = QLineF(v, polygon.at(next));

    // We now stretch segments a little bit to cope with approximation errors.
    for (QVector<QLineF>::Iterator it = segments.begin(); it != segments.end(); ++it)
    {
        QLineF& seg = *it;
        QPointF p1 = seg.p1();
        QPointF p2 = seg.p2();
        seg.setP1( p1 + (p1 - p2) * 0.35f);
        seg.setP2( p2 + (p2 - p1) * 0.35f);
    }

    // For each adjunct segment.
    for (int adj=0; adj<2; adj++)
    {
        int idx = wrapAround(i + adj - 1, segments.size());
        for (int j=0; j<segments.size(); j++)
        {
            // If the segment to compare to is valid (ie. if it is not
            // the segment itself nor an adjacent one) then check for
            // intersection.
            if (j != idx &&
                    j != wrapAround(idx-1, segments.size()) &&
                    j != wrapAround(idx+1, segments.size()))
            {
                QPointF intersection;
                if (segments[idx].intersect(segments[j], &intersection) == QLineF::BoundedIntersection)
                {
                    // Rearrange segments with new position at intersection point.
                    v = intersection;
                    segments[prev] = QLineF(polygon.at(prev), v);
                    segments[i]    = QLineF(v, polygon.at(next));
                }
            }
        }
    }
}
Esempio n. 14
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;
}
void ArrowItem::paint(QPainter *painter) {
  painter->drawLine(line());

  QBrush b = brush();
  b.setStyle(Qt::SolidPattern);
  b.setColor(pen().color());
  setBrush(b);

  start.clear();
  end.clear();
  if (_startArrowHead) {
    qreal deltax = view()->scaledFontSize(_startArrowScale, *painter->device())*0.5; // in points
    deltax *= painter->device()->logicalDpiX()/72.0; // convert to 'pixels'.
    qreal theta = atan2(qreal(line().y2() - line().y1()), qreal(line().x2() - line().x1())) - M_PI / 2.0;
    qreal sina = sin(theta);
    qreal cosa = cos(theta);
    qreal yin = sqrt(3.0) * deltax;
    qreal x1, y1, x2, y2;
    QMatrix m(cosa, sina, -sina, cosa, 0.0, 0.0);

    m.map( deltax, yin, &x1, &y1);
    m.map(-deltax, yin, &x2, &y2);

    QPolygonF pts;
    pts.append(line().p1());
    pts.append(line().p1() + QPointF(x1, y1));
    pts.append(line().p1() + QPointF(x2, y2));
    painter->drawPolygon(pts);
    start = pts;
  }

  if (_endArrowHead) {
    qreal deltax = view()->scaledFontSize(_endArrowScale, *painter->device())*0.5;
    deltax *= painter->device()->logicalDpiX()/72.0; // convert points to 'pixels'.
    qreal theta = atan2(qreal(line().y1() - line().y2()), qreal(line().x1() - line().x2())) - M_PI / 2.0;
    qreal sina = sin(theta);
    qreal cosa = cos(theta);
    qreal yin = sqrt(3.0) * deltax;
    qreal x1, y1, x2, y2;
    QMatrix m(cosa, sina, -sina, cosa, 0.0, 0.0);

    m.map( deltax, yin, &x1, &y1);
    m.map(-deltax, yin, &x2, &y2);

    QPolygonF pts;
    pts.append(line().p2());
    pts.append(line().p2() + QPointF(x1, y1));
    pts.append(line().p2() + QPointF(x2, y2));
    painter->drawPolygon(pts);
    end = pts;
  }
}
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;
}
// this method is factored out from LineDiagram::paint, and contains
// the common parts of the method that  previously implemented all
// chart types in one
void LineDiagram::LineDiagramType::paintElements(
    PaintContext* ctx,
    DataValueTextInfoList& list,
    LineAttributesInfoList& lineList,
    LineAttributes::MissingValuesPolicy policy )
{
    Q_UNUSED( policy );
    // paint all lines and their attributes
    const PainterSaver painterSaver( ctx->painter() );
    if ( diagram()->antiAliasing() )
        ctx->painter()->setRenderHint ( QPainter::Antialiasing );
    LineAttributesInfoListIterator itline ( lineList );

    QBrush curBrush;
    QPen curPen;
    QPolygonF points;
    while ( itline.hasNext() ) {
        const LineAttributesInfo& lineInfo = itline.next();
        const QModelIndex& index = lineInfo.index;
        const ThreeDLineAttributes td = diagram()->threeDLineAttributes( index );
        const ValueTrackerAttributes vt = diagram()->valueTrackerAttributes( index );

        if( td.isEnabled() ){
            paintThreeDLines( ctx, index, lineInfo.value, lineInfo.nextValue, td.depth() );
        } else {
            const QBrush br( diagram()->brush( index ) );
            const QPen pn( diagram()->pen( index ) );
            if( points.count() && points.last() == lineInfo.value && curBrush == br && curPen == pn ) {
                // line goes from last value in points to lineInfo.nextValue
                reverseMapper().addLine( lineInfo.index.row(), lineInfo.index.column(), points.last(), lineInfo.nextValue );
                points << lineInfo.nextValue;
            } else {
                if( points.count() )
                    paintPolyline( ctx, curBrush, curPen, points );
                curBrush = br;
                curPen   = pn;
                points.clear();
                // line goes from lineInfo.value to lineInfo,nextValue
                reverseMapper().addLine( lineInfo.index.row(), lineInfo.index.column(), lineInfo.value, lineInfo.nextValue );
                points << lineInfo.value << lineInfo.nextValue;
            }
        }

        if( vt.isEnabled() )
            paintValueTracker( ctx, vt, lineInfo.value );
    }
    if( points.count() )
        paintPolyline( ctx, curBrush, curPen, points );
    // paint all data value texts and the point markers
    paintDataValueTextsAndMarkers( diagram(), ctx, list, true );
}
Esempio n. 18
0
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 ] );
  }
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
// ============================================================================
/// Splits polygon in two
QList<QPolygonF> splitPolygonRandomly( const QPolygonF& polygon, QLineF* pdebugout )
{
	QRectF br = polygon.boundingRect();
	
	// get random angle on cutting
	double angle = random01()* 6.28;
	
	// cut throught the center
	QPointF center = br.center();
	double upper = br.width() + br.height(); // upper bound for any of the polygon's dimensions
	
	QPointF p1( center.x() - upper*sin(angle), center.y() - upper*cos(angle) );
	QPointF p2( center.x() + upper*sin(angle), center.y() + upper*cos(angle) );
	
	// debug
	if ( pdebugout ) *pdebugout = QLineF( p1, p2 );
	
	return splitPolygon( polygon, QLineF( p1, p2 ) );
}
Esempio n. 21
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;
}
Esempio n. 22
0
QPolygonF ObstacleBitmap::minkowskiSums(const QPolygonF& polygonV, const QPolygonF& polygonW){
	
	std::vector<QPointF> vertexV = initPolygonVertex(findFirstVertex(polygonV), polygonV);
	std::vector<QPointF> vertexW = initPolygonVertex(findFirstVertex(polygonW), polygonW);

	QPolygonF ret;

	int i = 0;
	int j = 0;

    size_t vSize = vertexV.size();
    size_t wSize = vertexW.size();

	do{
		qreal x = vertexV.at(i%vSize).x() + vertexW.at(j%wSize).x();
		qreal y = vertexV.at(i%vSize).y() + vertexW.at(j%wSize).y();
		ret.push_back(QPointF(x, y));
		QPointF V = vertexV.at((i+1)%vSize) - vertexV.at(i%vSize);
		QPointF W = vertexW.at((j+1)%wSize) - vertexW.at(j%wSize);
		double angle1 = CoordinateTransform::toPositiveDegree(std::atan2(V.y(), V.x()));
		double angle2 = CoordinateTransform::toPositiveDegree(std::atan2(W.y(), W.x()));

		if(i == polygonV.size()){
			//if(angle1 == 0.0){
				angle1 = 360.0;
			//}
		}

		if(j == polygonW.size()){
			//if(angle2 == 0.0){
				angle2 = 360.0;
			//}
		}

		if(angle1 < angle2){
			++i;
		}
		else if(angle1 > angle2){
			++j;
		}
		else{
			++i;
			++j;
		}

	}while((i < polygonV.size()) || (j < polygonW.size()));

	return ret;
}
Esempio n. 23
0
QPolygonF caGraphics::rotateObject(int degrees, int w, int h, int linesize, const QPolygonF& object) {
    // rotate
    double resizeWidth=999.0, resizeHeight=999.0;
    QTransform transform = QTransform().rotate(degrees);
    QPolygonF rotated = transform.map(object);
    //printf("w,h of object  %f %f\n",object.boundingRect().width(), object.boundingRect().height());
    //printf("w,h of rotated %f %f\n",rotated.boundingRect().width(), rotated.boundingRect().height());

    // calculate resize factor so that polygon will fit into the designer rectangle
    if(rotated.boundingRect().width() > 0) {
        resizeWidth = (double)(w) / rotated.boundingRect().width();
    }
    if(rotated.boundingRect().height() > 0) {
        resizeHeight = (double)(h) / rotated.boundingRect().height();
    }
    double resize = qMin(resizeWidth, resizeHeight);
    //printf("resize %f %f final=%f\n",resizeWidth, resizeHeight, resize);
    transform = QTransform().scale(resize, resize);
    rotated = transform.map(rotated);

    // get center of rotated polygon
    double centerX = rotated.boundingRect().x() + rotated.boundingRect().width()/2.0;
    double centerY = rotated.boundingRect().y() + rotated.boundingRect().height()/2.0;
    //printf("center of rotated polygon %f %f\n", centerX, centerY);

    // get center of canvas
    double centerXorg = w/2.0;
    double centerYorg = h/2.0;
    //printf("center of canvas %f %f\n", centerXorg, centerYorg);

    // calculate translation
    double translateX = centerX - centerXorg - linesize/2;
    double translateY = centerY - centerYorg - linesize/2;
    //printf("translate %f %f\n", translateX, translateY);

    transform = QTransform().translate(-translateX, -translateY);
    rotated = transform.map(rotated);
    return rotated;
}
Esempio n. 24
0
uint ShadeWidget::colorAt(int x)
{
    generateShade();

    QPolygonF pts = m_hoverPoints->points();
    for (int i=1; i < pts.size(); ++i) {
        if (pts.at(i-1).x() <= x && pts.at(i).x() >= x) {
            QLineF l(pts.at(i-1), pts.at(i));
            l.setLength(l.length() * ((x - l.x1()) / l.dx()));
            return m_shade.pixel(qRound(qMin(l.x2(), (qreal(m_shade.width() - 1)))),
                                 qRound(qMin(l.y2(), qreal(m_shade.height() - 1))));
        }
    }
    return 0;
}
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;
}
Esempio n. 26
0
void EFX::preview(QPolygonF &polygon, Function::Direction direction, int startOffset) const
{
    int stepCount = 128;
    int step = 0;
    float stepSize = (float)(1) / ((float)(stepCount) / (M_PI * 2.0));

    float i = 0;
    float x = 0;
    float y = 0;

    /* Reset the polygon to fill it with new values */
    polygon.clear();

    /* Draw a preview of the effect */
    for (step = 0; step < stepCount; step++)
    {
        calculatePoint(direction, startOffset, i, &x, &y);
        polygon << QPointF(x, y);
        i += stepSize;
    }
}
Esempio n. 27
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 );
}
Esempio n. 28
0
void ArrowItem::paint(QPainter *painter) {
  painter->drawLine(line());

  start.clear();
  end.clear();
  if (_startArrowHead) {
    //FIXME: this assumes that pixelSize == pointSize, which it only might...
    double deltax = view()->defaultFont(_startArrowScale).pointSizeF()*0.5;
    double theta = atan2(double(line().y2() - line().y1()), double(line().x2() - line().x1())) - M_PI / 2.0;
    double sina = sin(theta);
    double cosa = cos(theta);
    double yin = sqrt(3.0) * deltax;
    double x1, y1, x2, y2;
    QMatrix m(cosa, sina, -sina, cosa, 0.0, 0.0);

    m.map( deltax, yin, &x1, &y1);
    m.map(-deltax, yin, &x2, &y2);

    QPolygonF pts;
    pts.append(line().p1());
    pts.append(line().p1() + QPointF(x1, y1));
    pts.append(line().p1() + QPointF(x2, y2));
    painter->drawPolygon(pts);
    start = pts;
  }

  if (_endArrowHead) {
    //FIXME: this assumes that pixelSize == pointSize, which it only might...
    double deltax = view()->defaultFont(_endArrowScale).pointSizeF()*0.5;
    double theta = atan2(double(line().y1() - line().y2()), double(line().x1() - line().x2())) - M_PI / 2.0;
    double sina = sin(theta);
    double cosa = cos(theta);
    double yin = sqrt(3.0) * deltax;
    double x1, y1, x2, y2;
    QMatrix m(cosa, sina, -sina, cosa, 0.0, 0.0);

    m.map( deltax, yin, &x1, &y1);
    m.map(-deltax, yin, &x2, &y2);

    QPolygonF pts;
    pts.append(line().p2());
    pts.append(line().p2() + QPointF(x1, y1));
    pts.append(line().p2() + QPointF(x2, y2));
    painter->drawPolygon(pts);
    end = pts;
  }
}
Esempio n. 29
0
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;
		}
	}
}
Esempio n. 30
0
/**
 * 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;
}