Android tuvalinde dolu bir üçgen nasıl çizilir?


88

Bu üçgeni, çizim yöntemimde aşağıdaki kodu kullanarak android haritalarında çiziyorum:

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, alanlardan aldığım koordinatlardır. Temelde enlemler ve boylamlardır. Sonuç güzel bir üçgen ama içerideki kişi boş ve dolayısıyla haritayı görebiliyorum. Bir şekilde doldurmanın bir yolu var mı?


Cevabımda yayınladığım gibi, her lineTo () 'dan sonra sadece hareketTo () yapmayın, hepsi bu.
oli.G

Bunun zaten (yanlış) kabul edilmiş bir cevabı olan eski bir soru olduğunu biliyorum ve ayrıca işe yarayan nihai çözümünüzü de gönderdiniz ... ama neden işe yaradığını belirtmiyorsunuz ve umarım yorumum birisine benim zamandan tasarruf ettirebilir. ve bunun için harcadım :)
oli.G

Yanıtlar:


42

Muhtemelen şöyle bir şey yapmanız gerekiyor:

Paint red = new Paint();

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

Ve bu rengi ARGB'niz yerine yolunuz için kullanın. Yolunuzun son noktasının birincisinde bittiğinden emin olun, bu da mantıklı.

Lütfen işe yarayıp yaramadığını söyle!


Maalesef bu yardımcı olmuyor
oli.G

@Nicolas Rengi önceden tanımlanmış değerler kullanmak yerine RGB değeri ile özelleştirmek zorunda kalırsak ARGB yerine ne kullanmalıyız?
pallav bohara

75

Tamam ben yaptım. Başka birinin ihtiyaç duyması durumunda bu kodu paylaşıyorum:

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;

İpucu Nicolas için teşekkürler!


7
Sonuncusuna ihtiyacın olmadığına eminim lineTo(). close()bunu otomatik olarak yapar.
Timmmm

@Timmmm Test ettim, haklısın, son lineTo () 'ya gerek yok. Teşekkür ederim.
banxi1988

Çok teşekkür ederim. Üçgen çizerken neden bu kadar çok sorun yaşadım bilmiyorum ama son 20 dakikayı bu küçük problem üzerinde çeşitli hatalarla geçirdim.
Achal Dave

1
İşte kopyalayıp yapıştırmanın basit yöntemi (@ Pavel'in
ZirconCode

1
Eğer değişirse pathbir örnek değişkene, aramayı unutma path.reset()sonra canvas.drawPath().
Sira Lam

11

ayrıca tepe noktasını da kullanabilirsiniz:

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
Bu çözümün dolu şekilleri ele aldığını sanmıyorum. (test edemiyorum, şu anda IDE'm yok)
Nicolas C.

3
Bu daha performanslı bir çözüm gibi görünüyor, ancak ne yazık ki bu yöntem donanım hızlandırmalı görünümlerde desteklenmiyor. Donanım hızlandırmayı devre dışı bırakabilirsiniz, ancak ardından performans kazanımlarını kaybedersiniz: developer.android.com/guide/topics/graphics/hardware-accel.html
SurlyDre

8

görüntü açıklamasını buraya girin

bu işlev, bitmap'ten nasıl üçgen oluşturulacağını gösterir. Yani üçgen biçimli kırpılmış bir görüntü oluşturun. Aşağıdaki kodu deneyin veya demo örneğini indirin

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

Yukarıdaki işlev, tuval üzerine çizilmiş üçgen bir görüntü döndürür. Daha fazla oku


7

@ Pavel'in cevabını kılavuz olarak kullanarak, puanlarınız yoksa ancak başlangıç ​​x, y ve yükseklik ve genişliğe sahipseniz, işte size yardımcı bir yöntem. Ayrıca ters çevrilmiş / baş aşağı çizilebilir - bu benim için dikey çubuk grafiğin sonu olarak kullanıldığı için yararlıdır.

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

}

Bu çalışıyor! Düzgün bir üçgen elde etmek için paint.setAntiAlias ​​(true) kullanmayı unutmayın.
Boldijar Paul

2
DrawVertices ne için çağrıda bulunuyor?
PsiX

3

İlk baş harften sonra path.moveTo'yu kaldırmanız gerekir.

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 noktam yok ama tek bir noktam var x nad y o noktadan nasıl üçgen çizebilirim.
Pranav

2

Yapma moveTo()her sonrasılineTo()

Diğer bir deyişle, moveTo()ilki dışındaki her şeyi kaldırın .

Cidden, OP'nin kodunu kopyalayıp yapıştırır ve gereksiz olanı kaldırırsam moveTo() çağrıları işe yarıyor.

Başka hiçbir şeyin yapılmasına gerek yok.


DÜZENLEME: OP'nin "son çalışma çözümünü" zaten yayınladığını biliyorum, ancak neden işe yaradığını belirtmedi . Asıl sebep benim için oldukça şaşırtıcıydı, bu yüzden bir cevap ekleme ihtiyacı hissettim.


Bunun için bir yorum eklemeliydin. Bu bir cevap değil.
Angad Singh
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.