私は基本的に2つの接続された線を取り、それらの間の接続点を取り除き、それを曲線に置き換える何らかの回避策を実装しました。このような変更が目に見えない小さな線がたくさんあるので、私は非常に短いすべての線を取り除き、開いた端を再接続します。 https://www.toptal.com/c-plus-plus/rounded-corners-bezier-curves-qpainter
そして、ここでの機能:機能は主にボヤンKverhによって提供された、彼のチュートリアルをチェックアウト
namespace
{
float distance(const QPointF& pt1, const QPointF& pt2)
{
float hd = (pt1.x() - pt2.x()) * (pt1.x() - pt2.x());
float vd = (pt1.y() - pt2.y()) * (pt1.y() - pt2.y());
return std::sqrt(hd + vd);
}
QPointF getLineStart(const QPointF& pt1, const QPointF& pt2)
{
QPointF pt;
float rat = 10.0/distance(pt1, pt2);
if (rat > 0.5) {
rat = 0.5;
}
pt.setX((1.0 - rat) * pt1.x() + rat * pt2.x());
pt.setY((1.0 - rat) * pt1.y() + rat * pt2.y());
return pt;
}
QPointF getLineEnd(const QPointF& pt1, const QPointF& pt2)
{
QPointF pt;
float rat = 10.0/distance(pt1, pt2);
if (rat > 0.5) {
rat = 0.5;
}
pt.setX(rat * pt1.x() + (1.0 - rat)*pt2.x());
pt.setY(rat * pt1.y() + (1.0 - rat)*pt2.y());
return pt;
}
}
void PainterPath::smoothOut(const float& factor)
{
QList<QPointF> points;
QPointF p;
for (int i = 0; i < mPath->elementCount() - 1; i++) {
p = QPointF(mPath->elementAt(i).x, mPath->elementAt(i).y);
// Except for first and last points, check what the distance between two
// points is and if its less then min, don't add them to the list.
if (points.count() > 1 && (i < mPath->elementCount() - 2) && (distance(points.last(), p) < factor)) {
continue;
}
points.append(p);
}
// Don't proceed if we only have 3 or less points.
if (points.count() < 3) {
return;
}
QPointF pt1;
QPointF pt2;
QPainterPath* path = new QPainterPath();
for (int i = 0; i < points.count() - 1; i++) {
pt1 = getLineStart(points[i], points[i + 1]);
if (i == 0) {
path->moveTo(pt1);
} else {
path->quadTo(points[i], pt1);
}
pt2 = getLineEnd(points[i], points[i + 1]);
path->lineTo(pt2);
}
delete mPath;
mPath = path;
prepareGeometryChange();
}
ええ、私はそれに簡単な解決策がないことを恐れていたが、私は2番目を持っていますベジェ曲線とBスプラインを見てください。 –
悪いニュースには申し訳ありません。私は非常に便利なリンクで回答を更新しました(実装にはActionScriptを使用します)。 – rbaleksandar
ありがとう、それは面倒な面白そうに見えます、私はそれを試してみましょう:D –