32void QQuickRegularPolygonShapePrivate::updatePoints()
36 const qreal sliceAngle = 360.0f / sideCount;
37 const qreal a = width.valueBypassingBindings() / 2.0f;
38 const qreal b = height.valueBypassingBindings() / 2.0f;
39 const QVector2D center(a, b);
41 for (
int i = 0; i < sideCount; ++i) {
42 const qreal angleToCorner = qDegreesToRadians(i * sliceAngle);
45 const QVector2D xy = center + QVector2D(a * qSin(angleToCorner), -b * qCos(angleToCorner));
47 points.push_back(std::move(xy));
51void QQuickRegularPolygonShapePrivate::updateBisectors()
53 const auto size = points.size();
61 for (size_t i = 0; i < size; ++i) {
62 const auto &a = points[i];
63 const auto &b = points[(i == 0 ? size : i) - 1];
64 const auto &c = points[(i + 1 == size) ? 0 : (i + 1)];
66 const QVector2D vAB(b.x() - a.x(), b.y() - a.y());
67 const QVector2D vAC(c.x() - a.x(), c.y() - a.y());
68 const auto bisector = (vAB + vAC).normalized();
70 bisectors.push_back(std::move(bisector));
74void QQuickRegularPolygonShapePrivate::constructPolygonPath()
76 auto *ppath = QQuickShapePathPrivate::get(path);
79 path->setStartX(points[0].x());
80 path->setStartY(points[0].y());
82 for (
const auto &p : points) {
83 auto line =
new QQuickPathLine(path);
86 ppath->appendPathElement(line, QQuickPathPrivate::ProcessPathPolicy::DontProcess);
90 auto line =
new QQuickPathLine(path);
91 line->setX(points[0].x());
92 line->setY(points[0].y());
93 ppath->appendPathElement(line, QQuickPathPrivate::ProcessPathPolicy::DontProcess);
98void QQuickRegularPolygonShapePrivate::constructRoundedPolygonPath()
100 auto *ppath = QQuickShapePathPrivate::get(path);
104 const auto size = points.size();
105 for (size_t i = 0; i < size; ++i) {
106 const size_t idxMinusOne = (i == 0 ? size : i) - 1;
107 const size_t idxPlusOne = (i + 1 == size) ? 0 : (i + 1);
108 const auto &a = points[i];
109 const auto &b = points[idxMinusOne];
110 const auto &c = points[idxPlusOne];
111 qreal r = cornerRadius;
113 const QVector2D vAB(b.x() - a.x(), b.y() - a.y());
114 const QVector2D vAC(c.x() - a.x(), c.y() - a.y());
118 intersect(a, bisectors[i],
119 b, bisectors[idxMinusOne]);
121 intersect(a, bisectors[i],
122 c, bisectors[idxPlusOne]);
123 const qreal tMax = std::min(tAB, tAC);
126 const qreal alpha = qAcos(QVector2D::dotProduct(vAB, vAC) / (vAB.length() * vAC.length()));
131 const qreal maxRadius = std::round(QVector2D(c.x() - b.x(), c.y() - b.y()).length() / 2);
132 r = std::min(r, maxRadius);
135 const qreal cLength = r / (qSin(alpha / 2));
138 const qreal realC = std::min(cLength, tMax);
141 r = realC * qSin(alpha / 2);
143 const qreal t = qSqrt(qPow(realC, 2) - qPow(r, 2));
145 const auto p1 = (vAB.normalized() * t) + QVector2D(a.x(), a.y());
146 const auto p2 = (vAC.normalized() * t) + QVector2D(a.x(), a.y());
149 path->setStartX(p1.x());
150 path->setStartY(p1.y());
152 auto line =
new QQuickPathLine(path);
155 ppath->appendPathElement(line, QQuickPathPrivate::ProcessPathPolicy::DontProcess);
158 auto arc =
new QQuickPathArc(path);
163 ppath->appendPathElement(arc, QQuickPathPrivate::ProcessPathPolicy::DontProcess);
167 auto line =
new QQuickPathLine(path);
168 line->setX(path->startX());
169 line->setY(path->startY());
170 ppath->appendPathElement(line, QQuickPathPrivate::ProcessPathPolicy::DontProcess);
175void QQuickRegularPolygonShapePrivate::updatePath()
177 QQuickShapePathPrivate::get(path)->clearPathElements(
178 QQuickPathPrivate::DeleteElementPolicy::Delete);
182 if (qFuzzyCompare(cornerRadius, 0.0))
183 constructPolygonPath();
185 constructRoundedPolygonPath();
214QQuickRegularPolygonShape::QQuickRegularPolygonShape(QQuickItem *parent)
215 : QQuickShape(*(
new QQuickRegularPolygonShapePrivate), parent)
217 Q_D(QQuickRegularPolygonShape);
219 setPreferredRendererType(CurveRenderer);
224 d->path =
new QQuickShapePath(
this);
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);
233 connect(d->path, &QQuickShapePath::strokeColorChanged,
this, &QQuickRegularPolygonShape::strokeColorChanged);
234 connect(d->path, &QQuickShapePath::strokeWidthChanged,
this, &QQuickRegularPolygonShape::strokeWidthChanged);
235 connect(d->path, &QQuickShapePath::fillColorChanged,
this, &QQuickRegularPolygonShape::fillColorChanged);
236 connect(d->path, &QQuickShapePath::joinStyleChanged,
this, &QQuickRegularPolygonShape::joinStyleChanged);
237 connect(d->path, &QQuickShapePath::capStyleChanged,
this, &QQuickRegularPolygonShape::capStyleChanged);
238 connect(d->path, &QQuickShapePath::strokeStyleChanged,
this, &QQuickRegularPolygonShape::strokeStyleChanged);
239 connect(d->path, &QQuickShapePath::dashOffsetChanged,
this, &QQuickRegularPolygonShape::dashOffsetChanged);
240 connect(d->path, &QQuickShapePath::dashPatternChanged,
this, &QQuickRegularPolygonShape::dashPatternChanged);
241 connect(d->path, &QQuickShapePath::fillItemChanged,
this, &QQuickRegularPolygonShape::fillItemChanged);
242 connect(d->path, &QQuickShapePath::fillGradientChanged,
this, &QQuickRegularPolygonShape::fillGradientChanged);
278void QQuickRegularPolygonShape::setCornerRadius(qreal radius)
280 Q_D(QQuickRegularPolygonShape);
281 if (qFuzzyCompare(d->cornerRadius, radius))
283 d->cornerRadius = radius;
285 emit cornerRadiusChanged();