How can i draw an arrow using the graphics class?
Im using android graphics class and basically im trying to show a path on a map. So i need to print an arrow head on the canvas. Help me to figure out!
Thank you!
This is one of the methods i have used to draw a line. i want to print an arrow head on the edge of each and every line.
// 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);
}
Hope you'll still find this useful; here's how I draw an arrow head:
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);
}
Given a line with end points at p(x0, y0) and p(x1, y1), the method draws an arrow head with its vertex at p(x1, y1).
The variable
frac : 0 < frac < 1
determines the size of the arrow head.
When I used Igwe Kalu's solution, the size of the arrow head varied according to the distance between the points.
Here is my solution for making the arrow head a constant size, independent of the distance between the points.
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);
}
Same is worked ... But for illustration.. call the below method in onDraw.. so that you could see how it working...
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);
}
You can draw a Bitmap instead and apply a matrix to it.
// using a custom View, you can draw using path primitives:
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);
}
I saw this in your code:
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);
}
don't create new Paint objects within a loop like this, you only need one! And you only need to set properties like stroke width, color, etc, once.
I suggest you create an arrow bitmap
and with the following code from my post here, you can turn the arrow with ease.
I hope this helps.
I try this code it has been working perfectly
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;
}
User contributions licensed under CC BY-SA 3.0