日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/1/21 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt 实现钢笔画线效果详细原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

上一篇文章:Qt 實現畫線筆鋒效果詳細原理,根據這篇介紹的實現筆鋒效果的原理,我們很容易實現另外一種筆效:鋼筆。

所謂的鋼筆筆效,就是真實還原鋼筆書寫出來的線條效果,其特征就是:根據筆的繪制速度而線條的寬度會逐漸變化,寫得越快,線條越細,并且在收筆時帶有筆鋒效果。

那么,在上一篇文章的基礎上,稍微修改一下,就可以實現這個效果,看下效果圖:

實現原理

從上一篇文章我們知道,繪制的曲線是通過每兩個點形成一條貝塞爾曲線,所以在不松手的情況下連續畫線,整條線段是包含很多條path組合而成的。而要實現鋼筆效果的關鍵,是要讓線條的粗細跟隨繪制的速度來變化。

之前看過很多Android上實現鋼筆或者毛筆的算法,都是需要計算去畫線速度,根據速度來動態改變線條的粗細。但是我這里沒有計算速度,而是直接通過每一段path的長度來計算一個合理的寬度值出來。

眾所周知,長度(也就是距離)= 速度*時間,在單位時間內,速度和距離是成正比的,所以我們通過兩點間的距離來做判斷也是一樣的,沒多大區別,并且還不用單獨去計算速度了,簡單省事兒。

那么,我們要實現的效果是,畫線速度越快線條會越細,而畫線速度越快,所采集到的兩點間的距離就會越大,而我們是通過兩點間距離來做參考依據,也就是說,兩點間距和線條粗細是成反比的,兩點間距越長,對應的這條path就越細,距離越短,path就越粗,二者是線性關系。當然,這里path的寬度會有一個最大值和最小值,需要在實際的場景中進行調試。

OK,根據以上分析,我們可以得到以下的示意圖:

每條path都是通過兩個坐標點實時生成的貝塞爾曲線。
在繪制這條曲線的時候,先獲取到曲線的長度,然后線性計算出一個寬度值。
如何獲取path的長度呢?
這個好辦,QPainterPath有自帶的接口length():

計算曲線的寬度,我寫了一個簡單的計算方法:

