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,