Qt 实现钢笔画线效果详细原理


前言

最后一篇:Qt实现笔画效果的详细原理。根据本文介绍的实现笔画效果的原理,我们可以很容易地实现另一种笔画效果:笔。

所谓的笔效应就是恢复笔所写的线条效果。它的特点是线条的宽度会随着钢笔的绘图速度而逐渐变化。笔写得越快,线条就越细,当笔合上时,线条就会变得清晰。

然后,在前一篇文章的基础上,稍微修改一下就可以达到这个效果。请看效果图:

ImplemEntation Principle

从上一篇文章中,我们知道绘制的曲线通过每两点形成一条贝塞尔曲线,所以直线是连续绘制的,没有放开,整个线段由许多路径组合组成。钢笔效果的关键是使线条的粗细随着绘图速度而变化。

我以前在安卓系统上见过很多实现钢笔或刷子的算法。他们都需要计算画线的速度,并根据速度动态改变线条的粗细。然而,我不在这里计算速度,而是通过每条路径的长度直接计算一个合理的宽度值。

众所周知,长度(即距离)=速度*时间。在一个时间单位中,速度和距离是成正比的,所以我们用两点之间的距离来判断是相同的,没有太大的差别,也没有必要单独计算速度,这样既简单又方便。

然后,我们想要达到的效果是画线速度越快,线条就越细,画线速度越快,两点之间的距离就越大。我们使用两点之间的距离作为参考依据,也就是说,两点之间的距离与线的厚度成反比。两点之间的距离越长,对应的路径越薄,距离越短,路径越厚,两者呈线性关系。当然,这里的路径宽度会有一个最大值和一个最小值,这需要在实际场景中调试。

好的,根据上面的分析,我们可以得到下面?氖疽馔?:

每条路径都是通过两个坐标点实时生成的贝塞尔曲线。

绘制此曲线时,首先获取曲线的长度,然后线性计算宽度值。

我如何得到路径的长度?

这很容易处理。QPainterPath有自己的接口:

来计算曲线的宽度。我写了一个简单的计算方法:

PENWIDTH是一个宏定义,是曲线的最大宽度;

根据以上步骤,让我们来看看效果:

为了方便查看效果,每条路径都用不同的颜色区分。我们可以很明显地看到,路径的宽度是不同的,每条路径的连接宽度变化很明显,那么我们如何才能平滑连接呢?

此时,我们将使用上一篇文章中介绍的方法来弥补它。这里的填充点比前一篇文章中提到的稍微麻烦一些。您需要在中间线的两端添加点。原则是一样的。

请看示意图:

上面的红色圆圈是补充点。

从上图可以看出,路径2是倒数第二个路径,路径3是最后一个路径。

应该注意的是,图中添加的两个位置不是同时添加的。当新路径到达时,仅需要确定最新路径的宽度和先前路径的宽度,以决定是添加到先前路径还是当前最新路径。

这段话有点难讲。拆开它:

如果路径2是最后一个路径,路径1是倒数第二个,判断路径2有一个小宽度的笔路径2,在路径2上加一个点。

让我们看看另一种情况:

同样,这里路径2是最后一个路径,路径1是倒数第二个,判断路径2有一个大宽度的笔路径1,然后在路径1上添加点;

这个描述很容易理解。

好,让我们看看补充点的代码:

看看补充点后的效果:

这里的黑色部分是动态添加的点。

嗯,对排序原则的分析已经完成,除了判断距离然后计算线宽的过程之外,与上一篇文章中的原则类似。