qreal WbCanvasItem::calPathWidth(QPainterPath path) {qreal length = path.length();qreal width = PENWIDTH;qreal t = length/10. - 1;width = PENWIDTH - t;if(width < 3){ //最小寬度width = 3;}return width; }

PENWIDTH是一個宏定義,曲線最大寬度;

根據以上步驟,我們來看一下效果:

為了方便看效果,每條path用了不同的顏色來區分。我們可以很明顯的看到,path的寬度是不一樣的,并且每條path的連接處的寬度變化非常明顯,那么要怎么使其連接處變得平滑呢?

這時候就要用到上一篇介紹的方法進行補點了。這里的補點比上一篇文章中說的稍微麻煩點,需要將中間那根線條的兩頭都要補充點,其原理是一樣的。

看一下示意圖:

以上紅色圈圈部分,就是補充的點。
從以上圖可以看到,path2是倒數第二條path,path3是最后一條path。

需要注意的是,圖中補充的兩個地方,并不是同一時間補充的,當有新的path到來,只需要判斷最新的path和上一個path的寬度,從而決定是補充到上一個path還是當前最新的path上。

這段話有點拗口,拆解一下:

假如這里path2是最后的一條path,而path1是倒數第二條,判斷出來path2寬度筆path1小,那么就在path2的路徑上補充點;

再看一種情況:

同樣,這里path2是最后的一條path,而path1是倒數第二條,判斷出來path2寬度筆path1大,那么就在path1的路徑上補充點;

這樣描述就很容易理解了。

OK,我們看一下補充點的代碼:

void WbCanvasItem::drawPatchPoint2(QPainter *painter, QPainterPath lastPath,QPainterPath curPath,qreal lastWidth, qreal curWidth) {qreal tPatchLength = 100.;if(lastWidth < curWidth){tPatchLength = calPatchLength(curPath.length());qreal temp = (curWidth-lastWidth)/tPatchLength;int k = 0;for (qreal i = 1;i > (100-tPatchLength)/100.; i-=0.01) {k++;painter->setPen(QPen(Qt::black,curWidth-temp*k, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));painter->drawPoint(lastPath.pointAtPercent(i));}}else if(lastWidth > curWidth){tPatchLength = calPatchLength(curPath.length());qreal temp = (lastWidth-curWidth)/tPatchLength;int k = 0;for (qreal i = 0;i < tPatchLength/100.; i+=0.01) {k++;painter->setPen(QPen(Qt::black,lastWidth-temp*k, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));painter->drawPoint(curPath.pointAtPercent(i));}} }

看一下補充點后的效果:

這里的黑色部分就是動態補充上去的點。

好了, 整理原理分析完成,其實和前面一篇文章原理差不多,只是多了一步判斷距離然后計算線寬的過程。

總結

以上是生活随笔為你收集整理的Qt 实现钢笔画线效果详细原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产欧美在线 | 国产剧情一区二区三区 | 免费成人高清在线视频 | 成人爽a毛片一区二区免费 日本高清免费看 | 69免费 | 欧美日韩3p| 日韩精品成人无码专区免费 | 国产淫视频 | 免费在线精品视频 | 蜜臀久久99精品久久久无需会员 | 免费色网址 | 麻豆传媒网址 | 天天躁日日躁狠狠躁av麻豆男男 | 久久手机看片 | 日韩福利小视频 | 国产精品人人妻人人爽 | 自拍偷拍另类 | 国产精品国产精品国产专区蜜臀ah | 日韩久久高清 | yjizz国产| 日韩av资源 | 国产xxx69麻豆国语对白 | 亚洲一区二区色图 | 国产日韩一区二区 | www.午夜视频 | 97精品| 欧美男女交配视频 | 欧美在线视频二区 | 成人69视频| av网站大全免费 | 成人av教育 | 国产成人综合精品 | 日韩精品一区二区三区中文在线 | 亚洲熟女乱色一区二区三区久久久 | 久艹视频在线观看 | 青娱乐在线播放 | 色婷婷综合成人av | 男女免费毛片 | 亚洲成人影音 | 成人入口| 深爱激情丁香 | 夜夜爽夜夜| 男人天堂网在线视频 | 欧美成人三级伦在线观看 | 日本黄色天堂 | 网站av| 欧美日韩精品一区 | 日韩av自拍偷拍 | 自拍偷拍麻豆 | 欧美精产国品一二三区 | 国产做a| 亚洲午夜毛片 | 国产美女视频免费观看下载软件 | 永久免费看成人av的动态图 | 日本黄页网址 | 日日干日日插 | 97se综合| 久久久久亚洲av成人人电影 | 国产无遮挡18禁无码网站不卡 | 国产一级伦理片 | 久久泄欲网 | 另类小说亚洲色图 | 亚洲AV无码一区二区三区少妇 | 国产视频一区二区在线 | 影音先锋丝袜制服 | 午夜性 | 一级a毛片免费观看久久精品 | 色婷婷五 | 四虎成人网 | 久久人妻少妇嫩草av无码专区 | 韩国av一区二区三区 | 日韩成人av一区二区 | 熟妇高潮一区二区三区在线播放 | 色综合久久五月 | 国产伦精品一区二区三区免.费 | 黑人满足娇妻6699xx | 吻胸摸激情床激烈视频大胸 | 少妇一级淫片日本 | 另类欧美亚洲 | 日韩久久在线 | 一区二区国产在线 | 国产黄色大片免费看 | 国产乱了高清露脸对白 | 噼里啪啦免费观看 | 色窝窝无码一区二区三区 | 久久久免费精品视频 | 黄色污污网站在线观看 | 午夜视频在线观看一区 | 日日夜夜操av | 亚洲国产精品一区二区尤物区 | www.-级毛片线天内射视视 | 毛片aaaaaa | 日本不卡视频在线观看 | 亚洲色图27p | 欧美黄色三级 | 美味的客房沙龙服务 | 91国偷自产一区二区三区观看 | 成人精品| 天天干天天操天天 |