studio drawpath drawarc clase java android draw shape

java - drawpath - ¿Cómo dibujo una punta de flecha(en Android)?



drawpath android (6)

Soy bastante nuevo en Android y he estado jugando con Canvas. Estoy intentando dibujar una flecha, pero solo estoy teniendo suerte con el dibujo del eje, ninguna de las puntas de flecha está funcionando.

Busqué un poco y encontré un ejemplo de Java, pero Android no tiene GeneralPath o AffineTransform .

En este momento mi código se parece a lo siguiente (la punta de flecha no se parece en nada a una punta de flecha):

public class DrawableView extends View { Context mContext; private int centerX; private int centerY; private int radius; private double arrLength; private double arrHeading; private int margin = 10; public DrawableView(Context context) { super(context); mContext = context; } @Override protected void onDraw(Canvas canvas) { //Paint Background Paint background = new Paint(); background.setColor(getResources().getColor(R.color.background); canvas.drawRect(0, 0, getWidth(), getHeight(), background); //Set vars for Arrow Paint Paint paint = new Paint(); paint.setColor(getResources().getColor(R.color.arrowColor); centerX = getWidth() / 2; centerY = getHeight() / 2; arrLength = radius - 10; if(centerX < centerY) radius = centerX - margin; else radius = centerY - margin; //Draw Shaft int[] xy = findArrowPos(arrLength, arrHeading); canvas.drawLine(centerX, centerY, xy[0], xy[1], paint); //Draw ArrowHead //This is where I''m confused } private int[] findArrowPos(double length, double angle) { int[] points = new int[2]; double theta = Math.toRadians(angle); points[0] = centerX + (int) (length * Math.cos(theta)); points[1] = centerY + (int) (length * Math.sin(theta)); return points; } }

He echado un vistazo a los siguientes hilos de orientación:
* http://www.java-forums.org/awt-swing/6241-how-u-rotate-arrow-mark-line-moves-accordingly.html
* ¿Cómo dibujar una línea de flecha dirigida en Java?


¿Qué hay de usar "Path myPath = new Path ();" donde darías las posiciones x e y para crear un triángulo usando líneas y rellenándolo. Puedes leer sobre esto, aquí hay un ejemplo que tomé de algún lugar.

// create and draw triangles // use a Path object to store the 3 line segments // use .offset to draw in many locations // note: this triangle is not centered at 0,0 paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); paint.setColor(Color.RED); Path path = new Path(); path.moveTo(0, -10); path.lineTo(5, 0); path.lineTo(-5, 0); path.close(); path.offset(10, 40); canvas.drawPath(path, paint); path.offset(50, 100); canvas.drawPath(path, paint); // offset is cumlative // next draw displaces 50,100 from previous path.offset(50, 100); canvas.drawPath(path, paint);


He estado teniendo el mismo problema, necesito una flecha para apuntar en cierta dirección. Después de jugar con los algoritmos de dibujo, decidí que el método más simple es usar un mapa de bits y simplemente usar una matriz para rotarla, por ejemplo

ImageView image = (ImageView) findViewById(R.id.bitmap_image); Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.test); Matrix mat = new Matrix(); mat.postRotate(90); Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(), bMap.getHeight(), mat, true); image.setImageBitmap(bMapRotate);

entonces tu mapa de bits puede ser cualquier flecha que te guste.


Intento este código que ha estado funcionando perfectamente.

enter code here 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(); 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; }


Mi código de dibujo de flecha, tal vez pueda ser de alguna utilidad para alguien:

/** * Draw an arrow * change internal radius and angle to change appearance * - angle : angle in degrees of the arrows legs * - radius : length of the arrows legs * @author Steven Roelants 2017 * * @param paint * @param canvas * @param from_x * @param from_y * @param to_x * @param to_y */ private void drawArrow(Paint paint, Canvas canvas, float from_x, float from_y, float to_x, float to_y) { float angle,anglerad, radius, lineangle; //values to change for other appearance *CHANGE THESE FOR OTHER SIZE ARROWHEADS* radius=10; angle=15; //some angle calculations anglerad= (float) (PI*angle/180.0f); lineangle= (float) (atan2(to_y-from_y,to_x-from_x)); //tha line canvas.drawLine(from_x,from_y,to_x,to_y,paint); //tha triangle Path path = new Path(); path.setFillType(Path.FillType.EVEN_ODD); path.moveTo(to_x, to_y); path.lineTo((float)(to_x-radius*cos(lineangle - (anglerad / 2.0))), (float)(to_y-radius*sin(lineangle - (anglerad / 2.0)))); path.lineTo((float)(to_x-radius*cos(lineangle + (anglerad / 2.0))), (float)(to_y-radius*sin(lineangle + (anglerad / 2.0)))); path.close(); canvas.drawPath(path, paint); }


Si está buscando la solución para dibujar miles de flechas en un segundo, con líneas de cabeza de longitud fija, pruebe esta función (solo dibuja cabezas de flecha):

private void fillArrow(Paint paint, Canvas canvas, float x0, float y0, float x1, float y1) { paint.setStyle(Paint.Style.STROKE); int arrowHeadLenght = 10; int arrowHeadAngle = 45; float[] linePts = new float[] {x1 - arrowHeadLenght, y1, x1, y1}; float[] linePts2 = new float[] {x1, y1, x1, y1 + arrowHeadLenght}; Matrix rotateMat = new Matrix(); //get the center of the line float centerX = x1; float centerY = y1; //set the angle double angle = Math.atan2(y1 - y0, x1 - x0) * 180 / Math.PI + arrowHeadAngle; //rotate the matrix around the center rotateMat.setRotate((float) angle, centerX, centerY); rotateMat.mapPoints(linePts); rotateMat.mapPoints(linePts2); canvas.drawLine(linePts [0], linePts [1], linePts [2], linePts [3], paint); canvas.drawLine(linePts2 [0], linePts2 [1], linePts2 [2], linePts2 [3], paint); }

Basado en https://gamedev.stackexchange.com/questions/44456/drawing-lines-on-android-with-matrix


Utilice una Path como se muestra a continuación y ajuste las coordenadas en consecuencia:

// Construct a wedge-shaped path Path mPath = new Path(); mPath.moveTo(0, -50); mPath.lineTo(-20, 60); mPath.lineTo(0, 50); mPath.lineTo(20, 60); mPath.close();