QPainterPath CopyFilterGUIConnectionItem::shape() const { QLineF l = line(); QPainterPath path; path.setFillRule(Qt::WindingFill); double length = line().length(); if (length > 0) { double offset = min(length, maxArrowSize); QLineF unit = l.unitVector(); QLineF normal = l.normalVector().unitVector(); QPointF v(unit.dx(), unit.dy()); QPointF n(normal.dx(), normal.dy()); QPointF p2 = l.p2(); QPointF p3 = p2 - v * offset + 0.5 * n * offset; QPointF p4 = p2 - v * offset - 0.5 * n * offset; QPolygonF polygon; polygon.append(p4); polygon.append(p3); polygon.append(p2); path.addPolygon(polygon); QPolygonF polygon2; QPointF p1 = l.p1(); polygon2.append(p2 + 3 * n); polygon2.append(p2 - 2 * n); polygon2.append(p1 - 2 * n); polygon2.append(p1 + 3 * n); path.addPolygon(polygon2); if (factor != 1.0 || isDecibel) { QFont font; font.setPixelSize(10); QPointF center = (l.p1() + l.p2()) / 2; QString text = QString("%1").arg(factor); if (isDecibel) text += " dB"; QFontMetrics fontMetrics(font); QSizeF size = fontMetrics.size(0, text); size += QSizeF(2, 0); QRectF rect; rect.setSize(size); rect.moveCenter(center); path.addRoundedRect(rect.adjusted(-0.5, 0.5, 0.5, 0.5), 3, 3); } } return path; }
void CopyFilterGUIConnectionItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { QLineF l = line(); if (!l.isNull()) { painter->setBrush(Qt::black); if (isSelected()) { painter->setBrush(Qt::blue); painter->setPen(QPen(Qt::blue, 1.5)); } painter->drawLine(line()); double length = line().length(); double offset = min(length, maxArrowSize); QLineF unit = l.unitVector(); QLineF normal = l.normalVector().unitVector(); QPointF v(unit.dx(), unit.dy()); QPointF n(normal.dx(), normal.dy()); QPointF p2 = l.p2(); QPointF p3 = p2 - v * offset + 0.5 * n * offset; QPointF p4 = p2 - v * offset - 0.5 * n * offset; QPolygonF polygon; polygon.append(p2); polygon.append(p3); polygon.append(p4); painter->drawPolygon(polygon); if (factor != 1.0 || isDecibel) { QFont font = painter->font(); font.setPixelSize(10); painter->setFont(font); QPointF center = (l.p1() + l.p2()) / 2; QString text = QString("%1").arg(factor); if (isDecibel) text += " dB"; QSizeF size = painter->fontMetrics().size(0, text); size += QSizeF(2, 0); QRectF rect; rect.setSize(size); rect.moveCenter(center); painter->setBrush(Qt::white); painter->drawRoundedRect(rect.adjusted(-0.5, 0.5, 0.5, 0.5), 3, 3); painter->drawText(rect, Qt::AlignCenter, text); } } }
WebWheelEvent WebEventFactory::createWebWheelEvent(QWheelEvent* e, const QTransform& fromItemTransform) { float deltaX = 0; float deltaY = 0; float wheelTicksX = 0; float wheelTicksY = 0; WebWheelEvent::Granularity granularity = WebWheelEvent::ScrollByPixelWheelEvent; WebEvent::Modifiers modifiers = modifiersForEvent(e->modifiers()); double timestamp = currentTimeForEvent(e); if (e->orientation() == Qt::Horizontal) { deltaX = e->delta(); wheelTicksX = deltaX / 120.0f; } else { deltaY = e->delta(); wheelTicksY = deltaY / 120.0f; } // Since we report the scroll by the pixel, convert the delta to pixel distance using standard scroll step. // Use the same single scroll step as QTextEdit (in QTextEditPrivate::init [h,v]bar->setSingleStep) static const float cDefaultQtScrollStep = 20.f; // ### FIXME: Default from QtGui. Should use Qt platform theme API once configurable. const int wheelScrollLines = 3; deltaX = wheelTicksX * wheelScrollLines * cDefaultQtScrollStep; deltaY = wheelTicksY * wheelScrollLines * cDefaultQtScrollStep; // Transform the position and the pixel scrolling distance. QLineF transformedScroll = fromItemTransform.map(QLineF(e->posF(), e->posF() + QPointF(deltaX, deltaY))); IntPoint transformedPoint = transformedScroll.p1().toPoint(); IntPoint globalPoint = e->globalPosF().toPoint(); FloatSize transformedDelta(transformedScroll.dx(), transformedScroll.dy()); FloatSize wheelTicks(wheelTicksX, wheelTicksY); return WebWheelEvent(WebEvent::Wheel, transformedPoint, globalPoint, transformedDelta, wheelTicks, granularity, modifiers, timestamp); }
QLineF Robot::intersectDistance(QGraphicsLineItem *item, const double &baseAngle) const { QGraphicsScene *scene = item->scene(); if(!scene) return QLineF(0, 0, 0, 0); const double rad = (m_robot->rotation() + baseAngle) / 180.0 * M_PI; QLineF line(m_robot->pos(), m_robot->pos() + m_rangeLength * QPointF(cos(rad), sin(rad))); const QLineF unit = line.unitVector(); // qDebug() << unit.dx(); double xs = unit.dx(); double ys = unit.dy(); if(xs == 0.0) xs = 0.0001; if(ys == 0.0) ys = 0.0001; for(double i = 0; i < m_rangeLength; i += 1.0) { QRectF r(m_robot->x() + i * xs, m_robot->y() + i * ys, xs, ys); QList<QGraphicsItem *> items = scene->items(r, Qt::IntersectsItemBoundingRect, Qt::AscendingOrder); foreach(QGraphicsItem *t, items) { if(t->data(0) == BoardFile::Real) { line.setLength(i); return line; } } } return line; }
QRect CurveTracker::trackerRect( const QFont &font ) const { QRect r = QwtPlotPicker::trackerRect( font ); // align r to the first curve const QwtPlotItemList curves = plot()->itemList( QwtPlotItem::Rtti_PlotCurve ); if ( curves.size() > 0 ) { QPointF pos = invTransform( trackerPosition() ); const QLineF line = curveLineAt( static_cast<const QwtPlotCurve *>( curves[0] ), pos.x() ); if ( !line.isNull() ) { const double curveY = line.pointAt( ( pos.x() - line.p1().x() ) / line.dx() ).y(); pos.setY( curveY ); pos = transform( pos ); r.moveBottom( pos.y() ); } } return r; }
//---------------------------------------------------------------------------------------------- QPainterPath GraphEdgeView::shape() const { QPainterPath path;// = QGraphicsLineItem::shape(); 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); path.lineTo(myLine.p1()); path.lineTo(myLine.p2()); myLine = this->line(); myLine.translate(-dx * 4,-dy * 4); path.lineTo(myLine.p2()); path.lineTo(myLine.p1()); path.closeSubpath(); path.addPolygon(m_arrowHead); return path; }
void GEdge::adjust() { if (!source || !dest) return; QLineF * line = new QLineF (source->x(), source->y(), dest->x(), dest->y()); qreal length = line->length(); prepareGeometryChange(); if (length > qreal(20.)) { QPointF edgeOffset((line->dx() * 10) / length, (line->dy() * 10) / length); if (is_from_dummy_node) sourcePoint = line->p1(); else sourcePoint = line->p1() + edgeOffset; if (is_to_dummy_node) destPoint = line->p2(); else destPoint = line->p2() - edgeOffset; } else { sourcePoint = destPoint = line->p1(); } }
static inline QLineF qline_shifted(const QPointF &p1, const QPointF &p2, qreal offset) { QLineF l(p1, p2); QLineF ln = l.normalVector().unitVector(); l.translate(ln.dx() * offset, ln.dy() * offset); return l; }
void CCJKShapeLine::DrawArrow(QPainter *painter, const QLineF &line) { CJK_D(CCJKShapeLine); double angle = ::acos(line.dx() / line.length()); if (line.dy() >= 0) angle = (CJKPi * 2) - angle; if (d->arrowBeginType != ArrowNone) { qreal arrowSize = d->pen.width() + d->arrowBeginSize; QPointF arrowP1; QPointF arrowP2; arrowP1 = line.p1() + QPointF(sin(angle + CJKPi / 3) * arrowSize, cos(angle + CJKPi / 3) * arrowSize); arrowP2 = line.p1() + QPointF(sin(angle + CJKPi - CJKPi / 3) * arrowSize, cos(angle + CJKPi - CJKPi / 3) * arrowSize); DrawArrow(painter, d->arrowBeginType, line.p1(), arrowP1, arrowP2, arrowSize); } if (d->arrowEndType != ArrowNone) { qreal arrowSize = d->pen.width() + d->arrowEndSize; QPointF arrowP1; QPointF arrowP2; arrowP1 = line.p2() - QPointF(sin(angle + CJKPi / 3) * arrowSize, cos(angle + CJKPi / 3) * arrowSize); arrowP2 = line.p2() - QPointF(sin(angle + CJKPi - CJKPi / 3) * arrowSize, cos(angle + CJKPi - CJKPi / 3) * arrowSize); DrawArrow(painter, d->arrowEndType, line.p2(), arrowP1, arrowP2, arrowSize); } }
void GraphicsPathItem::paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setPen (QPen (QBrush (*_color), 0.1, Qt::SolidLine)); painter->setBrush (QBrush (*_color)); painter->drawLine (_start, _end); QPainterPath path; QLineF unit = QLineF (_start, _end).unitVector (); QLineF normal = unit.normalVector (); QPointF u (unit.dx (), unit.dy ()); QPointF v (normal.dx (), normal.dy ()); QPointF middle = 0.5 * (QPointF(_start) + QPointF (_end)); path.moveTo (middle + 0.4*u); path.lineTo (middle - 0.2*u + 0.2*v); path.lineTo (middle - 0.2*u - 0.2*v); path.closeSubpath (); painter->drawPath (path); }
/** * Calcul le point sur la fleche le plus près du point donné en parametre * @brief Fleche::PointLePlusPres * @param Position La osition à analyser * @return La position sur la fleche la plus proche */ QPointF Fleche::PointLePlusPres(QPointF Position) { //Calcul de la projection orthogonale de la position de la souris sur les segments verticaux de la flèche. QPointF Retour ; QPointF Projection ; qreal Distance (0); qreal DistanceMini(INFINITY) ; QLineF LigneBase ; QLineF LigneSourisProj ; LigneSourisProj.setPoints(Position, Projection); //Pour tout les segments for(register int i = 0; i < this->ListePoints.length() -1; i++) { LigneBase.setPoints(this->ListePoints[i], this->ListePoints[i+1]); //S'il sont verticaux if(LigneBase.dx() == 0) { //On calcul les coordonnées du point Projection.setX(this->ListePoints[i].x()); Projection.setY(Position.y()); //Si le point sort du segment if(Projection.y() < this->ListePoints[i].y() || Projection.y() > this->ListePoints[i+1].y()) { QLineF LigneSourisP1 ; QLineF LigneSourisP2 ; LigneSourisP1.setPoints(Position, this->ListePoints[i]); LigneSourisP2.setPoints(Position, this->ListePoints[i+1]); //On le recale sur l'extrémité la plus proche if(LigneSourisP1.length() < LigneSourisP2.length()) { Projection = this->ListePoints[i] ; } else { Projection = this->ListePoints[i+1] ; } } //On renvois le point le plus proche de la souris Distance = LigneSourisProj.length() ; if(Distance < DistanceMini) { Retour = Projection ; DistanceMini = Distance ; } } } return Retour; }
/*! \fn qreal QLineF::angle(const QLineF &line) const \obsolete Returns the angle (in degrees) between this line and the given \a line, taking the direction of the lines into account. If the lines do not intersect within their range, it is the intersection point of the extended lines that serves as origin (see QLineF::UnboundedIntersection). \table \row \o \inlineimage qlinef-angle-identicaldirection.png \o \inlineimage qlinef-angle-oppositedirection.png \endtable When the lines are parallel, this function returns 0 if they have the same direction; otherwise it returns 180. \sa intersect() */ qreal QLineF::angle(const QLineF &l) const { if (isNull() || l.isNull()) return 0; qreal cos_line = (dx()*l.dx() + dy()*l.dy()) / (length()*l.length()); qreal rad = 0; // only accept cos_line in the range [-1,1], if it is outside, use 0 (we return 0 rather than PI for those cases) if (cos_line >= -1.0 && cos_line <= 1.0) rad = acos( cos_line ); return rad * 360 / M_2PI; }
void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { if ( isSelected() ) { QPen pen(color_selected,2); pen.setCosmetic(true); painter->setPen(pen); QLineF nv = to_line().normalVector(); nv.setLength((Node::external_radius()-2)/painter->matrix().m11()); painter->drawLine(to_line().translated(nv.dx(),nv.dy())); painter->drawLine(to_line().translated(-nv.dx(),-nv.dy())); } if ( visible && highlighted ) m_style.edge_type->paint_highlighted(painter,*this); else if ( visible || highlighted ) m_style.edge_type->paint_regular(painter,*this); }
QString CurveTracker::curveInfoAt( const QwtPlotCurve *curve, const QPointF &pos ) const { const QLineF line = curveLineAt( curve, pos.x() ); if ( line.isNull() ) return QString::null; QPointF p = line.pointAt(( pos.x() - line.p1().x() ) / line.dx()); QString info( "<font color=""%1"">%2 / %3</font>" ); return info.arg( curve->pen().color().name() ).arg( p.y() ).arg(p.x()); }
QPolygonF QGVEdge::toBox(const QLineF &line) const { QLineF n = line.normalVector(); QPointF o(n.dx() * 0.5, n.dy() * 0.5); QPolygonF polygon; polygon.append(line.p1() + o); polygon.append(line.p2() + o); polygon.append(line.p2() - o); polygon.append(line.p1() - o); return polygon; }
QPolygonF QGVEdge::toArrow(const QLineF &line) const { QLineF n = line.normalVector(); QPointF o(n.dx() / 3.0, n.dy() / 3.0); //Only support normal arrow type QPolygonF polygon; polygon.append(line.p1() + o); polygon.append(line.p2()); polygon.append(line.p1() - o); return polygon; }
Position FractalPresenter::positionFromTransform( const QTransform& transform ) { QPointF center( m_resolution.width() / 2.0, m_resolution.height() / 2.0 ); QLineF line( center, QPointF( center.x() + m_resolution.height(), center.y() ) ); QLineF mapped = preciselyMap( transform, line ); Position position; position.setCenter( mapped.p1() ); position.setZoomFactor( -log10( mapped.length() ) ); position.setAngle( -atan2( mapped.dy(), mapped.dx() ) * 180.0 / M_PI ); if ( position.angle() < 0.0 ) position.setAngle( position.angle() + 360.0 ); return position; }
void tst_QLine::testNormalVector() { QFETCH(double, x1); QFETCH(double, y1); QFETCH(double, x2); QFETCH(double, y2); QFETCH(double, nvx); QFETCH(double, nvy); QLineF l(x1, y1, x2, y2); QLineF n = l.normalVector(); QCOMPARE(l.x1(), n.x1()); QCOMPARE(l.y1(), n.y1()); QCOMPARE(n.dx(), qreal(nvx)); QCOMPARE(n.dy(), qreal(nvy)); }
QPolygonF GraphicalRobotElement::calculateArrowHeadPosition (QLineF aLine) { int arrowSize = 10; QPolygonF polyF; QLineF Line; Line.setP1 (aLine.p2() ); Line.setP2 (aLine.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); polyF.clear(); polyF << Line.p1() << arrowP1 << arrowP2; return polyF; }
void Edge::adjust() { if (!m_source_node || !m_dest_node) return; const QLineF line(mapFromItem(m_source_node, 0, 0), mapFromItem(m_dest_node, 0, 0)); const double length{line.length()}; prepareGeometryChange(); if (length > 20.0) { const QPointF edgeOffset((line.dx() * 10) / length, (line.dy() * 10) / length); m_source_point = line.p1() + edgeOffset; m_dest_point = line.p2() - edgeOffset; } else { m_source_point = m_dest_point = line.p1(); } }
qreal Slit::scalar(const Ray * ray) const { QLineF vector = ray->line(); qreal rx = vector.x1(); //x coordinate of ray starting point qreal ry = vector.y1(); //y coordinate of ray starting point qreal rdx = vector.dx(); //horizontal component of the ray's vector qreal rdy = vector.dy(); //vertical component of the ray's vector //calculate on which side of a ray do the slit's edges lie qreal l = rdy * (m_leftEdge.x() - rx) - rdx * (m_leftEdge.y() - ry); qreal r = rdy * (m_rightEdge.x() - rx) - rdx * (m_rightEdge.y() - ry); qreal sl = rdy * (m_leftSlitEdge.x() - rx) - rdx * (m_leftSlitEdge.y() - ry); qreal sr = rdy * (m_rightSlitEdge.x() - rx) - rdx * (m_rightSlitEdge.y() - ry); //pair of points lie on the same side of ray - intersection impossible if(((Settings::fuzzyIsGreaterThanZero(l) && Settings::fuzzyIsGreaterThanZero(sl)) || (Settings::fuzzyIsLessThanZero(l) && Settings::fuzzyIsLessThanZero(sl)))&&((Settings::fuzzyIsGreaterThanZero(r) && Settings::fuzzyIsGreaterThanZero(sr)) || (Settings::fuzzyIsLessThanZero(r) && Settings::fuzzyIsLessThanZero(sr)))) return -1.0; qreal sx = m_leftEdge.x(); //x coordinate of slit segment edge qreal sy = m_leftEdge.y(); //y coordinate of slit segment edge qreal sdx = m_rightEdge.x() - sx; //horizontal component of the slit segment's vector qreal sdy = m_rightEdge.y() - sy; //vertical component of the slit segment's vector //plug: (x = rx + d * rdx) and (y = ry + d * rdy) into line equation: (sdy * (x - sx) - sdx * (y - sy) = 0) and solve for d return (sdx * ry - sdy * rx + sdy * sx - sdx * sy) / (sdy * rdx - sdx * rdy); }
void BezierCubicItem::controlPointMoved(int index) { // solid move if (index == 0 || index == 2) { QLineF l = index == 0 ? m_l1->line() : m_l2->line(); if (!l.isNull()) m_cps[index + 1]->setPos(m_cps[index]->pos() + QPointF(l.dx(), l.dy())); } // update line if (index < 2) m_l1->setLine(QLineF(m_cps[0]->pos(), m_cps[1]->pos())); else m_l2->setLine(QLineF(m_cps[2]->pos(), m_cps[3]->pos())); // update path QPainterPath path(m_cps[0]->pos()); path.cubicTo(m_cps[1]->pos(), m_cps[3]->pos(), m_cps[2]->pos()); m_path->setPath(path); emit shapeChanged(path); }
void EdgeItem::adjust() { if (m_startNode == nullptr || m_endNode == nullptr) return; prepareGeometryChange(); // update the line object m_line.setP1(m_startNode->pos()); m_line.setP2(m_endNode->pos()); // recalculate the start and end positions if (m_line.length() > 0.0) { QLineF trans = m_line.unitVector(); trans.setLength(NodeItem::Radius); m_line.translate(trans.dx(), trans.dy()); float newLength = m_line.length() - 2 * NodeItem::Radius; if (m_arrowhead) { newLength -= ArrowHeight / 2; } m_line.setLength(newLength); } }
void UBGraphicsDelegateFrame::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (None == mCurrentTool) return; QLineF move = QLineF(mStartingPoint, event->scenePos()); qreal moveX = move.length() * cos((move.angle() - mAngle) * PI / 180); qreal moveY = -move.length() * sin((move.angle() - mAngle) * PI / 180); qreal width = delegated()->boundingRect().width() * mTotalScaleX; qreal height = delegated()->boundingRect().height() * mTotalScaleY; if (mOperationMode == Scaling) { if(!rotating()) { mTranslateX = moveX; // Perform the resize if (resizingBottomRight()) { // ----------------------------------------------------- // ! We want to keep the aspect ratio with this resize ! // ----------------------------------------------------- qreal scaleX; qreal scaleY; if(!mMirrorX) { scaleX = (width + moveX) / width; } else { scaleX = (width - moveX) / width; } if(!mMirrorY) { scaleY = (height + moveY) / height; } else { scaleY = (height - moveY) / height; } qreal scaleFactor = (scaleX + scaleY) / 2; // Do not allow resizing of image size under frame size if (canResizeBottomRight(width, height, scaleFactor)) { if (mRespectRatio) { mScaleX = scaleFactor; mScaleY = scaleFactor; } else { mScaleX = scaleX; mScaleY = scaleY; } } } else if (resizingLeft() || resizingRight()) { if(width != 0) { qreal scaleX = 0.0; if(resizingLeft()) { scaleX = (width - moveX) / width; } else if(resizingRight()) { scaleX = (width + moveX) / width; } if(mDelegate->isFlippable() && qAbs(scaleX) != 0) { if((qAbs(width * scaleX)) < 2*mFrameWidth) { bool negative = (scaleX < 0)?true:false; if(negative) { if(mMirrorX) scaleX = 2*mFrameWidth/width; else scaleX = -2*mFrameWidth/width; } else { scaleX = -1; mFlippedX = !mFlippedX; } } mScaleX = scaleX; } else if (scaleX > 1 || (width * scaleX) > 2 * mFrameWidth) { mScaleX = scaleX; if(resizingLeft()) { mTranslateX = moveX; } } } } else if(resizingTop() || resizingBottom()) { if(height != 0) { qreal scaleY = 0.0; if(resizingTop()) { scaleY = (height - moveY) / height; } else if(resizingBottom()) { scaleY = (height + moveY) / height; } if(mDelegate->isFlippable() && qAbs(scaleY) != 0) { if((qAbs(height * scaleY)) < 2*mFrameWidth) { bool negative = (scaleY < 0)?true:false; if(negative) { if(mMirrorY) scaleY = 2*mFrameWidth/width; else scaleY = -2*mFrameWidth/width; } else { scaleY = -1; mFlippedY = !mFlippedY; } } mScaleY = scaleY; } else if (scaleY > 1 || (height * scaleY) > 2 * mFrameWidth) { mScaleY = scaleY; if(resizingTop()) { mTranslateY = moveY; } } } } } } if (rotating()) { mTranslateX = 0; mTranslateY = 0; QLineF startLine(sceneBoundingRect().center(), event->lastScenePos()); QLineF currentLine(sceneBoundingRect().center(), event->scenePos()); mAngle += startLine.angleTo(currentLine); if ((int)mAngle % 45 >= 45 - mAngleTolerance || (int)mAngle % 45 <= mAngleTolerance) { mAngle = qRound(mAngle / 45) * 45; mAngleOffset += startLine.angleTo(currentLine); if ((int)mAngleOffset % 360 > mAngleTolerance && (int)mAngleOffset % 360 < 360 - mAngleTolerance) { mAngle += mAngleOffset; mAngleOffset = 0; } } else if ((int)mAngle % 30 >= 30 - mAngleTolerance || (int)mAngle % 30 <= mAngleTolerance) { mAngle = qRound(mAngle / 30) * 30; mAngleOffset += startLine.angleTo(currentLine); if ((int)mAngleOffset % 360 > mAngleTolerance && (int)mAngleOffset % 360 < 360 - mAngleTolerance) { mAngle += mAngleOffset; mAngleOffset = 0; } } setCursorFromAngle(QString::number((int)mAngle % 360)); } else if (moving()) { mTranslateX = move.dx(); mTranslateY = move.dy(); moveLinkedItems(move); } if (mOperationMode == Scaling || moving() || rotating()) { QTransform tr = buildTransform(); if (resizingRight() || resizingBottom() || resizingBottomRight()) { QPointF ref; // we just detects coordinates of corner before and after scaling and then moves object at diff between them. if (resizingBottomRight() && (mMirrorX || mMirrorY)) { if (mFlippedX && !mMirrorX && mFlippedY)// && !mMirrorY) { mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).x() - tr.map(delegated()->boundingRect().bottomLeft()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).y() - tr.map(delegated()->boundingRect().bottomLeft()).y(); } else if ((mFlippedX || mMirrorX) && (mFlippedY || mMirrorY)) { mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomRight()).x() - tr.map(delegated()->boundingRect().bottomRight()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomRight()).y() - tr.map(delegated()->boundingRect().bottomRight()).y(); } else if (mFlippedX || mMirrorX) { mTranslateX += mInitialTransform.map(delegated()->boundingRect().topRight()).x() - tr.map(delegated()->boundingRect().topRight()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().topRight()).y() - tr.map(delegated()->boundingRect().topRight()).y(); } else if (mFlippedY || mMirrorY) { mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).x() - tr.map(delegated()->boundingRect().bottomLeft()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).y() - tr.map(delegated()->boundingRect().bottomLeft()).y(); } else { mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomRight()).x() - tr.map(delegated()->boundingRect().bottomRight()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomRight()).y() - tr.map(delegated()->boundingRect().bottomRight()).y(); } } else { mTranslateX += mInitialTransform.map(delegated()->boundingRect().topLeft()).x() - tr.map(delegated()->boundingRect().topLeft()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().topLeft()).y() - tr.map(delegated()->boundingRect().topLeft()).y(); } } else if (resizingTop() || resizingLeft()) { QPointF bottomRight = tr.map(delegated()->boundingRect().bottomRight()); QPointF fixedPoint = mInitialTransform.map(delegated()->boundingRect().bottomRight()); mTranslateX += fixedPoint.x() - bottomRight.x(); mTranslateY += fixedPoint.y() - bottomRight.y(); } delegated()->setTransform(buildTransform()); } else // resizing/resizing horizontally { if (resizingBottomRight()) { static QSizeF incV = QSizeF(); static QSizeF incH = QSizeF(); if (mMirrorX && mMirrorY) mCurrentTool = ResizeTop; else mCurrentTool = ResizeBottom; incV = resizeDelegate(moveX, moveY); mOriginalSize += incV; if (mMirrorX && mMirrorY) mCurrentTool = ResizeLeft; else mCurrentTool = ResizeRight; move = QLineF(event->lastScenePos(), event->scenePos()); moveX = move.length() * cos((move.angle() - mAngle) * PI / 180); moveY = -move.length() * sin((move.angle() - mAngle) * PI / 180); mFixedPoint = getFixedPointFromPos(); incH = resizeDelegate(moveX, moveY); mOriginalSize -= incV; mOriginalSize += incH; mCurrentTool = ResizeBottomRight; } else resizeDelegate(moveX, moveY); } event->accept(); }
void EdgeItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { if ( option->levelOfDetail < 0.1) return; /** Do not draw edges when adjacent nodes intersect */ QPolygonF pred_rect = mapFromItem( pred()->item(), pred()->item()->boundingRect()); QPolygonF succ_rect = mapFromItem( succ()->item(), succ()->item()->boundingRect()); if ( !succ_rect.intersected( pred_rect).isEmpty()) return; static const qreal spline_detail_level = 0.4; static const qreal draw_arrow_detail_level = 0.3; QPointF curr_point; QLineF line = QLineF(); curr_point = srcP; QPointF nextToDst = srcP; qreal opacity = min<qreal>( edge()->pred()->item()->opacityLevel(), edge()->succ()->item()->opacityLevel()); line.setP1( nextToDst); line.setP2( dstP); QPainterPath path( srcP); QPainterPathStroker stroker; stroker.setWidth( 0); if ( edge()->isSelf()) { path = selfEdgePath(); } else if ( option->levelOfDetail >= spline_detail_level) { path.cubicTo( cp1, cp2, dstP); } //path = stroker.createStroke(path); if ( nextToDst == dstP) return; //Set opacity if ( edge()->graph()->view()->isContext()) painter->setOpacity( opacity); QPen pen( option->palette.foreground().color(), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); if ( isNotNullP( edge()->style())) { pen = edge()->style()->pen(); } // Draw the line itself if ( option->levelOfDetail >= spline_detail_level) { if ( option->state & QStyle::State_Selected) { pen.setWidthF( pen.widthF() + 1); } } else { pen = QPen( pen.color(),1); } painter->setPen( pen); //Draw edge if ( edge()->isSelf() || option->levelOfDetail >= spline_detail_level) { painter->drawPath( path); } else { painter->drawLine( line); } // Draw the arrows if there's enough room and level of detail is appropriate if ( option->levelOfDetail >= draw_arrow_detail_level) { double angle = ::acos(line.dx() / line.length()); if ( line.dy() >= 0) angle = TwoPi - angle; QPointF destArrowP1; QPointF destArrowP2; /* NOTE: Qt::black can be replaced by option->palette.foreground().color() */ if ( isNotNullP( edge()->style())) { painter->setBrush( edge()->style()->pen().color()); } else { painter->setBrush(option->palette.foreground().color()); } if ( edge()->isSelf()) { angle = -2* Pi/3; } destArrowP1 = dstP + QPointF( sin(angle - Pi / 3) * arrowSize, cos(angle - Pi / 3) * arrowSize); destArrowP2 = dstP + QPointF( sin(angle - Pi + Pi / 3) * arrowSize, cos(angle - Pi + Pi / 3) * arrowSize); pen.setStyle( Qt::SolidLine); painter->setPen( pen); if ( succ()->isSimple()) { QPainterPath arrow_path; arrow_path.addPolygon( QPolygonF() << dstP << destArrowP1 << destArrowP2 << dstP); //path = path.united( arrow_path); painter->drawPolygon(QPolygonF() << dstP << destArrowP1 << destArrowP2); } } painter->setOpacity( 1); #ifdef SHOW_CONTROL_POINTS /** For illustrative purposes */ painter->setPen(QPen(Qt::gray, 1, Qt::DashLine, Qt::RoundCap, Qt::RoundJoin)); if ( !edge()->isSelf()) { painter->drawLine( srcP, dstP); painter->drawLine( srcP, cp1); painter->drawLine( cp2, dstP); } painter->setPen(QPen(Qt::red, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawPoint( srcP); painter->setPen(QPen(Qt::blue, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawPoint( dstP); painter->setPen(QPen(Qt::green, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawPoint( cp1); #endif }
void item_rectangles::drawLine(QGraphicsScene *scene, QLineF lineItem, QSize smallRect) { clearArray(); int h_dir=0; int v_dir=0; int angle = qRound(lineItem.angle()); //Calculate direction switch(angle) { case 0: h_dir=1; break; case 90: v_dir=-1; break; case 180: h_dir=-1; break; case 270: v_dir=1; break; default: if((angle>0)&&(angle<90)) { h_dir=1; v_dir=-1; } else if((angle>90)&&(angle<180)) { h_dir=-1; v_dir=-1; } else if((angle>180)&&(angle<270)) { h_dir=-1; v_dir=1; } else if((angle>270)&&(angle<360)) { h_dir=1; v_dir=1; } break; } long x = lineItem.p1().x(); long y = lineItem.p1().y(); long tW = fabs(qRound(lineItem.dx())); //targetWidth long tH = fabs(qRound(lineItem.dy())); //targetHeight QBrush brush = QBrush(Qt::darkYellow); for(int k=0,l=0, i=0, j=0; (i<=tW)&&(j<=tH); i+=smallRect.width()*fabs(h_dir), j+=smallRect.height()*fabs(v_dir),k++,l++ ) { long x1 = x + k * smallRect.width()*h_dir; long y1 = y + l * smallRect.height()*v_dir; rectArray.push_back(scene->addRect(1, 1, smallRect.width()-2, smallRect.height()-2, QPen(Qt::yellow, 2), brush)); rectArray.last()->setPos(x1, y1); rectArray.last()->setData(0, "YellowRectangle"); rectArray.last()->setOpacity(0.7); rectArray.last()->setZValue(10000); } }
void VBezier::editPoints(QPointF p, VElement::EditAction action) { static bool isDraging = false; static int currentNode; static int param; if(action == CLICK) { for(uint i=0;i<nodes.size();i++) { if(QLineF(nodes[i].p, p).length() < 6) { currentNode = i; param = 0; isDraging = true; } if(QLineF(nodes[i].c1, p).length() < 6) { currentNode = i; param = 1; isDraging = true; } if(QLineF(nodes[i].c2, p).length() < 6) { currentNode = i; param = 2; isDraging = true; } } } else if(action == DRAG) { if(isDraging) { if(param == 0) { VBezier::Node &n = nodes[currentNode]; QPointF delta = p - n.p; n.p += delta; n.c1 += delta; n.c2 += delta; } else if(param == 1) { VBezier::Node &n = nodes[currentNode]; QPointF delta = n.p - p; n.c1 = p; n.c2= n.p + delta; } if(param == 2) { VBezier::Node &n = nodes[currentNode]; QPointF delta = n.p - p; n.c1= n.p + delta; n.c2 = p; } rebuildBB(); } } else if(action == RELEASE) { isDraging = false; } else if(action == ADDPOINT) { std::vector<int> distanceToSide; int min = 0; nodes.push_back(nodes[0]); // dla linii między pierwszym i ostatnim wierzchołkiem for(uint i=0;i<nodes.size()-1;i++) { qreal distToA = QLineF(nodes[i].p, p).length(); qreal distToB = QLineF(nodes[i+1].p, p).length(); QLineF v(nodes[i].p, p); QLineF unit = QLineF(nodes[i].p, nodes[i+1].p).unitVector(); QLineF normal = unit.normalVector(); qreal proj = unit.dx()*v.dx() + unit.dy()*v.dy(); qreal distToLine = fabs(normal.dx()*v.dx() + normal.dy()*v.dy()); if(proj<0) distToLine = distToA; if(proj>QLineF(nodes[i].p, nodes[i+1].p).length()) distToLine = distToB; distanceToSide.push_back(distToLine); if(distanceToSide[i] < distanceToSide[min]) min = i; } nodes.pop_back(); min+=1; if(min == nodes.size()) { qreal distToFirst = QLineF(nodes[0].p, p).length(); qreal distToLast = QLineF(nodes[min-1].p, p).length(); if(distToFirst < distToLast) { min = 0; } } Node newNode; newNode.p = p; newNode.c1 = p; newNode.c2 = p; nodes.insert(nodes.begin() + min, newNode); currentNode = min; isDraging = true; param = 2; rebuildBB(); } else if(action == DELETEPOINT) { for(uint i=0;i<nodes.size();i++) { if(QLineF(nodes[i].p, p).length() < 6) { nodes.erase(nodes.begin()+i); rebuildBB(); break; } } } }
void Storage::paintEvent(QPaintEvent *anEvent) { QLabel::paintEvent(anEvent); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); //painter.setRenderHint(QPainter::SmoothPixmapTransform); QPen pen; if (NoTool != tool_) { pen.setWidth(5); pen.setColor(QColor(Qt::white)); pen.setStyle(Qt::DashLine); painter.setPen(pen); if (BoundingBoxTool == tool_) { /* с учётом масштаба */ QRect bbox = rect.getCoordinates(); QPoint bboxTopLeft = bbox.topLeft() * scale_; QPoint bboxBottomRight = bbox.bottomRight() * scale_; bbox.setTopLeft(bboxTopLeft); bbox.setBottomRight(bboxBottomRight); painter.drawRect(bbox); } else if (EllipseTool == tool_) { /* с учётом масштаба */ QRect elli = ell.getCoordinates().normalized(); QPoint ellTopLeft = elli.topLeft() * scale_; QPoint ellBottomRight = elli.bottomRight() * scale_; elli.setTopLeft(ellTopLeft); elli.setBottomRight(ellBottomRight); if(1 < elli.height() && 1 < elli.width() ) { painter.drawEllipse(elli); } // painter.drawRect(ell); } else if (ArrowTool == tool_) { /* с учётом масштаба */ QLineF line = arrow.getCoordinates(); QPointF p1 = line.p1() * scale_; QPointF p2 = line.p2() * scale_; line.setP1(p1); line.setP2(p2); if(1 < line.length()) { double angle = ::acos(line.dx() / line.length()); qreal Pi = atan(1)*4; if (line.dy() >= 0) angle = (Pi * 2) - angle; QPointF arrowP1 = line.p1() + QPointF(sin(angle + Pi / 3) * arrow_size_, cos(angle + Pi / 3) * arrow_size_); QPointF arrowP2 = line.p1() + QPointF(sin(angle + Pi - Pi / 3) * arrow_size_, cos(angle + Pi - Pi / 3) * arrow_size_); QPolygonF arrowTop; arrowTop.clear(); arrowTop << line.p1() << arrowP1 << arrowP2; painter.drawLine(line); painter.drawPolygon(arrowTop);///111 qDebug() << "arrowTop" << arrowTop; arrow_top_ = arrowTop; } } else if (PolygonTool == tool_) { /* с учётом масштаба */ QPoint point; QPolygon pol = poly.getCoordinates(); for (int i = 0; i < pol.size(); i++) { point.setX(pol.at(i).x()); point.setY(pol.at(i).y()); point *= scale_; pol.remove(i); pol.insert(i, point); } painter.drawPolygon(pol); } } /* рисуем фигуры */ drawBoundingBoxes(&painter, &pen); drawPolygons(&painter, &pen); drawEllipses(&painter, &pen); drawArrows(&painter, &pen); }
bool Intersection::inside(QPointF point, QLineF segment) { QLineF s(segment.p1(), point); return segment.dx() * s.dy() - s.dx() * segment.dy() > 0; }
qreal dx = line.dx(); qreal dy = line.dy(); double l = 2.0 * (dx * dx + dy * dy); if (l > 0) { xvel += factor * dx * 200.0 / l; yvel += factor * dy * 200.0 / l; } } // tendency to stay at a fixed orbit qreal orbit = getRadiusForState(configuration.state()); qreal distance = orbitForce.length(); QLineF unit = orbitForce.unitVector(); orbitForce.setLength(xvel * unit.dx() + yvel * unit.dy()); qreal w = 2 - exp(-pow(distance-orbit, 2)/(2 * 50)); if (distance < orbit) { xvel += orbitForce.dx() * w; yvel += orbitForce.dy() * w; } else { xvel -= orbitForce.dx() * w; yvel -= orbitForce.dy() * w; } if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1) xvel = yvel = 0; QRectF sceneRect = scene()->sceneRect();