QList<QPointF> Geometry::intersection(QLineF const &line, QPainterPath const &path, qreal eps) { QList<QPointF> result; QPointF startPoint; QPointF endPoint; for (int i = 0; i < path.elementCount(); ++i) { QPainterPath::Element const element = path.elementAt(i); // Checking that element belongs to the wall path if (element.isMoveTo()) { endPoint = QPointF(element.x, element.y); continue; } startPoint = endPoint; endPoint = QPointF(element.x, element.y); QLineF currentLine(startPoint, endPoint); QPointF intersectionPoint; // TODO: consider curve cases if (line.intersect(currentLine, &intersectionPoint) != QLineF::NoIntersection && belongs(intersectionPoint, currentLine, eps)) { result << intersectionPoint; } } return result; }
// cppcheck-suppress unusedFunction QLineF::IntersectType VSpline::CrossingSplLine ( const QLineF &line, QPointF *intersectionPoint ) const { QVector<qreal> px; QVector<qreal> py; px.append ( GetP1 ().x () ); py.append ( GetP1 ().y () ); QVector<qreal>& wpx = px; QVector<qreal>& wpy = py; PointBezier_r ( GetP1 ().x (), GetP1 ().y (), GetP2 ().x (), GetP2 ().y (), GetP3 ().x (), GetP3 ().y (), GetP4 ().x (), GetP4 ().y (), 0, wpx, wpy); px.append ( GetP4 ().x () ); py.append ( GetP4 ().y () ); qint32 i = 0; QPointF crosPoint; QLineF::IntersectType type = QLineF::NoIntersection; for ( i = 0; i < px.count()-1; ++i ) { type = line.intersect(QLineF ( QPointF ( px.at(i), py.at(i) ), QPointF ( px.at(i+1), py.at(i+1) )), &crosPoint); if ( type == QLineF::BoundedIntersection ) { *intersectionPoint = crosPoint; return type; } } throw "Can't found point of intersection spline and line."; }
/** @param point Un point donne @param line Un segment de droite donnee @param intersection si ce pointeur est different de 0, le QPointF ainsi designe contiendra les coordonnees du projete orthogonal, meme si celui-ci n'appartient pas au segment de droite @return true si le projete orthogonal du point sur la droite appartient au segment de droite. */ bool QET::orthogonalProjection(const QPointF &point, const QLineF &line, QPointF *intersection) { // recupere le vecteur normal de `line' QLineF line_normal_vector(line.normalVector()); QPointF normal_vector(line_normal_vector.dx(), line_normal_vector.dy()); // cree une droite perpendiculaire a `line' passant par `point' QLineF perpendicular_line(point, point + normal_vector); // determine le point d'intersection des deux droites = le projete orthogonal QPointF intersection_point; QLineF::IntersectType it = line.intersect(perpendicular_line, &intersection_point); // ne devrait pas arriver (mais bon...) if (it == QLineF::NoIntersection) return(false); // fournit le point d'intersection a l'appelant si necessaire if (intersection) { *intersection = intersection_point; } // determine si le point d'intersection appartient au segment de droite if (QET::lineContainsPoint(line, intersection_point)) { return(true); } return(false); }
//! [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); } }
/** * This implementation differs from PageLayout::inscribedCutterLine() in that * it forces the endpoints to lie on the top and bottom boundary lines. * Line's angle may change as a result. */ QLineF ImageView::customInscribedCutterLine(QLineF const& line, QRectF const& rect) { if (line.p1().y() == line.p2().y()) { // This should not happen, but if it does, we need to handle it gracefully. qreal middle_x = 0.5 * (line.p1().x() + line.p2().x()); middle_x = qBound(rect.left(), middle_x, rect.right()); return QLineF(QPointF(middle_x, rect.top()), QPointF(middle_x, rect.bottom())); } QPointF top_pt; QPointF bottom_pt; line.intersect(QLineF(rect.topLeft(), rect.topRight()), &top_pt); line.intersect(QLineF(rect.bottomLeft(), rect.bottomRight()), &bottom_pt); double const top_x = qBound(rect.left(), top_pt.x(), rect.right()); double const bottom_x = qBound(rect.left(), bottom_pt.x(), rect.right()); return QLineF(QPointF(top_x, rect.top()), QPointF(bottom_x, rect.bottom())); }
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); }
void ImageView::lineMoveRequest(int line_idx, QLineF line) { // Intersect with top and bottom. QPointF p_top; QPointF p_bottom; QRectF const valid_area(getOccupiedWidgetRect()); line.intersect(QLineF(valid_area.topLeft(), valid_area.topRight()), &p_top); line.intersect(QLineF(valid_area.bottomLeft(), valid_area.bottomRight()), &p_bottom); // Limit movement. double const min_x = qMin(p_top.x(), p_bottom.x()); double const max_x = qMax(p_top.x(), p_bottom.x()); double const left = valid_area.left() - min_x; double const right = max_x - valid_area.right(); if (left > right && left > 0.0) { line.translate(left, 0.0); } else if (right > 0.0) { line.translate(-right, 0.0); } m_virtLayout.setCutterLine(line_idx, widgetToVirtual().map(line)); update(); }
//This function assumes that the line does intersect with the viewport //boundary - i.e. one end of the line is in the viewport and one is not. QPointF MyGraphicsView::findIntersectionWithViewportBoundary(QLineF line) { QPointF c1, c2, c3, c4; getFourViewportCornersInSceneCoordinates(&c1, &c2, &c3, &c4); QLineF boundary1(c1, c2); QLineF boundary2(c2, c3); QLineF boundary3(c3, c4); QLineF boundary4(c4, c1); QPointF intersection; if (line.intersect(boundary1, &intersection) == QLineF::BoundedIntersection) return intersection; if (line.intersect(boundary2, &intersection) == QLineF::BoundedIntersection) return intersection; if (line.intersect(boundary3, &intersection) == QLineF::BoundedIntersection) return intersection; if (line.intersect(boundary4, &intersection) == QLineF::BoundedIntersection) return intersection; //The code should not get here, as the line should intersect with one of //the boundaries. return intersection; }
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; }
/*! * \brief Places a line into given rectangle * \param the line * \param the rectangle * \return QLineF beginning and ending at the edges of the rectangle. */ QLineF GT::intersectLineRect(const QLineF &st, const QRectF &rect) { QLineF start = st; QPointF iss[3]; int i = 0; // Půlnoční velkorysý odhad: double longEnough = fabs(rect.bottom()) + fabs(rect.top()) + fabs(rect.left()) + fabs(rect.right()) + fabs(start.x1()) + fabs(start.x2()) + fabs(start.y1()) + fabs(start.y2()); start.setLength(longEnough); if (QLineF::BoundedIntersection == start.intersect(QLineF(rect.bottomLeft(),rect.bottomRight()), iss + i)) i++; if (QLineF::BoundedIntersection == start.intersect(QLineF(rect.bottomLeft(),rect.topLeft()), iss + i)) i++; if (QLineF::BoundedIntersection == start.intersect(QLineF(rect.topRight(),rect.bottomRight()), iss + i)) i++; if (QLineF::BoundedIntersection == start.intersect(QLineF(rect.topRight(),rect.topLeft()), iss + i)) i++; start.setLength(-longEnough); if (QLineF::BoundedIntersection == start.intersect(QLineF(rect.bottomLeft(),rect.bottomRight()), iss + i)) i++; if (QLineF::BoundedIntersection == start.intersect(QLineF(rect.bottomLeft(),rect.topLeft()), iss + i)) i++; if (QLineF::BoundedIntersection == start.intersect(QLineF(rect.topRight(),rect.bottomRight()), iss + i)) i++; if (QLineF::BoundedIntersection == start.intersect(QLineF(rect.topRight(),rect.topLeft()), iss + i)) i++; if (2 == i) return QLineF(iss[0],iss[1]); else return QLineF(); }
/*! * \brief Makes a guess about the board corner positions using the Hough transform. * \param Source image * \param Maximum size of the image to transform. (Source image is scaled to this size.) * \param Angle resolution of the transformed image * \return Guessed positions of corners. * * Because the Hough tranform is computationally expensive (required time * is proportional to angleRes * (image diameter)**3), the original image is scaled down * maxSize. This has of course a consequence of lower accuracy (the border lines might * be shifted). */ QVector<QPointF> HoughTransform::guessCorners(const QImage src, const QSize &maxSize, int angleRes) { QImage imgscaled = src.scaled(maxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); // qDebug() << imgscaled.size(); // imgscaled.save("/tmp/debug/" + QUuid::createUuid().toString() + ".png"); HoughTransform ht(&imgscaled, angleRes); // ht.visualise().save("/tmp/debug/" + QUuid::createUuid().toString() + ".png"); QVector<Coords> borders = QVector<Coords>::fromStdVector(ht.roughEdges()); QVector<QPointF> corners(4); for (int i = 0; i < 4; i++) { QLineF a = houghLine(borders[i].r, borders[i].alpha * 2 * pi / angleRes, imgscaled.width(), imgscaled.height()); QLineF b = houghLine(borders[(i + 1) % 4].r, borders[(i + 1) % 4].alpha * 2 * pi / angleRes, imgscaled.width(), imgscaled.height()); QPointF intersection; if (QLineF::NoIntersection == a.intersect(b, &intersection)) { Q_UNREACHABLE(); } corners[i] = intersection * (src.width() / (qreal)imgscaled.width()); } return corners; }
QPair<SectorItem *, SectorItem *> SectorItem::split(QLineF splittingLine) { int currentIndex(1); int count(this->_mainLine.count()); bool match(false); QPointF pointIntersection; QPair<SectorItem*, SectorItem*> subSectors; while (currentIndex < count && !match) { QLineF segment(this->_mainLine.at(currentIndex - 1), this->_mainLine.at(currentIndex)); if (splittingLine.intersect(segment, &pointIntersection) == QLineF::BoundedIntersection) { SectorItem* first = new SectorItem(this->_competition); SectorItem* second = new SectorItem(this->_competition); IndexedPosition indexedIntersection(pointIntersection); float intersectionIndex = this->_mainLine[currentIndex].index(); indexedIntersection.setIndex(intersectionIndex); first->append(this->_mainLine.mid(0, currentIndex)); first->append(indexedIntersection, splittingLine); second->append(indexedIntersection, splittingLine); second->append(this->_mainLine.mid(currentIndex)); subSectors.first = first; subSectors.second = second; match = true; } currentIndex++; } return subSectors; }
void ArcItem::updateArrowPath(){ QPainterPath path; if((_endItem && _startItem->primaryShape().intersects(_endItem->primaryShape())) || (!_endItem && _startItem->primaryShape().contains(_end))){ _cachedArrowPath = path; return; } QPointF start(0,0), point = _end - pos(); //The arrow line and reverse liune QLineF revline(point, start); //Compute various points QLineF s = revline.normalVector(); s.setAngle(revline.angle() - 45); s.setLength(ARROW_SIZE); QPointF side1 = s.p2(); s = revline.normalVector(); s.setAngle(revline.angle() + 45); s.setLength(ARROW_SIZE); QPointF side2 = s.p2(); s = QLineF(side1, side2); QPointF head = point; s.intersect(revline, &head); path.moveTo(start); path.lineTo(head); path.lineTo(side1); path.lineTo(point); path.lineTo(side2); path.lineTo(head); _cachedArrowPath = path; }
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); } }
//! [4] void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { if (myStartNode->collidesWithItem(myEndNode)) return; QPen myPen = pen(); myPen.setColor(myColor); qreal arrowSize = 10; painter->setPen(myPen); painter->setBrush(myColor); //! [4] //! [5] // ----- gilgil temp 2012.06.29 ----- /* QLineF centerLine(myStartNode->pos(), myEndNode->pos()); QPolygonF endPolygon = myEndNode->polygon(); QPointF p1 = endPolygon.first() + myEndNode->pos(); QPointF p2; QPointF intersectPoint; QLineF polyLine; for (int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i) + myEndNode->pos(); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &intersectPoint); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } */ // ---------------------------------- QPointF start, end; start.setX(myStartNode->pos().x() + myStartNode->boundingRect().width() / 2); start.setY(myStartNode->pos().y() + myStartNode->boundingRect().height() / 2); end.setX (myEndNode->pos().x() + myEndNode->boundingRect().width() / 2); end.setY (myEndNode->pos().y() + myEndNode->boundingRect().height() / 2); QLineF centerLine(start, end); QPointF intersectPoint; QLineF::IntersectType intersectType; QLineF polyLine; while (true) { polyLine = QLineF(myEndNode->sceneBoundingRect().topLeft(), myEndNode->sceneBoundingRect().topRight()); intersectType = polyLine.intersect(centerLine, &intersectPoint); if (intersectType == QLineF::BoundedIntersection) break; polyLine = QLineF(myEndNode->sceneBoundingRect().topLeft(), myEndNode->sceneBoundingRect().bottomLeft()); intersectType = polyLine.intersect(centerLine, &intersectPoint); if (intersectType == QLineF::BoundedIntersection) break; polyLine = QLineF(myEndNode->sceneBoundingRect().topRight(), myEndNode->sceneBoundingRect().bottomRight()); intersectType = polyLine.intersect(centerLine, &intersectPoint); if (intersectType == QLineF::BoundedIntersection) break; polyLine = QLineF(myEndNode->sceneBoundingRect().bottomLeft(), myEndNode->sceneBoundingRect().bottomRight()); intersectType = polyLine.intersect(centerLine, &intersectPoint); if (intersectType == QLineF::BoundedIntersection) break; break; } setLine(QLineF(intersectPoint, start)); //! [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); } }
//---------------------------------------------------------------------------------------------- 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); //} }
QPointF Intersection::intersect(QLineF l1, QLineF l2) { QPointF p; l1.intersect(l2, &p); return p; }
void EllipseObject::updateRubber(QPainter* painter) { int rubberMode = objectRubberMode(); if(rubberMode == OBJ_RUBBER_ELLIPSE_LINE) { QPointF sceneLinePoint1 = objectRubberPoint("ELLIPSE_LINE_POINT1"); QPointF sceneLinePoint2 = objectRubberPoint("ELLIPSE_LINE_POINT2"); QPointF itemLinePoint1 = mapFromScene(sceneLinePoint1); QPointF itemLinePoint2 = mapFromScene(sceneLinePoint2); QLineF itemLine(itemLinePoint1, itemLinePoint2); if(painter) painter->drawLine(itemLine); updatePath(); } else if(rubberMode == OBJ_RUBBER_ELLIPSE_MAJORDIAMETER_MINORRADIUS) { QPointF sceneAxis1Point1 = objectRubberPoint("ELLIPSE_AXIS1_POINT1"); QPointF sceneAxis1Point2 = objectRubberPoint("ELLIPSE_AXIS1_POINT2"); QPointF sceneCenterPoint = objectRubberPoint("ELLIPSE_CENTER"); QPointF sceneAxis2Point2 = objectRubberPoint("ELLIPSE_AXIS2_POINT2"); qreal ellipseWidth = objectRubberPoint("ELLIPSE_WIDTH").x(); qreal ellipseRot = objectRubberPoint("ELLIPSE_ROT").x(); //TODO: incorporate perpendicularDistance() into libcgeometry qreal px = sceneAxis2Point2.x(); qreal py = sceneAxis2Point2.y(); qreal x1 = sceneAxis1Point1.x(); qreal y1 = sceneAxis1Point1.y(); QLineF line(sceneAxis1Point1, sceneAxis1Point2); QLineF norm = line.normalVector(); qreal dx = px-x1; qreal dy = py-y1; norm.translate(dx, dy); QPointF iPoint; norm.intersect(line, &iPoint); qreal ellipseHeight = QLineF(px, py, iPoint.x(), iPoint.y()).length()*2.0; setObjectCenter(sceneCenterPoint); setObjectSize(ellipseWidth, ellipseHeight); setRotation(-ellipseRot); QPointF itemCenterPoint = mapFromScene(sceneCenterPoint); QPointF itemAxis2Point2 = mapFromScene(sceneAxis2Point2); QLineF itemLine(itemCenterPoint, itemAxis2Point2); if(painter) painter->drawLine(itemLine); updatePath(); } else if(rubberMode == OBJ_RUBBER_ELLIPSE_MAJORRADIUS_MINORRADIUS) { QPointF sceneAxis1Point2 = objectRubberPoint("ELLIPSE_AXIS1_POINT2"); QPointF sceneCenterPoint = objectRubberPoint("ELLIPSE_CENTER"); QPointF sceneAxis2Point2 = objectRubberPoint("ELLIPSE_AXIS2_POINT2"); qreal ellipseWidth = objectRubberPoint("ELLIPSE_WIDTH").x(); qreal ellipseRot = objectRubberPoint("ELLIPSE_ROT").x(); //TODO: incorporate perpendicularDistance() into libcgeometry qreal px = sceneAxis2Point2.x(); qreal py = sceneAxis2Point2.y(); qreal x1 = sceneCenterPoint.x(); qreal y1 = sceneCenterPoint.y(); QLineF line(sceneCenterPoint, sceneAxis1Point2); QLineF norm = line.normalVector(); qreal dx = px-x1; qreal dy = py-y1; norm.translate(dx, dy); QPointF iPoint; norm.intersect(line, &iPoint); qreal ellipseHeight = QLineF(px, py, iPoint.x(), iPoint.y()).length()*2.0; setObjectCenter(sceneCenterPoint); setObjectSize(ellipseWidth, ellipseHeight); setRotation(-ellipseRot); QPointF itemCenterPoint = mapFromScene(sceneCenterPoint); QPointF itemAxis2Point2 = mapFromScene(sceneAxis2Point2); QLineF itemLine(itemCenterPoint, itemAxis2Point2); if(painter) painter->drawLine(itemLine); updatePath(); } }
void Lien::redraw(QPainter *painter, const QStyleOptionGraphicsItem *,QWidget *) { qDebug()<<"void lien::paint(QPainter *painter, const QStyleOptionGraphicsItem *,QWidget *)"; if (t1->collidesWithItem(t2)) return; QColor myColor(Qt::red); QPen myPen = laLigne->pen(); myPen.setColor(myColor); painter->setPen(myPen); painter->setBrush(myColor); QPointF origine=t1->pos()+QPointF(t1->boundingRect().width()/2,10); QPointF destination=t2->pos()+QPointF(t2->boundingRect().width()/2,10); QLineF centerLine(origine,destination); QPolygonF endPolygon = t2->polygon(); QPolygonF beginPolygon = t1->polygon(); QPointF p1 = endPolygon.first()+t2->pos() ; QPointF p2; QPointF intersectPointT2; QLineF polyLine; for (int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i)+t2->pos(); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &intersectPointT2); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } p1 = beginPolygon.first()+t1->pos() ; QPointF intersectPointT1; for (int i = 1; i < beginPolygon.count(); ++i) { p2 = beginPolygon.at(i)+t1->pos(); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &intersectPointT1); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } laLigne->setLine(QLineF(intersectPointT1,intersectPointT2)); if(typeDeJointure=="Cross") { texte1->document()->setPlainText("X"); texte2->document()->setPlainText("X"); } else { if(typeDeJointure=="Natural") { texte1->document()->setPlainText("?"); texte2->document()->setPlainText("?"); } else { if(typeDeJointure=="Inner") { texte1->document()->setPlainText("="); texte2->document()->setPlainText("="); } else { if(typeDeJointure=="left outer") { texte1->document()->setPlainText("+="); texte2->document()->setPlainText(""); } else { if(typeDeJointure=="right outer") { texte1->document()->setPlainText(""); texte2->document()->setPlainText("+="); } } } } } QPointF posTexte1,posTexte2; if(intersectPointT1.x()<intersectPointT2.x()) { posTexte1.setX(intersectPointT1.x()); posTexte2.setX(intersectPointT2.x()-texte2->document()->size().width()); } else { posTexte2.setX(intersectPointT2.x()); posTexte1.setX(intersectPointT1.x()-texte1->document()->size().width()); } if(intersectPointT1.y()<intersectPointT2.y()) { posTexte1.setY(intersectPointT1.y()); posTexte2.setY(intersectPointT2.y()-texte2->document()->size().height()); } else { posTexte2.setY(intersectPointT2.y()); posTexte1.setY(intersectPointT1.y()-texte1->document()->size().height()); } texte1->setPos(posTexte1); texte2->setPos(posTexte2); painter->drawLine(laLigne->line()); // if (isSelected()) { painter->setPen(QPen(myColor, 1, Qt::DashLine)); QLineF myLine = laLigne->line(); myLine.translate(0, 4.0); painter->drawLine(myLine); myLine.translate(0,-8.0); painter->drawLine(myLine); } }
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 Arrow::updatePosition() { //QLineF line(mapFromItem(m_startItem, 0, 0), mapFromItem(m_endItem, 0, 0)); //setLine(line); const QPointF startPos = m_startItem->pos(); const QPointF endPos = m_endItem->pos(); if (m_startItem->collidesWithItem(m_endItem)) { setLine(0, 0, 0, 0); return; } const qreal startScale = m_startItem->scale(); const qreal endScale = m_endItem->scale(); const int deltaX = qAbs(startPos.x() - endPos.x()); const int deltaY = qAbs(startPos.y() - endPos.y()); const QPointF pointDeltaX = QPointF(m_startItem->boundingRect().width() / 4, 0) * startScale; const QPointF pointDeltaY = QPointF(0, m_startItem->boundingRect().height() / 4) * startScale; QLineF centerLine(startPos + m_startItem->boundingRect().center() * startScale, endPos + m_endItem->boundingRect().center() * endScale); switch (m_status) { case PostMonster::Ok: case PostMonster::True: if (deltaX < deltaY) centerLine = QLineF(centerLine.p1() + pointDeltaX, centerLine.p2() + pointDeltaX); else centerLine = QLineF(centerLine.p1() - pointDeltaY, centerLine.p2() - pointDeltaY); break; case PostMonster::Fail: case PostMonster::False: if (deltaX < deltaY) centerLine = QLineF(centerLine.p1() - pointDeltaX, centerLine.p2() - pointDeltaX); else centerLine = QLineF(centerLine.p1() + pointDeltaY, centerLine.p2() + pointDeltaY); break; case PostMonster::Default: break; } QPolygonF itemPolygon = m_endItem->shape().toFillPolygon(); QPointF p1 = itemPolygon.first() + endPos; QPointF p2; QPointF startPoint, endPoint; QLineF polyLine; for (int i = 1; i < itemPolygon.count(); ++i) { p2 = itemPolygon.at(i) * endScale + endPos; polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &endPoint); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } itemPolygon = m_startItem->shape().toFillPolygon(); p1 = itemPolygon.first() + startPos; for (int i = 1; i < itemPolygon.count(); ++i) { p2 = itemPolygon.at(i) * startScale + startPos; polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &startPoint); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } setLine(QLineF(endPoint, startPoint)); }
QPolygonF minigis::shiftPolygon(const QPolygonF &origin, qreal delta, bool direction, QList<int> *doubleDots) { if (doubleDots) doubleDots->clear(); delta = qAbs(delta); QVector<QLineF> lines; for (int i = 1; i < origin.size(); ++i) { QLineF l(origin.at(i - 1), origin.at(i)); QLineF norm = l.normalVector(); qreal len = lengthR2(l.p2() - l.p1()); QPointF normVect = (norm.p2() - norm.p1()) / len; lines.append(l.translated(normVect * (direction ? -delta : delta))); } QPolygonF path; QVectorIterator<QLineF> it(lines); QLineF base = it.next(); int pointNumber = 0; path.append(base.p1()); while (it.hasNext()) { QLineF next = it.next(); ++pointNumber; double ang = base.angleTo(next); bool side = ang < 180 ? direction : !direction; if (ang > 180) ang = 360 - ang; if (qFuzzyIsNull(ang)) { // "I" + // линия-продолжение path.append(base.p2()); base.setP2(next.p2()); } else if (qFuzzyIsNull(ang - 180)) { // "IV" ? // коллинеарная линия в обраную строную // TODO: mb we don't need this path.append(base.p2()); path.append(next.p1()); base = next; if (doubleDots) doubleDots->append(pointNumber); } else if (ang < 120) { // "II" QPointF p; base.intersect(next, &p); if (side) { // "A" + // линия снаружи path.append(p); base = next; } else { // "B" - // линия внутри // TODO: correct algo path.append(p); base = next; } } else { // "III" if (side) { // "A" + // линия снаружи с острым углом QPointF p; base.intersect(next, &p); QPointF start = origin.at(pointNumber); QPointF vect = p - start; vect *= delta / lengthR2(vect); QPointF norm(vect.y(), -vect.x()); QLineF tmp(start + vect, start + vect + norm); base.intersect(tmp, &p); path.append(p); next.intersect(tmp, &p); path.append(p); base = next; if (doubleDots) doubleDots->append(pointNumber); } else { // "B" - // линия внутри с острым углом // TODO: correct algo QPointF p; base.intersect(next, &p); path.append(p); base = next; } } } path.append(base.p2()); return path; }