Qt 实现画线笔锋效果详细原理
前言
之前写过一篇文章介绍Qt中绘制平滑曲线的两种方式,文章在这里。这篇文章详细介绍了绘制的原理和实现方式,那么,如果要在此曲线上实现笔锋效果怎么做呢?
所谓的笔锋效果,就是钢笔书写抬笔时的笔尖,也就是说,绘制曲线抬笔时形成一个笔尖的效果。
话不多说,直接来看效果:
动画效果如下:
实现原理
要实现该效果,需要完成以下几个关键步骤:
- 1.每两个点形成一个贝塞尔曲线path进行绘制
- 2.最新的一条path绘制细线(笔锋最细处的宽度)
- 3.倒数第二条path绘制粗线(正常的线条宽度)
- 4.在两条path连接处补充点使其过渡平滑
接下来一步步的分析,首先第一条,每两个点形成一个贝塞尔曲线path进行绘制,这个比较简单,就不多讲了吧,也就是说,在move事件中,每来一个新点,就让该点和前一个点生成一个贝塞尔曲线,使用QPainterPath中的quadTo
函数,之所以要用贝塞尔曲线,是为了解决折线问题,这个在前面的文章中已经介绍过了。这里就不重复说咯。
我们直接来看第二条: 最新的一个path绘制细线。
这个怎么理解呢?看一个图示:
以上是线条放大的效果,最新的path,也就是上面的newPath,通过当前点和前一个点生成的这条path,绘制一条细线,这条线就作为笔锋,假如这时候抬笔,那么newPath就是最后一条线段,那么笔锋就是这条线来形成的。
做完第二步,我们看一下绘制效果:
第三步:倒数第二条path绘制粗线(正常的线条宽度)
从上面的图示可以看到,我们将最新的newPath绘制细线,那么如果这时候又出现一个新的点,形成了新的path,而之前的newPath就会变成前一个path,这里命名为lastPath,由于该path还是细线,所以这里我们需要将前一个path重新补充绘制成正常的粗线,图示如下:
这里的黄线,也就是我们补充绘制的线条,而最新的path依然是细线,根据以上示意图就很容易明白了。
所以简单来说,就是不断的将最新path绘制成细线,然后将前一个path补充绘制成粗线。
看一下效果:
为了区分不同的path,这里采用了不同的颜色来代表,每一段颜色代表一个path,最新的path就是右边的绿色线条,可以看到最新的path和前一条path由于线宽不同, 所以连接处并不平滑,所以要解决这个问题,需要做最后一步:补点。
什么是补点,就是说我们需要在连接处 根据最新path的线条路径来绘制一系列的点进行填充,使其连接处看起来平滑,图示如下:
上面的圈圈就是补充的点,点与点之间距离越小,看起来就越平滑,而圈圈的圆心点是跟随最新的path线条走的,就是path线的线条高度的中心点,圈圈的半径大小逐渐变小。
再看看补充点后的效果:
可以看到,笔尖黑色的地方线条就是通过补充点来实现的。
那么,问题来了,如何知道最后这条path的路径呢?
其实Qt已经提供了接口,我们通过QPainterPath来生成的曲线,这个类提供了一个函数叫pointAtPercent
,定义如下:
这个接口就是返回在path曲线上的坐标点,通过传入百分比来调用,很方便了吧。
我这里的补充点实现方式,就是通过循环的不断的绘制:
//在两个path连接处绘制补充点,使其连接处平滑
void WbCanvasItem::drawPatchPoint(QPainter * painter,QPainterPath path)
{qreal temp = (PENWIDTH-3)/100.;int k = 0;for (qreal i = 0;i < 1; i+=0.01) {k++;painter->setPen(QPen(Qt::black,PENWIDTH-temp*k, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));painter->drawPoint(path.pointAtPercent(i));}
}
前三步骤代码:
QPainterPath lastPath = obj->StrokeLastPath(PENWIDTH);
m_pRealPainter->fillPath(lastPath,Qt::red);//填充轮廓
path = obj->StrokePath(3);
m_pRealPainter->fillPath(path,Qt::red);//填充轮廓
drawPatchPoint(m_pRealPainter,obj->path());
ok ,整个实现方式已介绍完成,本文主要讲解原理,代码未整理,就不上传了,用到的关键函数已经介绍过,只要明白原理过后,根据原理一步步的操作,就可以实现了。
Qt 实现钢笔画线效果详细原理
Qt 实现画线笔锋效果详细原理相关推荐
- Qt 实现钢笔画线效果详细原理
前言 上一篇文章:Qt 实现画线笔锋效果详细原理,根据这篇介绍的实现笔锋效果的原理,我们很容易实现另外一种笔效:钢笔. 所谓的钢笔笔效,就是真实还原钢笔书写出来的线条效果,其特征就是:根据笔的绘制速度 ...
- 基于Canvas的画线动画效果
想着用js实现一个画线动画,借助Canvas实现了.动画效果: 手机端访问 https://sagitarioo.github.io/Personal/htmlCode/linePaint/lineS ...
- html5画线的效果属性,canvas线条的属性详解
一.线条的帽子lineCap 取值:butt(默认值),round圆头,square方头 var canvas=document.getElementById("canvas"); ...
- 高德地图实现画线搜索
今天分享一下,使用高德地图api实现上图可自由画线的效果. 查看高德官方文档会发现,并没有可自主画图,文档提供的矢量图功能有: AMap.Polyline 构造折线 AMap.BezierCurve ...
- Qt实现桌面画线、标记,流畅绘制,支持鼠标和多点触控绘制原创
前言 经常会在网上直播讲课或者点评中看到可以在课件上或者桌面上进行画线标记划重点,其实实现并不难,原理就是在桌面上盖一个透明图层,然后根据鼠标点绘制曲线. 今天分享如何通过Qt的QGraphics体系 ...
- Qt实现桌面画线、标记,流畅绘制,支持鼠标和多点触控绘制
前言 经常会在网上直播讲课或者点评中看到可以在课件上或者桌面上进行画线标记划重点,其实实现并不难,原理就是在桌面上盖一个透明图层,然后根据鼠标点绘制曲线. 今天分享如何通过Qt的QGraphics体系 ...
- Qt Scene graph画线
前言 想要实现在QML中画线,有几种方式: 第一种,用在QML中用Canvas来实现画线功能,经过实践,效率比较低,折线非常严重,特别是在Android手机上运行. 第二种,通过QPainter来绘制 ...
- 【QT 5 学习笔记-学习绘图相关+画线图形等+绘图事件+基础学习(1)】
[QT 5 学习笔记-学习绘图相关+画线图形等+绘图事件+基础学习(1)] 1.说明 2.实验环境 3.参照学习链接 4.自己的学习与理解 5.学习与实践代码. (1)建立基础工程. (2)加入绘图事 ...
- 毛边效果 html,Html5 Canvas画线有毛边解决方法
例外参考:http://jo2.org/html5-canvas%E7%94%BB%E5%9B%BE3%EF%BC%9A1px%E7%BA%BF%E6%9D%A1%E6%A8%A1%E7%B3%8A% ...
- 毛边效果 html,Html5中Canvas画线有毛边如何解决
Html5 Canvas 所有的画线指令画出来的线条都有毛边(比如 lineTo, arcTo,strokeRect),这是因为在Canvas中整数坐标值对应的位置恰巧是屏幕象素点中间的夹缝,那么当按 ...
最新文章
- 一起智慧课堂_智慧课堂与传统课堂相比,优点在哪些
- pytorch 加载模型 模型大小测试速度
- NA-NP-IE系列实验实验15:RIPv2 手工汇总
- MVC POST请求后执行javascript代码
- 如何创建Java程序
- 基于STM32L476的锂电池SOC检测
- centos 6.6 mysql5.7_CentOS 6.5/6.6 安装(install)mysql 5.7 最完整版教程-Go语言中文社区...
- Oracle AutoVue 21.0.x最新支持程序文件格式及版本
- Sprite Renderer
- 小白入门---HTML5音乐播放器
- 【AI入门学习方法】
- python 7-33 修理牧场 (25 分) PTA
- Global Shutter和Rolling Shutter之间的区别
- SecureCRT的设置
- php.符号,特殊符号大全
- IntelliJ IDEA 新版 UI 中的项目导航改进
- 我的日期工具类、java常见时间的处理方法
- 自动称重管理软件功能如何助力企业实现信息化(二)
- CVPR2022《NFormer: Robust Person Re-identification with Neighbor Transformer》
- JBPM具体应用之decision节点的使用
热门文章
- c语言中结构体中默认值,C Struct中的缺省值
- html的excel表格自动换行,Excel单元格内换行实现同时设置多单元格自动换、避免输入短横线...
- 计算机应用基础中专起大专,17秋中国医科大学《计算机应用基础(中专起点大专)》在线作业标准100分答案...
- 使用CA签发的服务器证书搭建Tomcat双向SSL认证服务
- 【SAP消息号KD503】
- mysql常用存储引擎以及悲观锁与乐观锁
- 最新微信公众号采集方案详细介绍
- c语言编程一个超市购物程序,急求一超市的销售记录C程序(各位大哥帮帮忙啊!)...
- Error starting userland proxy: listen tcp 0.0.0.0:xxx端口: bind: address already in use解决办法
- php deflate 解压,PHP编码gzdeflate与Golang解码DEFLATE