gpt4 book ai didi

c++ - 如何在QT中绘制一条经过多个点的平滑曲线?

转载 作者:太空狗 更新时间:2023-10-29 22:58:24 42 4
gpt4 key购买 nike

有没有办法通过QT中的一组点绘制一条平滑的线?点的数量和位置在运行时设置。

目前,我绘制了一个 QPainterPath,其中包含从一个点到另一个点的 lineTo,创建一条路径。我确实使用了渲染提示抗锯齿,但路径仍然是锯齿状的。

我见过 QSplineSeries,它似乎提供了这种弯曲的路径,但它在 Qt4.8 中不可用,这是我正在使用的 QT 版本。

另一个经常被建议的选项是使用贝塞尔曲线,但那些使用一个起点和终点以及两个控制点,所以我需要为每个线段(每个 lineTo)计算它并以某种方式计算那些我不知道的控制点目前没有。

最佳答案

最后,我实现了某种解决方法,基本上采用两条连接线,删除它们之间的连接点并用曲线替换它。由于我有很多细线,这样的变化是不可见的,所以我删除了所有非常短的线并重新连接了开口端。该功能主要由 Bojan Kverh 提供,查看他的教程:https://www.toptal.com/c-plus-plus/rounded-corners-bezier-curves-qpainter

这里是函数:

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();
}

关于c++ - 如何在QT中绘制一条经过多个点的平滑曲线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40764011/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com