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.