コード例 #1
0
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;
  }
}
コード例 #2
0
ファイル: lineHandler.cpp プロジェクト: Esenin/qreal
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();
	}
}
コード例 #3
0
ファイル: ClipPainter.cpp プロジェクト: shentok/marble
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;
            }
        }
    }
}
コード例 #4
0
ファイル: SMDItem.cpp プロジェクト: constrictor/Layoutie
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);
}
コード例 #5
0
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));
	}
}
コード例 #6
0
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;
}
コード例 #7
0
ファイル: arrow.cpp プロジェクト: AtlantisCD9/Qt
//! [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);
    }
}
コード例 #8
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()->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() );
    }
}
コード例 #9
0
ファイル: qwt_plot_histogram.cpp プロジェクト: Aconex/pcp
//! 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();
}
コード例 #10
0
ファイル: circleitem.cpp プロジェクト: RossWilliamson/kst_old
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;
  }
}
コード例 #11
0
ファイル: Arrow.cpp プロジェクト: skyrpex/Flat2D_old
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);
}
コード例 #12
0
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 );
}
コード例 #13
0
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;
}
コード例 #14
0
ファイル: qwt_spline.cpp プロジェクト: XelaRellum/qwt
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;
}   
コード例 #15
0
ファイル: gui_edge.cpp プロジェクト: MIPT-ILab/MIPT-Vis
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;
}
コード例 #16
0
ファイル: qgsnodeeditor.cpp プロジェクト: 3liz/Quantum-GIS
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();
  }
}
コード例 #17
0
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;
}
コード例 #18
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;
}
コード例 #19
0
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;
}
コード例 #20
0
ファイル: splinetest.cpp プロジェクト: Au-Zone/qwt
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 );
}
コード例 #21
0
ファイル: editpolygontool.cpp プロジェクト: Shorttail/tiled
/**
 * 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;
}
コード例 #22
0
ファイル: lineHandler.cpp プロジェクト: ZiminGrigory/qreal
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;
		}
	}
}
コード例 #23
0
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();
}
コード例 #24
0
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 );
}
コード例 #25
0
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 );
}
コード例 #26
0
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;
}
コード例 #27
0
ファイル: qwt_spline.cpp プロジェクト: XelaRellum/qwt
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;
}
コード例 #28
0
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 );
}
コード例 #29
0
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);

    }




}
コード例 #30
0
//----------------------------------------------------------------------------------------------
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);
    //}
}