Android 캔버스에 채워진 삼각형을 그리는 방법은 무엇입니까?


88

그래서 내 그리기 메서드에서 아래 코드를 사용하여 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 jul.

나는 그것이 이미 (잘못된) 대답을 받아 들인 오래된 질문이라는 것을 알고 있으며 작동하는 최종 솔루션을 게시했습니다 ...하지만 작동하는 이유를 밝히지 않고 내 의견이 누군가를 절약 할 수 있기를 바랍니다. 그냥 :)에 지출했습니다
— oli.G

답변:


42

다음과 같은 작업이 필요할 수 있습니다.

Paint red = new Paint();

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

그리고 ARGB 대신이 색상을 경로에 사용하십시오. 경로의 마지막 지점이 첫 번째 지점에서 끝나는 지 확인하십시오.

작동하는지 알려주세요!


불행하게도이 도움이되지 않습니다
— oli.G

@Nicolas 미리 정의 된 값을 사용하는 대신 RGB 값으로 색상을 사용자 정의해야하는 경우 ARGB 대신 무엇을 사용해야합니까?
— pallav bohara 2011

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;

힌트 Nicolas 주셔서 감사합니다!


7
나는 당신이 마지막이 필요하지 않다고 확신합니다 lineTo(). close()자동으로 수행됩니다.
— Timmmm

@Timmmm 테스트 해봤는데, 당신 말이 맞아요, 마지막 lineTo ()가 필요 없습니다. 감사합니다.
— banxi1988

정말 고맙습니다. 삼각형을 그리는 데 왜 그렇게 많은 문제가 있었는지 모르겠지만 지난 20 분 동안이 작은 문제에 대한 다양한 버그를 보냈습니다.
— Achal Dave

1
다음은 복사-붙여 넣기를위한 간단한 방법입니다 ( @Pavel
— ZirconCode

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가없는, 테스트 할 수 없습니다)
— 니콜라스 C.에게

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 2014 년

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가 있습니다. 어떻게 그 점에서 삼각형을 그릴 수 있습니까?
— Pranav

2

moveTo()매번 후 하지 마십시오lineTo()

즉, moveTo()첫 번째를 제외한 모든 것을 제거하십시오 .

진지하게, OP의 코드를 복사하여 붙여넣고 불필요한 moveTo()호출을 제거하면 작동합니다.

다른 작업은 수행 할 필요가 없습니다.


편집 : 나는 OP가 이미 그의 "최종 작업 솔루션"을 게시했음을 알고 있지만, 작동 이유 를 밝히지 않았습니다 . 실제 이유는 제게 놀랍게도 답을 추가 할 필요가 있다고 느꼈습니다.


이에 대한 설명을 추가해야합니다. 이것은 대답이 아닙니다.
— 앙 가드 싱
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.