如何在Android canvas中绘制实心三角形?


87

因此,我在我的draw方法中使用以下代码在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);

pointX_returned是我从字段中获取的坐标。它们基本上是经度和纬度。结果是一个漂亮的三角形,但内部人员为空,因此我可以看到地图。有办法以某种方式填充它吗?


正如我在答案中发布的那样,只是不要在每个lineTo()之后移动moveTo(),仅此而已。
oli.G

我知道这是一个古老的问题,已经有一个(不正确的)可接受的答案,并且您还发布了最终的解决方案,但是仍然有效……但是,您并没有说明这样做的原因,希望我的评论可以为我节省时间。 ve刚刚花了这个时间:)
oli.G

Answers:


41

您可能需要执行以下操作:

Paint red = new Paint();

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

并将此颜色用于您的路径,而不是ARGB。确保路径的最后一点在第一个点结束,这也很有意义。

告诉我是否可行!


不幸的是,这无济于事
oli.G

@Nicolas如果必须使用RGB值而不是使用预定义的值自定义颜色,该使用什么代替ARGB?
pallav bohara

75

好吧,我做到了。我共享此代码,以防其他人需要它:

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;

感谢您的提示尼古拉斯!


7
我敢肯定你不需要最后一个lineTo()close()自动执行。
Timmmm 2012年

@Timmmm我已经测试过了,您是对的,不需要最后一行To()。谢谢。
banxi1988

非常感谢。我不知道为什么在绘制三角形时会有如此多的问题,但是在过去的20分钟里,我花了很多时间解决这个小问题。
Achal Dave

1
这是复制粘贴的简单方法(基于@Pavel
ZirconCode 2014年

1
如果更改path为实例变量,请记住在path.reset()之后调用canvas.drawPath()
Sira Lam

11

您也可以使用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());

2
我认为此解决方案无法处理填充形状。(无法测试,目前我没有IDE)
Nicolas C. 2010年

3
这似乎是性能更高的解决方案,但是不幸的是,硬件加速视图不支持此方法。您可以禁用硬件加速,但随后会失去其性能提升:developer.android.com/guide/topics/graphics/hardware-accel.html
SurlyDre 2013年

8

在此处输入图片说明

此功能显示如何从位图创建三角形。即,创建三角形的裁剪图像。尝试下面的代码或下载演示示例

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

上面的函数返回在画布上绘制的三角形图像。阅读更多


7

使用@Pavel的答案作为指导,如果您没有这些点,但以x,y和高度和宽度开头,则可以使用以下帮助方法。还可以绘制倒置/倒置的图形,这对我很有用,因为它被用作垂直条形图的末端。

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

}

工作正常!不要忘记使用paint.setAntiAlias(true)以获得平滑的三角形。
Boldijar Paul

2
drawVertices要求什么?
PsiX 2014年

3

您需要在首次初始设置后删除path.moveTo。

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

我没有3点,但是只有1点x nad y如何从该点绘制三角形。
普拉纳夫2015年

2

不要moveTo()每次lineTo()

换句话说,移除所有 moveTo()除第一个以外的。

认真的说,如果我只是复制粘贴OP的代码并删除不必要的代码 moveTo()调用,那么它将起作用。

不需要做其他任何事情。


编辑:我知道OP已经发布了他的“最终工作解决方案”,但是他没有说明为什么起作用。实际原因令我感到惊讶,因此我觉得有必要添加答案。


您应该为此添加一条评论。这不是答案。
Angad Singh,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.