How to draw a filled triangle in android canvas?

105,178

Solution 1

You probably need to do something like :

Paint red = new Paint();

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

And use this color for your path, instead of your ARGB. Make sure the last point of your path ends on the first one, it makes sense also.

Tell me if it works please !

Solution 2

Ok I've done it. I'm sharing this code in case someone else will need it:

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;

Thanks for the hint Nicolas!

Solution 3

you can also use vertice :

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());

Solution 4

Using @Pavel's answer as guide, here's a helper method if you don't have the points but have start x,y and height and width. Also can draw inverted/upside down - which is useful for me as it was used as end of vertical barchart.

 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);
    }

Solution 5

enter image description here

this function shows how to create a triangle from bitmap. That is, create triangular shaped cropped image. Try the code below or 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;
    }

The function above returns an triangular image drawn on canvas. Read more

Share:
105,178
Pavel
Author by

Pavel

Updated on July 15, 2020

Comments

  • Pavel
    Pavel almost 4 years

    So I'm drawing this triangle in android maps using the code below in my draw method:

    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);
    

    The pointX_returned are the coordinates which I'm getting from the fields. They are basically latitudes and longitudes. The result is a nice triangle but the insider is empty and therefore I can see the map. Is there a way to fill it up somehow?

  • Nicolas C.
    Nicolas C. almost 14 years
    I don't think this solution handles filled shapes. (cannot test, I don't have my IDE at the moment)
  • Timmmm
    Timmmm almost 12 years
    I'm pretty sure you don't need the last lineTo(). close() does that automatically.
  • banxi1988
    banxi1988 over 11 years
    @Timmmm I've test ,you are right,no need the last lineTo().Thank you.
  • Achal Dave
    Achal Dave about 11 years
    Thank you so much. I don't know why I had so many issues drawing a triangle, but I've spent the past 20 minutes with various bugs on this tiny problem.
  • SurlyDre
    SurlyDre over 10 years
    This seems like the more performant solution, but unfortunately this method is not supported on hardware-accelerated views. You can disable hardware acceleration, but then you lose its performance gains: developer.android.com/guide/topics/graphics/hardware-accel.h‌​tml
  • steveh
    steveh almost 10 years
    i wonder, would this work with a series of arcTo? not sure how the arcs would be connected, since each arc is specified separately, not as a continuation of the last
  • Boldijar Paul
    Boldijar Paul almost 10 years
    This is working! Don't forget to use paint.setAntiAlias(true) in order to get a smooth triangle.
  • ZirconCode
    ZirconCode over 9 years
    Here's the simple method for copy-pasting (based on @Pavel's code): gist.github.com/ZirconCode/59cae1e2615279eafb29
  • PsiX
    PsiX over 9 years
    What is the drawVertices call for?
  • Shirish Herwade
    Shirish Herwade about 9 years
    can you pleas share your whole code related to triangle drawing. I think you have extended View class, so in that case the extended class and few lines where it is used. It will help me a lot
  • Pranav
    Pranav over 8 years
    I dont have 3 point but have only one point x nad y how can i draw a triangle from that point.
  • oli.G
    oli.G almost 7 years
    I would just like to point out that the reason this works is that he removed the unnecessary (and as it turns out, malicious) moveTo() calls after every lineTo().
  • oli.G
    oli.G almost 7 years
    Unfortunately this does not help
  • pallav bohara
    pallav bohara over 6 years
    @Nicolas What to use instead of ARGB, if we have to customize color with RGB value instead of using pre-defined values?
  • Sira Lam
    Sira Lam about 6 years
    if you changed path to an instance variable, remember to call path.reset() after canvas.drawPath().
  • Angad Singh
    Angad Singh almost 6 years
    You should have added a comment for this. This isn't an answer.