62  int balloonSegment = -1;
 
   63  QPointF balloonSegmentPoint1;
 
   64  QPointF balloonSegmentPoint2;
 
   66  const bool invertedY = rect.height() < 0;
 
   68  cornerRadius = std::min( cornerRadius, std::min( std::fabs( rect.height() ), rect.width() ) / 2.0 );
 
   71  if ( rect.contains( origin.
toQPointF() ) )
 
   78    QList<QLineF> segmentList;
 
   79    segmentList << 
segment( 0, rect, cornerRadius );
 
   80    segmentList << 
segment( 1, rect, cornerRadius );
 
   81    segmentList << 
segment( 2, rect, cornerRadius );
 
   82    segmentList << 
segment( 3, rect, cornerRadius );
 
   85    double minEdgeDist = std::numeric_limits<double>::max();
 
   86    int minEdgeIndex = -1;
 
   90    for ( 
int i = 0; i < 4; ++i )
 
   92      QLineF currentSegment = segmentList.at( i );
 
   94      double currentMinDist = origin.
sqrDistToSegment( currentSegment.x1(), currentSegment.y1(), currentSegment.x2(), currentSegment.y2(), currentMinDistPoint );
 
   95      bool isPreferredSegment = 
false;
 
   99        const double angle = fmod( origin.
azimuth( currentMinDistPoint ) + 360.0, 360.0 );
 
  100        if ( angle < 45 || angle > 315 )
 
  101          isPreferredSegment = i == 0;
 
  102        else if ( angle < 135 )
 
  103          isPreferredSegment = i == 3;
 
  104        else if ( angle < 225 )
 
  105          isPreferredSegment = i == 2;
 
  107          isPreferredSegment = i == 1;
 
  109      else if ( currentMinDist < minEdgeDist )
 
  110        isPreferredSegment = 
true;
 
  112      if ( isPreferredSegment )
 
  115        minEdgePoint = currentMinDistPoint;
 
  116        minEdgeDist = currentMinDist;
 
  117        minEdge = currentSegment;
 
  121    if ( minEdgeIndex >= 0 )
 
  123      balloonSegment = minEdgeIndex;
 
  124      QPointF minEdgeEnd = minEdge.p2();
 
  125      balloonSegmentPoint1 = QPointF( minEdgePoint.
x(), minEdgePoint.
y() );
 
  127      const double segmentLength = minEdge.length();
 
  128      const double clampedWedgeWidth = std::clamp( wedgeWidth, 0.0, segmentLength );
 
  129      if ( std::sqrt( minEdgePoint.
sqrDist( minEdgeEnd.x(), minEdgeEnd.y() ) ) < clampedWedgeWidth )
 
  134        balloonSegmentPoint1 = QPointF( x, y );
 
  141        balloonSegmentPoint2 = QPointF( x, y );
 
  149  for ( 
int i = 0; i < 4; ++i )
 
  151    QLineF currentSegment = 
segment( i, rect, cornerRadius );
 
  154      p0 = currentSegment.p1();
 
  155      path.moveTo( currentSegment.p1() );
 
  160        path.arcTo( std::min( p1.x(), currentSegment.p1().x() ),
 
  161                    std::min( p1.y(), currentSegment.p1().y() ),
 
  162                    cornerRadius, cornerRadius,
 
  163                    i == 0 ? -180 : ( i == 1 ? -90 : ( i == 2 ? 0 : 90 ) ),
 
  166        path.arcTo( std::min( p1.x(), currentSegment.p1().x() ),
 
  167                    std::min( p1.y(), currentSegment.p1().y() ),
 
  168                    cornerRadius, cornerRadius,
 
  169                    i == 0 ? 180 : ( i == 1 ? 90 : ( i == 2 ? 0 : -90 ) ),
 
  173    if ( i == balloonSegment )
 
  175      path.lineTo( balloonSegmentPoint1 );
 
  177      path.lineTo( balloonSegmentPoint2 );
 
  180    p1 = currentSegment.p2();
 
  185    path.arcTo( std::min( p1.x(), p0.x() ),
 
  186                std::min( p1.y(), p0.y() ),
 
  187                cornerRadius, cornerRadius,
 
  190    path.arcTo( std::min( p1.x(), p0.x() ),
 
  191                std::min( p1.y(), p0.y() ),
 
  192                cornerRadius, cornerRadius,
 
 
static void pointOnLineWithDistance(double x1, double y1, double x2, double y2, double distance, double &x, double &y, double *z1=nullptr, double *z2=nullptr, double *z=nullptr, double *m1=nullptr, double *m2=nullptr, double *m=nullptr)
Calculates the point a specified distance from (x1, y1) toward a second point (x2,...