GL绘制自定义线条3_自定义线帽
生活随笔
收集整理的這篇文章主要介紹了
GL绘制自定义线条3_自定义线帽
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
安卓Path搭配Paint可以設置線帽,我想能不能把我自己的線條繪制Demo也加上類似的功能。
線頭規則描述:
????????1、設一個線寬一半的線段,坐標為(0, 0)到(-lineWidth / 2, 0)。
????????2、設步驟1的線段有一垂直于它的向量(0,1),然后傳入最近兩次觸摸坐標,并將第二次觸摸坐標減去第一次觸摸觸摸坐標,得到當前畫線的前進方向向量,然后求與(0, 1)向量夾角。
????????3、以從步驟2中得到的夾角,到該夾角+180度為止,以一定的角度步進量旋轉步驟1的線段,形成一個切合線段的半圓。
????????4、最后添加一個(-lineWidth / 2, 0)到(lineWidth / 2, 0)的線段并旋轉到步驟3的最終角度,方便和線段本體對接。
線尾規則描述:
????????1、只需把線頭的規則中的步驟二改為,最后一次的之前一次的觸摸坐標 減去 最后一次的觸摸坐標作為方向向量即可(和前進方向相反)。
????????2、去冗余處理,每前進一次,就把之前添加的線尾半圓頂點刪掉。
????????關鍵代碼:
????????
/**給線頭添加符合線寬的邊界,便于和纖體本身鏈接**/private void lineCapAddBorder(double angle, float firstVec[], List<float[]> newVecs) {try {float rotatedVec0[] = rotate2d(new float[] {-mLineWidth / 2f, 0}, angle + 180);float rotatedVec1[] = rotate2d(new float[] {mLineWidth / 2f, 0}, angle + 180);float newVec[] = new float[6];//偏移到對應位置newVec[0] = rotatedVec0[0] + firstVec[0];newVec[1] = rotatedVec0[1] + firstVec[1];newVec[3] = rotatedVec1[0] + firstVec[0];newVec[4] = rotatedVec1[1] + firstVec[1];newVecs.add(newVec);} catch (Exception e) {e.printStackTrace();}}/**繪制線頭* @param isHead 是否曲線頭部添加線帽,否則視為曲線尾部添加線帽**/private int lineCap(boolean isHead, @NonNull float firstVec[], @NonNull float secVec[], int color) {if (null == firstVec) {return -1;}if (mHeadPointBuf == null) {mHeadCapPointByteBuffer = ByteBuffer.allocateDirect(mHeadInitVertexCount * 4); //頂點數 * sizeof(float)mHeadCapPointByteBuffer.order(ByteOrder.nativeOrder());mHeadPointBuf = mHeadCapPointByteBuffer.asFloatBuffer();mHeadPointBuf.position(0);mHeadCapPointBufferPos = 0;}//按初始化大小初始化RGBA字節數組和RGBA數組if (mHeadColorBuf == null) {mHeadCapColorByteBuffer = ByteBuffer.allocateDirect(mHeadInitColorCount * 4);mHeadCapColorByteBuffer.order(ByteOrder.nativeOrder());mHeadColorBuf = mHeadCapColorByteBuffer.asFloatBuffer();mHeadColorBuf.position(0);mHeadCapColorBufferPos = 0;}/**1、了解線條開始的方向,將半徑線條繞旋轉該方向與標準測量用向量的夾角的角度量* 2、旋轉180度時按照一定步進產生多個頂點,todo 但怎么確定旋轉的方向是順時針還是逆時針?以什么為依據判斷?以傳入向量方向為參考,但具體怎么做?*/float initVert[] = new float[] { //初始時左端點的坐標,初始時在原點兩側,然后以傳入的頂點作為偏移量-mLineWidth / 2f, 0};//旋轉并在過程中產生頂點float actualVec[] = new float[3];actualVec[0] = secVec[0] - firstVec[0];actualVec[1] = secVec[1] - firstVec[1];double angle = calcAngleOfVectorsOnXYPanel(mStandardVec, actualVec); //對比基準向量旋轉了多少度int step = 6; //改成只有90度可以得到一個尖頭筆帽List<float[]> newVecs = new LinkedList<>();if (!isHead) {//給曲線結尾加一段和線寬等長的邊lineCapAddBorder(angle, firstVec, newVecs);}//半圓線頭for (double degreeBias = angle; degreeBias <= 180 + angle; degreeBias += step) {try {float rotatedVec[] = rotate2d(initVert, degreeBias);float newVec[] = new float[6];//偏移到對應位置newVec[0] = rotatedVec[0] + firstVec[0];newVec[1] = rotatedVec[1] + firstVec[1];newVec[3] += firstVec[0];newVec[4] += firstVec[1];newVecs.add(newVec);} catch (Exception e) {e.printStackTrace();}}if (isHead) {//給曲線開頭加一段和線寬等長的邊lineCapAddBorder(angle, firstVec, newVecs);}for (float[] newVec : newVecs) {for (int i = 0; i < newVec.length; i++) {checkCapacity();mPointBuf.put(mPointBufferPos++, newVec[i]);}for (int i = 0; i < newVec.length / 3; i++) {checkCapacity();//寫入顏色值r,g,b,afloat alpha = (float) (((color & 0xFF000000) >> 24) & 0x000000FF) / 255f;float blue = (float) ((color & 0x000000FF)) / 255f;float green = (float) ((color & 0x0000FF00) >> 8) / 255f;float red = (float) ((color & 0x00FF0000) >> 16) / 255f;mColorBuf.put(mColorBufferPos++, red);mColorBuf.put(mColorBufferPos++, green);mColorBuf.put(mColorBufferPos++, blue);mColorBuf.put(mColorBufferPos++, alpha);}}return newVecs.size() * newVecs.get(0).length;}最后效果:
旋轉步進設定為90度,因此能顯示尖頭效果:
?設定為15度,則可以形成非常圓潤的線頭:
以線條方式繪制,即可看到頂點構成如下圖:
?基本再現了Android path + paint的大部分線條效果了。
總結
以上是生活随笔為你收集整理的GL绘制自定义线条3_自定义线帽的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华唯鑫能油能否与矿物油、加氢油、合成油对
- 下一篇: curve25519-dalek中Sca