/** * 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()); }
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); } } }
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; } }