4

如何使用图形类绘制箭头?

我使用 android 图形类,基本上我试图在地图上显示路径。所以我需要在画布上打印一个箭头。帮我弄清楚!

谢谢!

这是我用来画线的方法之一。我想在每一行的边缘打印一个箭头。

//       ArrayList<Point> ArrayListPoints = new ArrayList<Point>(); // Assign the shortest path here

//       ArrayListPoints.add(new Point(262,100));
//       ArrayListPoints.add(new Point(262,165));
//       ArrayListPoints.add(new Point(346,165));
//       ArrayListPoints.add(new Point(420,165));

       ArrayList<Point> ArrayListPointsFINAL;

    ArrayListPointsFINAL = storePath.ArrayListPoints;

    if(ArrayListPointsFINAL == null){
        System.out.println("ArrayListPointsFINAL is NULL");
    }
    else{

    ArrayList<Float> ArrayList_X = new ArrayList<Float>();
     ArrayList<Float> ArrayList_Y = new ArrayList<Float>();
     //int size = get.ArrayListPoints.size();

    for(int i=0; i<ArrayListPointsFINAL.size(); i++){
        ArrayList_X.add(Float.parseFloat(String.valueOf(ArrayListPointsFINAL.get(i).x)));
        ArrayList_Y.add(Float.parseFloat(String.valueOf(ArrayListPointsFINAL.get(i).y)));
          }   

    for(int i=1; i<ArrayList_X.size(); i++){
        Paint myPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        myPaint.setStrokeWidth(8/*1 /getResources().getDisplayMetrics().density*/);
        myPaint.setColor(0xffff0000);   //color.RED
       // myPaint.setStyle(myPaint);

       canvas.drawLine(ArrayList_X.get(i), ArrayList_Y.get(i), ArrayList_X.get(i-1), ArrayList_Y.get(i-1),myPaint);       

    }
4

7 回答 7

9

希望您仍然会发现这很有用;这是我绘制箭头的方法:

    private void fillArrow(Canvas canvas, float x0, float y0, float x1, float y1) {

    paint.setStyle(Paint.Style.FILL);

    float deltaX = x1 - x0;
    float deltaY = y1 - y0;
    float frac = (float) 0.1;

    float point_x_1 = x0 + (float) ((1 - frac) * deltaX + frac * deltaY);
    float point_y_1 = y0 + (float) ((1 - frac) * deltaY - frac * deltaX);

    float point_x_2 = x1;
    float point_y_2 = y1;

    float point_x_3 = x0 + (float) ((1 - frac) * deltaX - frac * deltaY);
    float point_y_3 = y0 + (float) ((1 - frac) * deltaY + frac * deltaX);

    Path path = new Path();
    path.setFillType(Path.FillType.EVEN_ODD);

    path.moveTo(point_x_1, point_y_1);
    path.lineTo(point_x_2, point_y_2);
    path.lineTo(point_x_3, point_y_3);
    path.lineTo(point_x_1, point_y_1);
    path.lineTo(point_x_1, point_y_1);
    path.close();

    canvas.drawPath(path, paint);
}

给定一条端点位于 p(x0, y0) 和 p(x1, y1) 的线,该方法绘制一个箭头,其顶点位于 p(x1, y1)。

变量

frac : 0 < frac < 1

确定箭头的大小。

于 2012-11-16T23:17:47.623 回答
3

当我使用 Igwe Kalu 的解决方案时,箭头的大小会根据点之间的距离而变化。

这是我使箭头大小恒定的解决方案,与点之间的距离无关。

private void fillArrow(Canvas canvas, float x0, float y0, float x1, float y1) {
    paint.setStyle(Paint.Style.FILL);

    float deltaX = x1 - x0;
    float deltaY = y1 - y0;
    double distance = Math.sqrt((deltaX * deltaX) + (deltaY * deltaY));
    float frac = (float) (1 / (distance / 30));

    float point_x_1 = x0 + (float) ((1 - frac) * deltaX + frac * deltaY);
    float point_y_1 = y0 + (float) ((1 - frac) * deltaY - frac * deltaX);

    float point_x_2 = x1;
    float point_y_2 = y1;

    float point_x_3 = x0 + (float) ((1 - frac) * deltaX - frac * deltaY);
    float point_y_3 = y0 + (float) ((1 - frac) * deltaY + frac * deltaX);

    Path path = new Path();
    path.setFillType(Path.FillType.EVEN_ODD);

    path.moveTo(point_x_1, point_y_1);
    path.lineTo(point_x_2, point_y_2);
    path.lineTo(point_x_3, point_y_3);
    path.lineTo(point_x_1, point_y_1);
    path.lineTo(point_x_1, point_y_1);
    path.close();

    canvas.drawPath(path, paint);
}
于 2015-04-01T05:20:08.743 回答
1

同样的工作......但为了说明......在onDraw中调用下面的方法......这样你就可以看到它是如何工作的......

private void fillArrow(Canvas canvas, float x0, float y0, float x1, float y1) {
    Paint paint = new Paint();
    paint.setColor(Color.BLACK);
    paint.setStyle(Paint.Style.FILL);

    float deltaX = x1 - x0;
    float deltaY = y1 - y0;
    float distance = (float) Math.sqrt((deltaX * deltaX)
            + (deltaY * deltaY));
    float frac = (float) (1 / (distance / 15));

    float point_x_1 = x0 + (float) ((1 - frac) * deltaX + frac * deltaY);
    float point_y_1 = y0 + (float) ((1 - frac) * deltaY - frac * deltaX);

    float point_x_2 = x1;
    float point_y_2 = y1;

    float point_x_3 = x0 + (float) ((1 - frac) * deltaX - frac * deltaY);
    float point_y_3 = y0 + (float) ((1 - frac) * deltaY + frac * deltaX);

    float midOfArrow_x = (point_x_1 + point_x_3) / 2;
    float midOfArrow_y = (point_y_1 + point_y_3) / 2;

    Path path = new Path();
    path.setFillType(Path.FillType.EVEN_ODD);

    path.moveTo(point_x_1, point_y_1);
    path.lineTo(point_x_2, point_y_2);
    path.lineTo(point_x_3, point_y_3);
    path.lineTo(point_x_1, point_y_1);
    // path.lineTo(point_x_1, point_y_1);
    path.close();

    path.transform(mMatrix);
    canvas.drawPath(path, paint);

    paint = new Paint();
    paint.setColor(Color.RED);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(9);
    path = new Path();

    path.moveTo(x0, y0);
    path.lineTo(midOfArrow_x, midOfArrow_y);
    path.transform(mMatrix);
    canvas.drawPath(path, paint);

    paint = new Paint();
    paint.setColor(Color.WHITE);
    paint.setStyle(Paint.Style.STROKE);

    canvas.drawCircle(x0, y0, 10, paint);

    canvas.drawCircle(midOfArrow_x, midOfArrow_y, 10, paint);

    paint.setColor(Color.RED);
    canvas.drawCircle(point_x_1, point_y_1, 10, paint);

    paint.setColor(Color.GREEN);
    canvas.drawCircle(point_x_2, point_y_2, 10, paint);

    paint.setColor(Color.BLUE);
    canvas.drawCircle(point_x_3, point_y_3, 10, paint);

}
于 2015-08-07T09:15:26.630 回答
0

您可以改为绘制位图并对其应用矩阵。

于 2012-08-15T19:16:25.920 回答
0

// 使用自定义视图,您可以使用路径图元进行绘制:

  private Paint mPaint;                 // paint object
  private Path mPathGrid;                   // path object

    @Override
    protected void onDraw(Canvas canvas) 
    {

        if (mPaint == null)
         mPaint = new Paint();                   // cache your paint object
            if (mPathGrid == null)
     mPathGrid = new Path();                 // and your path

        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);

        // a white arrow pointing down
        mPaint.setColor(Color.WHITE);
        mPaint.setStrokeWidth(2);
        mPathGrid.reset();
        mPathGrid.moveTo(100.0, 100.0);         // 100,100 is starting point of path

                // "draw" the outline of your arrow... play "connect the dots"...
        mPathGrid.lineTo(100.0 + 10.0f, 100.0);
        mPathGrid.lineTo(100.0 + 10.0f, 100.0 - 5.0f);
        mPathGrid.lineTo(100.0 + 13.0f, 100.0 - 5.0f);
        mPathGrid.lineTo(100.0 + 10.0f, 100.0 - 8.0f);
        mPathGrid.lineTo(100.0 + 7.0f, 100.0 - 5.0f);
        mPathGrid.lineTo(100.0 + 10.0f, 100.0 - 5.0f);
        canvas.drawPath(mPathGrid, mPaint);

        super.onDraw(canvas);
    }

