这是一个基于Qt的贝塞尔曲线实现代码示例:
#include <QPainter>
#include <QPoint>
#include <QWidget>
class BezierCurveWidget : public QWidget {
public:
explicit BezierCurveWidget(QWidget* parent = nullptr)
: QWidget(parent), p1_{0, height() / 2}, p2_{width(), height() / 2} {}
protected:
void paintEvent(QPaintEvent*) override {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 绘制控制点和辅助线
painter.setPen(QPen(Qt::black, 2));
painter.drawEllipse(p1_, 5, 5);
painter.drawEllipse(p2_, 5, 5);
painter.drawLine(QPointF(0, height() / 2), p1_);
painter.drawLine(QPointF(width(), height() / 2), p2_);
// 绘制贝塞尔曲线
painter.setPen(QPen(Qt::red, 3));
painter.drawBezierCurve(p1_, p2_);
}
void mousePressEvent(QMouseEvent* event) override { updateControlPoints(event->pos()); }
void mouseMoveEvent(QMouseEvent* event) override { updateControlPoints(event->pos()); }
private:
void updateControlPoints(const QPoint& pos) {
if (qAbs(pos.x() - p1_.x()) < qAbs(pos.x() - p2_.x())) {
p1_ = pos;
} else {
p2_ = pos;
}
update();
}
private:
QPointF p1_;
QPointF p2_;
};
// 扩展 QPainter 类,用于绘制贝塞尔曲线
class QPainterEx : public QPainter {
public:
explicit QPainterEx(QPaintDevice* device) : QPainter(device) {}
void drawBezierCurve(const QPointF& p1, const QPointF& p2) {
QPointF ctrl1((p2.x() - p1.x()) / 2 + p1.x(), p1.y());
QPointF ctrl2((p2.x() - p1.x()) / 2 + p1.x(), p2.y());
moveTo(p1);
cubicTo(ctrl1, ctrl2, p2);
stroke();
}
};
使用方法:
int main(int argc, char** argv) {
QApplication app(argc, argv);
BezierCurveWidget widget;
widget.resize(800, 600);
widget.show();
return app.exec();
}
运行程序,你将看到一个窗口,其中包含两个控制点和一条贝塞尔曲线。通过拖动控制点,可以手动绘制出不同的曲线形状。
使用 QPainterEx
类绘制贝塞尔曲线时,我们首先计算出两个控制点的位置,然后调用 cubicTo
方法绘制曲线。因为该类是 QPainter
的子类,所以另外的绘图功能也可以被直接使用。