Qt学习——绘制贝塞尔曲线

1、绘制曲线

首先认为所有的线都是由点组成的,于是尝试采用直接绘制两点连接直线的方式来绘制曲线,代码如下

    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing);

    painter.setPen(QPen(Qt::red,2,Qt::SolidLine));

    for(int i = 0; i < _lines.size(); ++i)
    {
        const QVector<QPointF> &line = _lines.at(i);       //鼠标移动采集的点,通过引用取出,                确保操作的是同一块内存
        for(int j = 1; j < line.size()-1; ++j)
        {
            QLineF lineF = QLineF(line.at(j), line.at(j + 1));
            painter.drawLine(lineF);

        }
    }

但是仔细观察会发现每个点之间的连接处并不平滑,达不到平滑曲线的效果,于是采用另外一种实现方式,通过贝塞尔曲线来调整曲线

2、绘制贝塞尔曲线

在绘制贝塞尔曲线前需要学习了解一个关键类——QPainterPath

官方解释:QPainterPath类为绘制操作提供了一个容器,允许构造和重用图形形状。
画家路径是由许多图形构建块(如矩形、椭圆、直线和曲线)组成的对象。构建块可以在封闭的子路径中连接,例如作为一个矩形或椭圆。闭合路径的起点和终点是重合的。或者它们可以独立地作为未封闭的子路径存在,比如直线和曲线。
QPainterPath对象可用于填充、勾勒和剪裁。为给定的画家生成可填充的轮廓。

通过QPainterPath可以实现任意图形的绘制

 painter.setPen(QPen(Qt::red,2,Qt::SolidLine));

    for(int i = 0; i < _lines.size(); ++i)
    {
        QLineF prevLine;
        const QVector<QPointF> &line = _lines.at(i);       //鼠标移动采集的点,通过引用取出,                确保操作的是同一块内存
        for(int j = 1; j < line.size()-1; ++j)
        {
            QPainterPath strokesPath;
            prevLine = QLineF(line.at(j - 1), line.at(j));  //获取上一个线段
            QLineF curLine(line.at(j), line.at(j + 1));     //获取当前线段
            strokesPath.moveTo(prevLine.pointAt(0.5));      //将当前线段路径的起点移至上一线段的中点
            strokesPath.quadTo(line.at(j), curLine.pointAt(0.5));       //将当前点设置为曲线控制点,当前线段的中点设置为曲线的结束点
            painter.drawPath(strokesPath);      //绘制曲线
        }

    }

绘制贝塞尔曲线采用的也是点对点拼接成曲线,不同的是拼接的点选取的是上一条绘制线段的中点,每次绘制是通过moveTo函数将绘制的起点移动到上一条线段的中点(pointAt(0.5);取值为0-1,0为线段起点,1位线段终点;);通过quadTo函数,在当前位置和给定端点之间添加一条二次贝塞尔曲线,控制点由c指定,第一个参数为控制点。添加曲线后,当前点被更新为曲线的结束点,第二个参数为结束点。

此处需要注意的是如果采用线段末端进行拼接的话,因为每次绘制曲线时都是只绘制了当前获取的两个点之间的线段,而上一条线段的终点一下一条线段的起点之间只是单纯的拼接,并没使用贝塞尔曲线的绘制。

(注:个人见解,如有异议,欢迎斧正)。

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值