欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > 贝塞尔曲线学习

贝塞尔曲线学习

2025/4/18 22:36:05 来源:https://blog.csdn.net/ckg3824278/article/details/146042281  浏览:    关键词:贝塞尔曲线学习

1、一阶贝塞尔曲线

一阶贝塞尔曲线其实是一条直线——给定点 P0、P1,线性贝塞尔曲线就是一条两点之间的直线,公式如下:

B(t) = P0 + (P1 - P0)t = (1-t)P0 + tP1, t\epsilon [0,1]

一阶曲线很好理解, 就是根据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);}elsepainter.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₂‌‌。其数学表达式为:

B(t) = (1 - t)^2 * P0 + 2t * (1-t) * P1 + t^{2} * P2

其中,参数 ‌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);}elsepainter.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₃‌ 定义,参数方程为:

B(t) = (1-t)^{3} * P0 + 3 * (1-t)^{2} * t * P1 + 3 * (1-t) * t^{2} * P2 + t^{3} * P3    

其中 ‌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);}elsepainter.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();
}

觉得有帮助的话,打赏一下呗。。

           

需要商务合作(定制程序)的欢迎私信!! 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词