Come disegnare un triangolo pieno in Android Canvas?


87

Quindi sto disegnando questo triangolo nelle mappe Android usando il codice seguente nel mio metodo di disegno:

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

I pointX_returned sono le coordinate che ottengo dai campi. Sono fondamentalmente latitudini e longitudini. Il risultato è un bel triangolo ma l'insider è vuoto e quindi posso vedere la mappa. C'è un modo per riempirlo in qualche modo?


Come ho postato nella mia risposta, non spostareTo () dopo ogni rigaTo (), è tutto quello che c'è.
oli.G

So che è una vecchia domanda che ha già una risposta (errata) accettata, e hai anche pubblicato la tua soluzione finale che funziona ... ma non stai dicendo perché funziona, e spero che il mio commento possa far risparmiare tempo a qualcuno. ho appena speso per questo :)
oli.G

Risposte:


41

Probabilmente devi fare qualcosa come:

Paint red = new Paint();

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

E usa questo colore per il tuo percorso, invece del tuo ARGB. Assicurati che l'ultimo punto del tuo percorso finisca sul primo, ha anche senso.

Dimmi se funziona per favore!


Purtroppo questo non aiuta
oli.G

@Nicolas Cosa usare al posto di ARGB, se dobbiamo personalizzare il colore con il valore RGB invece di usare valori predefiniti?
pallav bohara

75

Ok l'ho fatto. Condivido questo codice nel caso in cui qualcun altro ne abbia bisogno:

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;

Grazie per il suggerimento Nicolas!


7
Sono abbastanza sicuro che non ti serva l'ultimo lineTo(). close()lo fa automaticamente.
Timmmm,

@Timmmm ho testato, hai ragione, non serve l'ultima riga a (). Grazie.
banxi1988

Grazie mille. Non so perché ho avuto così tanti problemi a disegnare un triangolo, ma ho passato gli ultimi 20 minuti con vari bug su questo piccolo problema.
Achal Dave

1
Ecco il metodo semplice per il copia-incolla (basato sul codice di @ Pavel): gist.github.com/ZirconCode/59cae1e2615279eafb29
ZirconCode

1
se sei passato patha una variabile di istanza, ricordati di chiamare path.reset()dopo canvas.drawPath().
Sira Lam

11

puoi anche usare 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
Non credo che questa soluzione gestisca le forme piene. (non posso testare, al momento non ho il mio IDE)
Nicolas C.

3
Sembra la soluzione più performante, ma sfortunatamente questo metodo non è supportato nelle viste con accelerazione hardware. Puoi disabilitare l'accelerazione hardware, ma poi perdi i suoi guadagni in termini di prestazioni: developer.android.com/guide/topics/graphics/hardware-accel.html
SurlyDre

8

inserisci qui la descrizione dell'immagine

questa funzione mostra come creare un triangolo da bitmap. Cioè, crea un'immagine ritagliata di forma triangolare. Prova il codice qui sotto o scarica un esempio 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;
    }

La funzione sopra restituisce un'immagine triangolare disegnata su tela. Leggi di più


7

Usando la risposta di @ Pavel come guida, ecco un metodo di supporto se non hai i punti ma hai inizio x, ye altezza e larghezza. Può anche disegnare capovolto / capovolto, il che è utile per me poiché è stato utilizzato come fine del grafico a barre verticale.

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

}

Funziona! Non dimenticare di usare paint.setAntiAlias ​​(true) per ottenere un triangolo liscio.
Boldijar Paul

2
A cosa serve il drawVertices?
PsiX

3

È necessario rimuovere path.moveTo dopo la prima iniziale.

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

Non ho 3 punti ma ho solo un punto x nad y come posso disegnare un triangolo da quel punto.
Pranav

2

Non moveTo()dopo ciascunolineTo()

In altre parole, rimuovi tutti moveTo()tranne il primo.

Seriamente, se copio e incollo il codice OP e rimuovo il file non necessario moveTo() chiamate , funziona.

Nient'altro deve essere fatto.


EDIT: So che l'OP ha già pubblicato la sua "soluzione di lavoro finale", ma non ha detto perché funziona. La vera ragione mi sorprendeva, quindi ho sentito il bisogno di aggiungere una risposta.


Avresti dovuto aggiungere un commento per questo. Questa non è una risposta.
Angad Singh
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.