31void QQuickRegularPolygonShapePrivate::updatePoints()
35 const qreal sliceAngle = 360.0f / sideCount;
36 const qreal a = width.valueBypassingBindings() / 2.0f;
37 const qreal b = height.valueBypassingBindings() / 2.0f;
38 const QVector2D center(a, b);
40 for (
int i = 0; i < sideCount; ++i) {
41 const qreal angleToCorner = qDegreesToRadians(i * sliceAngle);
44 const QVector2D xy = center + QVector2D(a * qSin(angleToCorner), -b * qCos(angleToCorner));
46 points.push_back(std::move(xy));
50void QQuickRegularPolygonShapePrivate::updateBisectors()
52 const auto size = points.size();
60 for (size_t i = 0; i < size; ++i) {
61 const auto &a = points[i];
62 const auto &b = points[(i == 0 ? size : i) - 1];
63 const auto &c = points[(i + 1 == size) ? 0 : (i + 1)];
65 const QVector2D vAB(b.x() - a.x(), b.y() - a.y());
66 const QVector2D vAC(c.x() - a.x(), c.y() - a.y());
67 const auto bisector = (vAB + vAC).normalized();
69 bisectors.push_back(std::move(bisector));
73void QQuickRegularPolygonShapePrivate::constructPolygonPath()
75 auto *ppath = QQuickShapePathPrivate::get(path);
78 path->setStartX(points[0].x());
79 path->setStartY(points[0].y());
81 for (
const auto &p : points) {
82 auto line =
new QQuickPathLine(path);
85 ppath->appendPathElement(line, QQuickPathPrivate::ProcessPathPolicy::DontProcess);
89 auto line =
new QQuickPathLine(path);
90 line->setX(points[0].x());
91 line->setY(points[0].y());
92 ppath->appendPathElement(line, QQuickPathPrivate::ProcessPathPolicy::DontProcess);
97void QQuickRegularPolygonShapePrivate::constructRoundedPolygonPath()
99 auto *ppath = QQuickShapePathPrivate::get(path);
103 const auto size = points.size();
104 for (size_t i = 0; i < size; ++i) {
105 const size_t idxMinusOne = (i == 0 ? size : i) - 1;
106 const size_t idxPlusOne = (i + 1 == size) ? 0 : (i + 1);
107 const auto &a = points[i];
108 const auto &b = points[idxMinusOne];
109 const auto &c = points[idxPlusOne];
110 qreal r = cornerRadius;
112 const QVector2D vAB(b.x() - a.x(), b.y() - a.y());
113 const QVector2D vAC(c.x() - a.x(), c.y() - a.y());
117 intersect(a, bisectors[i],
118 b, bisectors[idxMinusOne]);
120 intersect(a, bisectors[i],
121 c, bisectors[idxPlusOne]);
122 const qreal tMax = std::min(tAB, tAC);
125 const qreal alpha = qAcos(QVector2D::dotProduct(vAB, vAC) / (vAB.length() * vAC.length()));
130 const qreal maxRadius = std::round(QVector2D(c.x() - b.x(), c.y() - b.y()).length() / 2);
131 r = std::min(r, maxRadius);
134 const qreal cLength = r / (qSin(alpha / 2));
137 const qreal realC = std::min(cLength, tMax);
140 r = realC * qSin(alpha / 2);
142 const qreal t = qSqrt(qPow(realC, 2) - qPow(r, 2));
144 const auto p1 = (vAB.normalized() * t) + QVector2D(a.x(), a.y());
145 const auto p2 = (vAC.normalized() * t) + QVector2D(a.x(), a.y());
148 path->setStartX(p1.x());
149 path->setStartY(p1.y());
151 auto line =
new QQuickPathLine(path);
154 ppath->appendPathElement(line, QQuickPathPrivate::ProcessPathPolicy::DontProcess);
157 auto arc =
new QQuickPathArc(path);
162 ppath->appendPathElement(arc, QQuickPathPrivate::ProcessPathPolicy::DontProcess);
166 auto line =
new QQuickPathLine(path);
167 line->setX(path->startX());
168 line->setY(path->startY());
169 ppath->appendPathElement(line, QQuickPathPrivate::ProcessPathPolicy::DontProcess);
174void QQuickRegularPolygonShapePrivate::updatePath()
176 QQuickShapePathPrivate::get(path)->clearPathElements(
177 QQuickPathPrivate::DeleteElementPolicy::Delete);
181 if (qFuzzyCompare(cornerRadius, 0.0))
182 constructPolygonPath();
184 constructRoundedPolygonPath();
213QQuickRegularPolygonShape::QQuickRegularPolygonShape(QQuickItem *parent)
214 : QQuickShape(*(
new QQuickRegularPolygonShapePrivate), parent)
216 Q_D(QQuickRegularPolygonShape);
218 setPreferredRendererType(CurveRenderer);
223 d->path =
new QQuickShapePath(
this);
224 d->path->setAsynchronous(
true);
225 d->path->setStrokeWidth(1);
226 d->path->setStrokeColor(QColorConstants::Black);
227 d->path->setFillColor(QColorConstants::White);
229 d->sp.append(d->path);
230 d->path->setParent(
this);
231 d->extra.value().resourcesList.append(d->path);
247void QQuickRegularPolygonShape::setDashOffset(qreal offset)
249 Q_D(QQuickRegularPolygonShape);
250 if (qFuzzyCompare(d->path->dashOffset(), offset))
252 d->path->setDashOffset(offset);
253 emit dashOffsetChanged();
270void QQuickRegularPolygonShape::setCornerRadius(qreal radius)
272 Q_D(QQuickRegularPolygonShape);
273 if (qFuzzyCompare(d->cornerRadius, radius))
275 d->cornerRadius = radius;
277 emit cornerRadiusChanged();
321void QQuickRegularPolygonShape::setStrokeWidth(qreal width)
323 Q_D(QQuickRegularPolygonShape);
324 if (qFuzzyCompare(d->path->strokeWidth(), width))
326 d->path->setStrokeWidth(width);
327 emit strokeWidthChanged();
436void QQuickRegularPolygonShape::setStrokeStyle(QQuickShapePath::StrokeStyle style)
438 Q_D(QQuickRegularPolygonShape);
439 if (d->path->strokeStyle() == style)
441 d->path->setStrokeStyle(style);
442 emit strokeStyleChanged();