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();
}
觉得有帮助的话,打赏一下呗。。
需要商务合作(定制程序)的欢迎私信!!