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); } } }
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; }
//---------------------------------------------------------------------------------------------- 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; }
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); }
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); }
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); }
/*! \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; }
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)); }
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(); } }
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 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); }
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 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 GraphEdgeView::paint(QPainter *p_painter, const QStyleOptionGraphicsItem *p_option, QWidget *p_widget) { if (m_startNode->collidesWithItem(m_endNode)) return; QPen myPen = pen(); myPen.setColor(m_color); qreal arrowSize = m_arrowSize; p_painter->setPen(myPen); p_painter->setBrush(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_color, 1, 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); } }
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; } } } }
// you can call it "normalizedProjectionLength" if you like static qreal normProjection( const QLineF &l1, const QLineF &l2 ) { const qreal dotProduct = l1.dx() * l2.dx() + l1.dy() * l2.dy(); return qAbs( dotProduct / ( l1.length() * l2.length() ) ); }
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); }
void EdgeItem::adjust() { prepareGeometryChange(); if ( edge()->pred()->item()->isVisible() && edge()->succ()->item()->isVisible()) { setVisible( true); } else { setVisible( false); return; } if ( edge()->isSelf()) { QPointF center = mapFromItem( pred()->item(), pred()->item()->borderRect().center()); QRectF r = pred()->item()->borderRect(); srcP = center + QPointF( 3 * r.width()/8, r.height() /2); dstP = center + QPointF( 3 * r.width()/8, -r.height() /2); topLeft = center + QPointF( 3 * r.width()/8, -r.height()/2 - SE_VERT_MARGIN); cp1 = center + QPointF( (r.width() / 2) + SE_HOR_MARGIN, 0); btmRight = cp1 + QPointF( 0, r.height()/2 + SE_VERT_MARGIN); update(); return; } srcP = mapFromItem( pred()->item(), pred()->item()->boundingRect().center()); dstP = mapFromItem( succ()->item(), succ()->item()->boundingRect().center()); topLeft = srcP; btmRight = dstP; QPointF srcCP = srcP; QPointF dstCP = dstP; if ( pred()->isEdgeLabel()) { srcP = mapFromItem( pred()->item(), pred()->item()->borderRect().left(), pred()->item()->borderRect().center().y()); qreal w = pred()->item()->borderRect().width(); //srcP += QPointF( -w, 0); srcCP = srcP; } if ( succ()->isEdgeLabel()) { dstP = mapFromItem( succ()->item(), succ()->item()->borderRect().left(), succ()->item()->borderRect().center().y()); dstCP = dstP; } if ( pred()->isSimple()) { QLineF line( srcP, dstP); QPolygonF endPolygon = mapFromItem( pred()->item(), pred()->item()->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( line, &srcP); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } } if ( succ()->isSimple()) { QLineF line2( srcP, dstP); QPolygonF endPolygon = mapFromItem( succ()->item(), succ()->item()->shape().toFillPolygon()); QPointF p1 = endPolygon.first();; QPointF p2; QLineF polyLine; for ( int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect( line2, &dstP); if ( intersectType == QLineF::BoundedIntersection) break; p1 = p2; } } topLeft.setX( min< qreal>( srcP.x(), dstP.x())); topLeft.setY( min< qreal>( srcP.y(), dstP.y())); btmRight.setX( max< qreal>( srcP.x(), dstP.x())); btmRight.setY( max< qreal>( srcP.y(), dstP.y())); QLineF mainLine = QLineF( srcP, dstP); if ( mainLine.length() < 1) return; qreal size = abs< qreal>(( min< qreal>( abs< qreal>( mainLine.dx()), abs< qreal>( mainLine.dy())))); //Stub if( size < 2* EdgeControlSize) { size = 2* EdgeControlSize; } if( size > 20 * EdgeControlSize) { size = 20 * EdgeControlSize; } NodeItem *next_pred = NULL; NodeItem *next_succ = NULL; if ( ( pred()->isEdgeControl() || pred()->isEdgeLabel()) && isNotNullP( pred()->firstPred())) { next_pred = pred()->firstPred()->pred()->item(); } if ( ( succ()->isEdgeControl() || succ()->isEdgeLabel()) && isNotNullP( succ()->firstSucc())) { next_succ = succ()->firstSucc()->succ()->item(); } /** Place cp1 */ if ( isNotNullP( next_pred)) { QPointF p1 = mapFromItem( next_pred, next_pred->borderRect().center()); QLineF line( p1, dstCP); QPointF cp1_offset = QPointF( (line.dx() * size)/ line.length(), (line.dy() * size)/ line.length()); cp1 = srcP + cp1_offset; } else { QPointF cp1_offset = QPointF( (mainLine.dx() * size)/ mainLine.length(), (mainLine.dy() * size)/ mainLine.length()); cp1 = srcP + cp1_offset; } topLeft.setX( min< qreal>( topLeft.x(), cp1.x())); topLeft.setY( min< qreal>( topLeft.y(), cp1.y())); btmRight.setX( max< qreal>( btmRight.x(), cp1.x())); btmRight.setY( max< qreal>( btmRight.y(), cp1.y())); /** Place cp2 */ if ( isNotNullP( next_succ)) { QPointF p2 = mapFromItem( next_succ, next_succ->borderRect().center()); QLineF line( p2, srcCP); QPointF cp2_offset = QPointF( (line.dx() * size)/ line.length(), (line.dy() * size)/ line.length()); cp2 = dstP + cp2_offset; } else { QPointF cp2_offset = QPointF( -(mainLine.dx() * size)/ mainLine.length(), -(mainLine.dy() * size)/ mainLine.length()); cp2 = dstP + cp2_offset; } topLeft.setX( min< qreal>( topLeft.x(), cp2.x())); topLeft.setY( min< qreal>( topLeft.y(), cp2.y())); btmRight.setX( max< qreal>( btmRight.x(), cp2.x())); btmRight.setY( max< qreal>( btmRight.y(), cp2.y())); update(); }
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 }
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();
bool Intersection::inside(QPointF point, QLineF segment) { QLineF s(segment.p1(), point); return segment.dx() * s.dy() - s.dx() * segment.dy() > 0; }
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); } }