軟件方法繪制,如QT、Android(skia)都自帶2D繪圖引擎,支持矢量路徑填充並且抗鋸齒!如果使用OpenGL繪制矢量,對建模算法以及紋理都有要求,不同的建模算法決定了最終的視覺效果。OpenGL繪制路徑,抗鋸齒效果由紋理來實現。下面介紹兩種不同效果的路徑實現和繪制:
通過紋理方式實現抗鋸齒單色路徑繪制。
建模算法非常簡單:將一個polyline分解成一些列兩點的線段,單獨對每個線段建模,如下圖0132和4576處貼兩個半圓,2354用寬度為1的像素條放樣生成。線段的末端是半圓,所以線段與線段之間能很好地銜接。
思路來源:http://answers.oreilly.com/topic/1669-how-to-render-anti-aliased-lines-with-textures-in-ios-4/
注意:如果貼圖是半透明的,拐角處紋理會增強,效果不理想,如下圖,所以該建模算法只適合單色不透明路徑。
現在各家手機地圖中路線都是立體紋理繪制,紋理效果如下圖:
實現立體路徑繪制,建模算法的難點在拐角處處理,尤其銳角,角度很小的時候如何處理。經過一段時間的研究,實現了一種簡單而且足夠魯邦的算法,思路非常簡單:銳角的時候進行插值(使用的是三次樣條插值),將銳角轉化成鈍角,鈍角的時候建模算法如下圖:
如上圖,一個建模處理單元由三個點組成,P0,P1,P2組成且夾角為鈍角,路徑寬度為2*radius,建模思路如下:
T1 = normalize( P1-P0 ); // P0P1 單位向量
N1 = Vec2f( -T1.y, T1.x); // 法線向量可以直接寫出
v0 = P0 + radius * N1; // 右手法則,v0方向為正
v1 = p0 - radius * N1;
v2 = P1 + radius * N1;
v3 = P1 - radius * N1;
T2 = normalize( P2-P1 ); // P0P1 單位向量
N2 = Vec2f( -T2.y, T2.x); // 法線向量可以直接寫出
v4 = P1 + radius * N2;
v5 = p1 - radius * N2;
v6 = P2 + radius * N2;
v7 = P2 - radius * N2;
verticesList: v0, v1, v2, v3, v4, v5, v6, v7
triangleIndexList: 0,1,2, 2,1,3, 2,4,5, 2,5,4, 2,3,4, 2,4,3, 4,5,6 6,5,7