1、一阶贝塞尔曲线

一阶贝塞尔曲线其实是一条直线------给定点 P0、P1,线性贝塞尔曲线就是一条两点之间的直线,公式如下:
一阶曲线很好理解, 就是根据t来线性插值。
void MainWindow::mousePressEvent(QMouseEvent *e)
{
    list.append(e->pos());
    update();
}
void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    if(list.size() >= 2)
    {
        QPoint p0 = list.at(list.size() - 2);
        QPoint p1 = list.last();
        // 生成贝塞尔曲线路径
        QPainterPath path;
        path.moveTo(p0);
        for (float t = 0.0; t <= 1.000001; t += 0.1)
        {
            QPointF pt = linearBezier(t, p0, p1);
            path.lineTo(pt);
            drawPoint(painter, pt);
        }
        // 绘制曲线
        painter.setPen(Qt::blue);
        painter.drawPath(path);
    }
    else
        painter.fillRect(rect(), Qt::white);
}
QPointF MainWindow::linearBezier(float t, const QPointF &P0, const QPointF &P1)
{
    float x = (1 - t) * P0.x() + t * P1.x();
    float y = (1 - t) * P0.y() + t * P1.y();
    return QPointF(x, y);
}
void MainWindow::drawPoint(QPainter &painter, const QPointF &p)
{
    painter.save();
    QPen pen;
    pen.setWidth(8);
    pen.setColor(Qt::red);
    painter.setPen(pen);
    painter.drawPoint(p);
    painter.restore();
}
void MainWindow::on_pushButton_clicked()
{
    list.clear();
    update();
}2、二阶贝塞尔曲线

二阶贝塞尔曲线由三个控制点构成:起始点 P₀ 、控制点 P₁  和终止点 P₂。其数学表达式为:
其中,参数 t 从 0 到 1 变化时,曲线从 P₀  平滑过渡到 P₂ ,形状由 P₁ 的位置决定。
void MainWindow::mousePressEvent(QMouseEvent *e)
{
    list.append(e->pos());
    update();
}
void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    if(list.size() >= 3)
    {
        QPoint p0 = list.at(list.size() - 3);
        QPoint p1 = list.at(list.size() - 2);
        QPoint p2 = list.last();
        painter.setPen(Qt::green);
        painter.drawLine(p0, p1);
        painter.drawLine(p1, p2);
        // 生成贝塞尔曲线路径
        QPainterPath path;
        path.moveTo(p0);
        for (float t = 0.0; t <= 1.000001; t += 0.1)
        {
            QPointF pt = quadraticBezier(t, p0, p1, p2);
            path.lineTo(pt);
            drawPoint(painter, pt);
        }
        // 绘制曲线
        painter.setPen(Qt::blue);
        painter.drawPath(path);
    }
    else
        painter.fillRect(rect(), Qt::white);
}
QPointF MainWindow::quadraticBezier(float t, const QPointF& P0, const QPointF& P1, const QPointF& P2)
{
    QPointF result = (1 - t) * (1 - t) * P0 + 2 * (1 - t) * t * P1 + t * t * P2;
    return result;
}
void MainWindow::drawPoint(QPainter &painter, const QPointF &p)
{
    painter.save();
    QPen pen;
    pen.setWidth(8);
    pen.setColor(Qt::red);
    painter.setPen(pen);
    painter.drawPoint(p);
    painter.restore();
}
void MainWindow::on_pushButton_clicked()
{
    list.clear();
    update();
}3、三阶贝塞尔曲线

三阶贝塞尔曲线由4个控制点 P₀、P₁、P₂、P₃ 定义,参数方程为:
其中 t ∈ [0,1]。
该公式通过递归插值实现,支持生成含两个拐点的平滑曲线。
void MainWindow::mousePressEvent(QMouseEvent *e)
{
    list.append(e->pos());
    update();
}
void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    if(list.size() >= 4)
    {
        QPoint p0 = list.at(list.size() - 4);
        QPoint p1 = list.at(list.size() - 3);
        QPoint p2 = list.at(list.size() - 2);
        QPoint p3 = list.last();
        drawPoint(painter, p0);
        drawPoint(painter, p1);
        drawPoint(painter, p2);
        drawPoint(painter, p3);
        painter.setPen(Qt::green);
        painter.drawLine(p0, p1);
        painter.drawLine(p1, p2);
        painter.drawLine(p2, p3);
        // 生成贝塞尔曲线路径
        QPainterPath path;
        path.moveTo(p0);
        for (float t = 0.0; t <= 1.000001; t += 0.1)
        {
            QPointF pt = cubicBezier(t, p0, p1, p2, p3);
            path.lineTo(pt);
            drawPoint(painter, pt);
        }
        // 绘制曲线
        painter.setPen(Qt::blue);
        painter.drawPath(path);
    }
    else
        painter.fillRect(rect(), Qt::white);
}
// 计算三阶贝塞尔曲线上的点
QPointF MainWindow::cubicBezier(float t, const QPointF &P0, const QPointF &P1, const QPointF &P2, const QPointF &P3) {
    float x = pow(1 - t, 3) * P0.x() + 3 * pow(1 - t, 2) * t * P1.x() + 3 * (1 - t) * pow(t, 2) * P2.x() + pow(t, 3) * P3.x();
    float y = pow(1 - t, 3) * P0.y() + 3 * pow(1 - t, 2) * t * P1.y() + 3 * (1 - t) * pow(t, 2) * P2.y() + pow(t, 3) * P3.y();
    return QPointF(x, y);
}
void MainWindow::drawPoint(QPainter &painter, const QPointF &p)
{
    painter.save();
    QPen pen;
    pen.setWidth(8);
    pen.setColor(Qt::red);
    painter.setPen(pen);
    painter.drawPoint(p);
    painter.restore();
}
void MainWindow::on_pushButton_clicked()
{
    list.clear();
    update();
}觉得有帮助的话,打赏一下呗。。
 
 
需要商务合作(定制程序)的欢迎私信!!