2010-08-17 26 views
70

Así que estoy dibujando en este triángulo mapas androide con el siguiente código en mi método draw:Cómo dibujar un triángulo relleno en un lienzo Android?

paint.setARGB(255, 153, 29, 29); 
paint.setStyle(Paint.Style.FILL_AND_STROKE); 
paint.setAntiAlias(true); 

Path path = new Path(); 
path.moveTo(point1_returned.x, point1_returned.y); 
path.lineTo(point2_returned.x, point2_returned.y); 
path.moveTo(point2_returned.x, point2_returned.y); 
path.lineTo(point3_returned.x, point3_returned.y); 
path.moveTo(point3_returned.x, point3_returned.y); 
path.lineTo(point1_returned.x, point1_returned.y); 
path.close(); 

canvas.drawPath(path, paint); 

El pointX_returned cuales son las coordenadas que recibo de los campos. Básicamente son latitudes y longitudes. El resultado es un bonito triángulo, pero el interno está vacío y, por lo tanto, puedo ver el mapa. ¿Hay alguna manera de llenarlo de alguna manera?

+0

Como publiqué en mi respuesta, simplemente no muevasTo() después de cada líneaTo(), eso es todo lo que hay. –

+0

Sé que es una vieja pregunta que ya tiene una respuesta (incorrecta) aceptada, y también publicó su solución final que funciona ... pero no dice por qué funciona, y espero que mi comentario pueda salvar a alguien el momento en que Acabo de gastar en esto :) –

Respuesta

35

es probable que tenga que hacer algo como:

Paint red = new Paint(); 

red.setColor(android.graphics.Color.RED); 
red.setStyle(Paint.Style.FILL); 

Y el uso de este color para su camino, en lugar de su ARGB. Asegúrate de que el último punto de tu camino termina en el primero, también tiene sentido.

Dime si funciona, por favor!

+0

Desafortunadamente esto no ayuda –

+0

@Nicolas ¿Qué usar en lugar de ARGB, si tenemos que personalizar el color con el valor RGB en lugar de usar valores predefinidos? –

66

Ok Lo he hecho. Estoy compartiendo este código en caso de que alguien más lo necesite:

super.draw(canvas, mapView, true); 

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 

paint.setStrokeWidth(2); 
paint.setColor(android.graphics.Color.RED);  
paint.setStyle(Paint.Style.FILL_AND_STROKE); 
paint.setAntiAlias(true); 

Point point1_draw = new Point();   
Point point2_draw = new Point();  
Point point3_draw = new Point(); 

mapView.getProjection().toPixels(point1, point1_draw); 
mapView.getProjection().toPixels(point2, point2_draw); 
mapView.getProjection().toPixels(point3, point3_draw); 

Path path = new Path(); 
path.setFillType(Path.FillType.EVEN_ODD); 
path.moveTo(point1_draw.x,point1_draw.y); 
path.lineTo(point2_draw.x,point2_draw.y); 
path.lineTo(point3_draw.x,point3_draw.y); 
path.lineTo(point1_draw.x,point1_draw.y); 
path.close(); 

canvas.drawPath(path, paint); 

//canvas.drawLine(point1_draw.x,point1_draw.y,point2_draw.x,point2_draw.y, paint); 

return true; 

Gracias por la pista Nicolas!

+4

Estoy bastante seguro de que no necesita la última 'lineTo()'. 'close()' hace eso automáticamente. – Timmmm

+0

@Timmmm He probado, tienes razón, no necesitas la última líneaTo(). Gracias. – banxi1988

+0

Muchas gracias. No sé por qué tuve tantos problemas dibujando un triángulo, pero he pasado los últimos 20 minutos con varios errores en este pequeño problema. –

10

también se puede utilizar Vértice:

private static final int verticesColors[] = { 
    Color.LTGRAY, Color.LTGRAY, Color.LTGRAY, 0xFF000000, 0xFF000000, 0xFF000000 
}; 
float verts[] = { 
    point1.x, point1.y, point2.x, point2.y, point3.x, point3.y 
}; 
canvas.drawVertices(Canvas.VertexMode.TRIANGLES, verts.length, verts, 0, null, 0, verticesColors, 0, null, 0, 0, new Paint()); 
+2

No creo que esta solución maneje formas rellenas. (No puedo probar, no tengo mi IDE por el momento) –

+3

Parece la solución más eficaz, pero desafortunadamente este método no es compatible con las vistas aceleradas por hardware. Puede desactivar la aceleración de hardware, pero luego pierde las ganancias de rendimiento: http://developer.android.com/guide/topics/graphics/hardware-accel.html – SurlyDre