我在您的代码中看到了这一点:

for(int i=1; i<ArrayList_X.size(); i++)
{ 
        Paint myPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
        myPaint.setStrokeWidth(8/*1 /getResources().getDisplayMetrics().density*/); 
        myPaint.setColor(0xffff0000);   //color.RED 
       // myPaint.setStyle(myPaint); 

       canvas.drawLine(ArrayList_X.get(i), ArrayList_Y.get(i), ArrayList_X.get(i-1), ArrayList_Y.get(i-1),myPaint);        

    } 

不要在这样的循环中创建新的 Paint 对象,你只需要一个!您只需要设置笔画宽度、颜色等属性一次。

于 2012-08-15T19:23:54.753 回答
0

我建议您使用我在此处arrow bitmap的帖子中的以下代码创建一个和,您可以轻松地转动箭头。

我希望这有帮助。

于 2012-08-15T19:40:55.820 回答
0

我尝试了这段代码,它一直运行良好

Here is my code...

switch (event.getAction())
{
   case MotionEvent.ACTION_DOWN:
        mPath.reset();
    mPath.moveTo(x, y);
        mX = x;
        mY = y;
        startPoint = new PointF(event.getX(), event.getY());
        endPoint = new PointF();
        invalidate();

     //   isDrawing = true;
        break;
    case MotionEvent.ACTION_MOVE:
            float dx = Math.abs(x - mX);
        System.out.println("action move");
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
        {
        //  currentDrawingPath.path.quadTo(mX,mY,(x + mX)/2, (y + mY)/2);
        }
        mX = x;
        mY = y;
          endPoint.x = event.getX();
            endPoint.y = event.getY();
          isDrawing = true;

          invalidate();
        break;
    case MotionEvent.ACTION_UP:
           mPath.lineTo(mX, mY);
           float deltaX =   endPoint.x-startPoint.x;
           float deltaY =   endPoint.y-startPoint.y;
           float frac = (float) 0.1;

       float point_x_1 = startPoint.x + (float) ((1 - frac) * deltaX + frac * deltaY);
       float point_y_1 = startPoint.y + (float) ((1 - frac) * deltaY - frac * deltaX);

           float point_x_2 = endPoint.x;
           float point_y_2 = endPoint.y;

       float point_x_3 = startPoint.x + (float) ((1 - frac) * deltaX - frac * deltaY);
       float point_y_3 = startPoint.y + (float) ((1 - frac) * deltaY + frac * deltaX);



           mPath.moveTo(point_x_1, point_y_1);
           mPath.lineTo(point_x_2, point_y_2);
           mPath.lineTo(point_x_3, point_y_3);
           mPath.lineTo(point_x_1, point_y_1);
           mPath.lineTo(point_x_1, point_y_1);
            mCanvas.drawPath(mPath, ppaint);
            endPoint.x = event.getX();
            endPoint.y = event.getY();
            isDrawing = false;
            invalidate();
        break;
    default:
        break;
}       
于 2012-11-30T08:59:56.040 回答