android 使用Canvas畫箭頭
阿新 • • 發佈:2019-01-23
畫箭頭這個東西太麻煩啦,開始想用把箭頭畫好,然後到指定點旋轉的方法,但是,效果一直不好。想用數學的方法來畫,但是發現計算很複雜啊。於是google,發現一個兄臺使用了java當中的awt實現了畫箭頭(http://www.bangchui.org/simple/?t16755.html),於是就借過來,改了一下,結果真能用。成果不敢獨佔,在此拿來給大家分享:
顯示效果如下圖所示:public class MyCanvas extends View{ private Canvas myCanvas; private Paint myPaint=new Paint(); public MyCanvas(Context context) { super(context); // TODO Auto-generated constructor stub } public MyCanvas(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public MyCanvas(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); this.myCanvas=canvas; drawAL(0, 0, 100, 100); } /** * 設定畫筆預設樣式 */ public void setPaintDefaultStyle(){ myPaint.setAntiAlias(true); myPaint.setColor(Color.RED); myPaint.setStyle(Paint.Style.STROKE); myPaint.setStrokeWidth(3); } /** * 畫圓 * @param x x座標 * @param y y座標 * @param radius 圓的半徑 */ public void drawCircle(float x,float y,float radius){ myCanvas.drawCircle(x, y, radius, myPaint); invalidate(); } /** * 畫一條直線 * @param fromX 起點x座標 * @param fromY 起點Y座標 * @param toX 終點X座標 * @param toY 終點Y座標 */ public void drawLine(float fromX,float fromY,float toX,float toY){ Path linePath=new Path(); linePath.moveTo(fromX, fromY); linePath.lineTo(toX, toY); linePath.close(); myCanvas.drawPath(linePath, myPaint); invalidate(); } /** * 畫箭頭 * @param sx * @param sy * @param ex * @param ey */ public void drawAL(int sx, int sy, int ex, int ey) { double H = 8; // 箭頭高度 double L = 3.5; // 底邊的一半 int x3 = 0; int y3 = 0; int x4 = 0; int y4 = 0; double awrad = Math.atan(L / H); // 箭頭角度 double arraow_len = Math.sqrt(L * L + H * H); // 箭頭的長度 double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len); double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len); double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端點 double y_3 = ey - arrXY_1[1]; double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端點 double y_4 = ey - arrXY_2[1]; Double X3 = new Double(x_3); x3 = X3.intValue(); Double Y3 = new Double(y_3); y3 = Y3.intValue(); Double X4 = new Double(x_4); x4 = X4.intValue(); Double Y4 = new Double(y_4); y4 = Y4.intValue(); // 畫線 myCanvas.drawLine(sx, sy, ex, ey,myPaint); Path triangle = new Path(); triangle.moveTo(ex, ey); triangle.lineTo(x3, y3); triangle.lineTo(x4, y4); triangle.close(); myCanvas.drawPath(triangle,myPaint); } // 計算 public double[] rotateVec(int px, int py, double ang, boolean isChLen, double newLen) { double mathstr[] = new double[2]; // 向量旋轉函式,引數含義分別是x分量、y分量、旋轉角、是否改變長度、新長度 double vx = px * Math.cos(ang) - py * Math.sin(ang); double vy = px * Math.sin(ang) + py * Math.cos(ang); if (isChLen) { double d = Math.sqrt(vx * vx + vy * vy); vx = vx / d * newLen; vy = vy / d * newLen; mathstr[0] = vx; mathstr[1] = vy; } return mathstr; } }
希望能夠幫助到大家!