Làm thế nào để vẽ một hình tam giác đầy trong canvas Android?


87

Vì vậy, tôi đang vẽ hình tam giác này trong bản đồ Android bằng cách sử dụng mã bên dưới trong phương pháp vẽ của tôi:

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 là tọa độ mà tôi nhận được từ các trường. Về cơ bản chúng là vĩ độ và kinh độ. Kết quả là một hình tam giác đẹp nhưng bên trong trống rỗng và do đó tôi có thể nhìn thấy bản đồ. Có cách nào để lấp đầy nó bằng cách nào đó không?


Như tôi đã đăng trong câu trả lời của mình, chỉ cần không moveTo () sau mỗi dòngTo (), đó là tất cả.
oli.G

Tôi biết đó là một câu hỏi cũ đã có một câu trả lời (không chính xác) được chấp nhận, và bạn cũng đã đăng giải pháp cuối cùng của mình hiệu quả ... nhưng bạn không nói rõ tại sao nó hoạt động và tôi hy vọng nhận xét của tôi có thể giúp ai đó tiết kiệm thời gian cho tôi ' đã chi tiêu cho việc này :)
oli.G

Câu trả lời:


41

Bạn có thể cần phải làm điều gì đó như:

Paint red = new Paint();

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

Và sử dụng màu này cho đường dẫn của bạn, thay vì ARGB của bạn. Đảm bảo rằng điểm cuối cùng của con đường của bạn kết thúc ở điểm đầu tiên, nó cũng có ý nghĩa.

Xin vui lòng cho tôi biết nếu nó hoạt động!


Đáng tiếc là điều này không giúp
oli.G

@Nicolas Sử dụng gì thay vì ARGB, nếu chúng ta phải tùy chỉnh màu với giá trị RGB thay vì sử dụng các giá trị được xác định trước?
pallav bohara

75

Ok, tôi đã làm xong. Tôi đang chia sẻ mã này trong trường hợp người khác cần nó:

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;

Cảm ơn vì gợi ý Nicolas!


7
Tôi khá chắc rằng bạn không cần cái cuối cùng lineTo(). close()làm điều đó tự động.
Timmmm

@Timmmm Tôi đã kiểm tra, bạn nói đúng, không cần dòng cuối cùngTo (). Cảm ơn bạn.
banxi1988

Cảm ơn bạn rất nhiều. Tôi không biết tại sao tôi gặp quá nhiều vấn đề khi vẽ một hình tam giác, nhưng tôi đã dành 20 phút qua với nhiều lỗi khác nhau cho vấn đề nhỏ này.
Achal Dave

1
Đây là phương pháp đơn giản để sao chép dán (dựa trên @ đang Pavel của): gist.github.com/ZirconCode/59cae1e2615279eafb29
ZirconCode

1
nếu bạn đã thay đổi paththành một biến thể hiện, hãy nhớ gọi path.reset()sau canvas.drawPath().
Sira Lam

11

bạn cũng có thể sử dụng 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
Tôi không nghĩ rằng giải pháp này xử lý các hình dạng đầy. (không thể kiểm tra, tôi không có IDE của mình vào lúc này)
Nicolas C.

3
Đây có vẻ là giải pháp hiệu quả hơn, nhưng tiếc là phương pháp này không được hỗ trợ trên các chế độ xem tăng tốc phần cứng. Bạn có thể tắt tăng tốc phần cứng, nhưng sau đó bạn sẽ mất hiệu suất tăng: developer.android.com/guide/topics/graphics/hardware-accel.html
SurlyDre

8

nhập mô tả hình ảnh ở đây

hàm này cho biết cách tạo một hình tam giác từ bitmap. Đó là, tạo ảnh cắt hình tam giác. Hãy thử mã bên dưới hoặc tải xuống ví dụ demo

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

Hàm trên trả về một hình tam giác được vẽ trên canvas. Đọc thêm


7

Sử dụng câu trả lời của @ Pavel làm hướng dẫn, đây là một phương pháp trợ giúp nếu bạn không có các điểm nhưng có bắt đầu x, y và chiều cao và chiều rộng. Cũng có thể vẽ ngược / lộn ngược - điều này rất hữu ích cho tôi vì nó được sử dụng như phần cuối của biểu đồ dọc.

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

}

Điều này đang hoạt động! Đừng quên sử dụng paint.setAntiAlias ​​(true) để có được một hình tam giác mịn.
Boldijar Paul

2
Lệnh drawVertices là gì?
PsiX

3

Bạn cần xóa path.moveTo sau lần đầu tiên.

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

Tôi không có 3 điểm nhưng chỉ có một điểm x nad y làm thế nào tôi có thể vẽ một tam giác từ điểm đó.
Pranav

2

Đừng moveTo()sau mỗilineTo()

Nói cách khác, loại bỏ tất cả moveTo()ngoại trừ cái đầu tiên.

Nghiêm túc mà nói, nếu tôi chỉ sao chép-dán mã của OP và xóa các moveTo()cuộc gọi không cần thiết , nó sẽ hoạt động.

Không cần làm gì khác.


CHỈNH SỬA: Tôi biết OP đã đăng "giải pháp làm việc cuối cùng" của anh ấy, nhưng anh ấy không nói tại sao nó hoạt động. Lý do thực sự khá bất ngờ đối với tôi, vì vậy tôi cảm thấy cần phải thêm một câu trả lời.


Bạn nên thêm một bình luận cho điều này. Đây không phải là một câu trả lời.
Angad Singh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.