4
private void drawArrows(Point[] point, Canvas canvas, Paint paint) { 

    float [] points = new float[8];    
    points[0] = point[0].x;  
    points[1] = point[0].y;  
    points[2] = point[1].x;  
    points[3] = point[1].y;   
    points[4] = point[2].x;  
    points[5] = point[2].y;    
    points[6] = point[0].x;  
    points[7] = point[0].y; 

    canvas.drawVertices(VertexMode.TRIANGLES, 8, points, 0, null, 0, null, 0, null, 0, 0, paint); 
    Path path = new Path(); 
    path.moveTo(point[0].x , point[0].y); 
    path.lineTo(point[1].x,point[1].y); 
    path.lineTo(point[2].x,point[2].y); 
    canvas.drawPath(path,paint); 

} 
+0

¡Esto funciona! No olvides usar paint.setAntiAlias ​​(true) para obtener un triángulo liso. –

+1

¿Para qué se llama drawVertices? – PsiX

3

Es necesario eliminar path.moveTo después de la primera inicial.

Path path = new Path(); 
path.moveTo(point1_returned.x, point1_returned.y); 
path.lineTo(point2_returned.x, point2_returned.y); 
path.lineTo(point3_returned.x, point3_returned.y); 
path.lineTo(point1_returned.x, point1_returned.y); 
path.close(); 
+0

No tengo 3 puntos pero tengo solo un punto x nad y cómo puedo dibujar un triángulo desde ese punto. – Pranav

3

Usando @ respuesta de Pavel como guía, aquí está un método de ayuda si usted no tiene los puntos, pero ha empezar x, y, altura y anchura. También puede dibujar invertido/invertido, lo cual es útil para mí ya que se usó como extremo de la tabla de barras vertical.

private void drawTriangle(int x, int y, int width, int height, boolean inverted, Paint paint, Canvas canvas){ 

     Point p1 = new Point(x,y); 
     int pointX = x + width/2; 
     int pointY = inverted? y + height : y - height; 

     Point p2 = new Point(pointX,pointY); 
     Point p3 = new Point(x+width,y); 


     Path path = new Path(); 
     path.setFillType(Path.FillType.EVEN_ODD); 
     path.moveTo(p1.x,p1.y); 
     path.lineTo(p2.x,p2.y); 
     path.lineTo(p3.x,p3.y); 
     path.close(); 

     canvas.drawPath(path, paint); 
    } 
4

enter image description here

esta función se muestra cómo crear un triángulo de mapa de bits. Es decir, crea una imagen recortada de forma triangular. Probar el código de abajo o download demo example

public static Bitmap getTriangleBitmap(Bitmap bitmap, int radius) { 
     Bitmap finalBitmap; 
     if (bitmap.getWidth() != radius || bitmap.getHeight() != radius) 
      finalBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, 
        false); 
     else 
      finalBitmap = bitmap; 
     Bitmap output = Bitmap.createBitmap(finalBitmap.getWidth(), 
       finalBitmap.getHeight(), Bitmap.Config.ARGB_8888); 
     Canvas canvas = new Canvas(output); 

     Paint paint = new Paint(); 
     final Rect rect = new Rect(0, 0, finalBitmap.getWidth(), 
       finalBitmap.getHeight()); 

     Point point1_draw = new Point(75, 0); 
     Point point2_draw = new Point(0, 180); 
     Point point3_draw = new Point(180, 180); 

     Path path = new Path(); 
     path.moveTo(point1_draw.x, point1_draw.y); 
     path.lineTo(point2_draw.x, point2_draw.y); 
     path.lineTo(point3_draw.x, point3_draw.y); 
     path.lineTo(point1_draw.x, point1_draw.y); 
     path.close(); 
     canvas.drawARGB(0, 0, 0, 0); 
     paint.setColor(Color.parseColor("#BAB399")); 
     canvas.drawPath(path, paint); 
     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 
     canvas.drawBitmap(finalBitmap, rect, rect, paint); 

     return output; 
    } 

La función anterior devuelve una imagen triangular dibujado sobre tela. Read more

1

¿No moveTo() después de cada lineTo()

En otras palabras, eliminar todos los moveTo() excepto el primero.

En serio, si solo copio y pego el código de OP y elimino las llamadas innecesarias moveTo(), funciona.

No se necesita hacer nada más.


EDIT: Sé que la OP ya publicado su "solución final de trabajo", pero no indicó qué funciona. La razón real fue bastante sorprendente para mí, así que sentí la necesidad de agregar una respuesta.

Cuestiones relacionadas