/**
 * This method aligns *this* Symbol to the line being
 * passed. That is, it ensures that the axis of this symbol aligns
 * exactly with the \a "to" line passed.
 *
 * Also this item is moved such that the second end point of the
 * SymbolEndPoints for the current symbol *collides* with the second end
 * point of \a "to" line.
 */
void Symbol::alignTo(const QLineF& to)
{
    QLineF toMapped(mapFromParent(to.p1()), mapFromParent(to.p2()));

    QLineF origAxis = Symbol::symbolTable[m_symbolType].axisLine;
    QLineF translatedAxis = origAxis.translated(toMapped.p2() - origAxis.p2());

    qreal angle = translatedAxis.angleTo(toMapped);
    rotate(-angle);

    QPointF delta = to.p2() - mapToParent(symbolEndPoints().second);
    moveBy(delta.x(), delta.y());
}
示例#2
0
void AssociationItem::placeEndLabels(const QLineF &lineSegment, QGraphicsItem *endName, QGraphicsItem *endCardinality,
                                     QGraphicsItem *endItem, double headLength)
{
    const double HEAD_OFFSET = headLength + 6.0;
    const double SIDE_OFFSET = 4.0;
    QPointF headOffset = QPointF(HEAD_OFFSET, 0);
    QPointF sideOffset = QPointF(0.0, SIDE_OFFSET);

    double angle = GeometryUtilities::calcAngle(lineSegment);
    if (angle >= -5 && angle <= 5) {
        if (endName)
            endName->setPos(lineSegment.p1() + headOffset + sideOffset);
        if (endCardinality)
            endCardinality->setPos(lineSegment.p1() + headOffset - sideOffset
                                   - endCardinality->boundingRect().bottomLeft());
    } else if (angle <= -175 || angle >= 175) {
        if (endName)
            endName->setPos(lineSegment.p1() - headOffset + sideOffset - endName->boundingRect().topRight());
        if (endCardinality)
            endCardinality->setPos(lineSegment.p1() - headOffset
                                   - sideOffset - endCardinality->boundingRect().bottomRight());
    } else {
        QRectF rect;
        if (endCardinality)
            rect = endCardinality->boundingRect();
        if (endName)
            rect = rect.united(endName->boundingRect().translated(rect.bottomLeft()));

        QPointF rectPlacement;
        GeometryUtilities::Side alignedSide = GeometryUtilities::SideUnspecified;

        if (auto objectItem = dynamic_cast<IIntersectionable *>(endItem)) {
            QPointF intersectionPoint;
            QLineF intersectionLine;

            if (objectItem->intersectShapeWithLine(GeometryUtilities::stretch(lineSegment.translated(pos()), 2.0, 0.0),
                                                   &intersectionPoint, &intersectionLine)) {
                if (!GeometryUtilities::placeRectAtLine(rect, lineSegment, HEAD_OFFSET, SIDE_OFFSET,
                                                        intersectionLine, &rectPlacement, &alignedSide)) {
                    rectPlacement = intersectionPoint;
                }
            } else {
                rectPlacement = lineSegment.p1();
            }
        } else {
            rectPlacement = endItem->pos();
        }

        if (endCardinality) {
            if (alignedSide == GeometryUtilities::SideRight)
                endCardinality->setPos(rectPlacement
                                       + QPointF(rect.width() - endCardinality->boundingRect().width(), 0.0));
            else
                endCardinality->setPos(rectPlacement);
            rectPlacement += endCardinality->boundingRect().bottomLeft();
        }
        if (endName) {
            if (alignedSide == GeometryUtilities::SideRight)
                endName->setPos(rectPlacement + QPointF(rect.width() - endName->boundingRect().width(), 0.0));
            else
                endName->setPos(rectPlacement);
        }
    }
}
示例#3
0
void tst_QLine::testIntersection_data()
{
    QTest::addColumn<double>("xa1");
    QTest::addColumn<double>("ya1");
    QTest::addColumn<double>("xa2");
    QTest::addColumn<double>("ya2");
    QTest::addColumn<double>("xb1");
    QTest::addColumn<double>("yb1");
    QTest::addColumn<double>("xb2");
    QTest::addColumn<double>("yb2");
    QTest::addColumn<int>("type");
    QTest::addColumn<double>("ix");
    QTest::addColumn<double>("iy");

    QTest::newRow("parallel") << 1.0 << 1.0 << 3.0 << 4.0
                           << 5.0 << 6.0 << 7.0 << 9.0
                           << int(QLineF::NoIntersection) << 0.0 << 0.0;
    QTest::newRow("unbounded") << 1.0 << 1.0 << 5.0 << 5.0
                            << 0.0 << 4.0 << 3.0 << 4.0
                            << int(QLineF::UnboundedIntersection) << 4.0 << 4.0;
    QTest::newRow("bounded") << 1.0 << 1.0 << 5.0 << 5.0
                          << 0.0 << 4.0 << 5.0 << 4.0
                          << int(QLineF::BoundedIntersection) << 4.0 << 4.0;

    QTest::newRow("almost vertical") << 0.0 << 10.0 << 20.0000000000001 << 10.0
                                     << 10.0 << 0.0 << 10.0 << 20.0
                                     << int(QLineF::BoundedIntersection) << 10.0 << 10.0;

    QTest::newRow("almost horizontal") << 0.0 << 10.0 << 20.0 << 10.0
                                       << 10.0000000000001 << 0.0 << 10.0 << 20.0
                                       << int(QLineF::BoundedIntersection) << 10.0 << 10.0;

    QTest::newRow("long vertical") << 100.1599256468623
                                   << 100.7861905065196
                                   << 100.1599256468604
                                   << -9999.78619050651
                                   << 10.0 << 50.0 << 190.0 << 50.0
                                   << int(QLineF::BoundedIntersection)
                                   << 100.1599256468622
                                   << 50.0;

    QLineF baseA(0, -50, 0, 50);
    QLineF baseB(-50, 0, 50, 0);

    for (int i = 0; i < 1000; ++i) {
        QLineF a = QLineF::fromPolar(50, i);
        a.setP1(-a.p2());

        QLineF b = QLineF::fromPolar(50, i * 0.997 + 90);
        b.setP1(-b.p2());

        // make the qFuzzyCompare be a bit more lenient
        a = a.translated(1, 1);
        b = b.translated(1, 1);

        QTest::newRow(("rotation-" + QByteArray::number(i)).constData())
            << (double)a.x1() << (double)a.y1() << (double)a.x2() << (double)a.y2()
            << (double)b.x1() << (double)b.y1() << (double)b.x2() << (double)b.y2()
            << int(QLineF::BoundedIntersection)
            << 1.0
            << 1.0;
    }
}