如題:
公司要求作一個塗鴉板,要有鋼筆、毛筆等畫筆效果,網上搜了不少,但是效果不怎麼好,決定本身研究下。廢話很少說,進入正題。
首先,賽貝爾曲線弄明白了,在畫曲線的過程當中就是一條條的向量。
第二,曲線在畫的過程當中要有粗細變化(就是簡單的實現)
第三,在原有向量的兩側也畫兩個兩向量A1B一、A2B2。以下圖:
上圖中,線段A1A2的長度跟畫筆移動速度存在f1(x)的關係。黑色曲線是向量AB經過賽貝爾畫出來的效果。
下面介紹畫筆實現的邏輯:
爲了實現畫筆效果,其實就是一共畫了三條賽貝爾曲線,分別根據向量A1B1,AB,A2B2所得(見上圖)。A一、A2是經過AB向量求得的,A點是向量A1A2的中點,AB垂直於A1B1。
再通過屢次測試後,我找到了計算A1A2長度值是比較關鍵的問題,單純的靠一個線性函數算出來的結果顯示很糟糕。我的推薦:利用正選函數或者餘弦函數的變化來求得。代碼以下:
<span style="white-space:pre"> </span>private final float KEY_PAINT_WIDTH=2.5f;//當速度很慢時,畫出的曲線爲畫筆寬度的多少倍,此值通過測試不會有間隙或者很小。
/**
* 根據變化的餘弦函數y=0.5*[cos(x*PI)+1](0<x<1),將速度轉化爲畫筆寬度的2.5倍。
* x<0,寬度爲最大寬度,2.5倍畫筆寬度
* 0<x<1,根據上面函數,進行轉化
* x>1,根據函數y=width/x,當y<0.2時,取最小值0.2
* @param delayTime
* @return
*/
private float controlPaint(double v){
//餘弦函數
//y=0.5*[cos(x*PI)+1]
float result=KEY_PAINT_WIDTH*paintSize;
if(v<0){
}else if(v<1){
result=(float) (0.5*paintSize*KEY_PAINT_WIDTH*(Math.cos(v*Math.PI)+1));
}else{
result=((float) (paintSize/v>0.1?paintSize/v:0.1));
}
return result;
}
轉化函數須要根據本身測定的畫筆速度的合適值進行相應的轉化,這裏不作過多贅述。
實現書寫的效果以下圖(測試在平板(分辨率1280*800)):函數
原文地址:http://blog.csdn.net/sbduxing/article/details/39343465測試