如何使用图形类绘制箭头?
我使用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);
}
答案 0 :(得分:7)
希望你仍然觉得这很有用;这是我画箭头的方法:
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
确定箭头的大小。
干杯!
答案 1 :(得分:1)
当我使用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);
}
答案 2 :(得分: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);
}
答案 3 :(得分:0)
您可以改为绘制位图并对其应用矩阵。
答案 4 :(得分: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对象,只需要一个!而且你只需要设置一次属性,如笔画宽度,颜色等。
答案 5 :(得分:0)
我建议您创建arrow bitmap
并使用我的帖子here中的以下代码,您可以轻松地转动箭头。
我希望这会有所帮助。
答案 6 :(得分: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;
}