90 votes

Comment dessiner un triangle rempli dans le canevas Android ?

Je dessine donc ce triangle dans Android maps en utilisant le code ci-dessous dans ma méthode de dessin :

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

Les pointsX_renvoyés sont les coordonnées que j'obtiens des champs. Il s'agit essentiellement de latitudes et de longitudes. Le résultat est un joli triangle mais l'intérieur est vide et je peux donc voir la carte. Existe-t-il un moyen de le remplir d'une manière ou d'une autre ?

0 votes

Comme je l'ai indiqué dans ma réponse, il suffit de ne pas utiliser moveTo() après chaque lineTo(), c'est tout.

0 votes

Je sais que c'est une vieille question qui a déjà une réponse (incorrecte) acceptée, et vous avez également posté votre solution finale qui fonctionne... mais vous ne dites pas pourquoi elle fonctionne, et j'espère que mon commentaire pourra épargner à quelqu'un le temps que je viens de passer là-dessus :)

75voto

Pavel Points 1430

Ok, je l'ai fait. Je partage ce code au cas où quelqu'un d'autre en aurait besoin :

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;

Merci pour l'astuce Nicolas !

7 votes

Je suis presque sûr que tu n'as pas besoin de la dernière. lineTo() . close() le fait automatiquement.

0 votes

@Timmmm j'ai testé ,vous avez raison,pas besoin de la dernière ligneTo().merci.

0 votes

Merci beaucoup. Je ne sais pas pourquoi j'avais tant de problèmes pour dessiner un triangle, mais j'ai passé les 20 dernières minutes avec différents bugs sur ce petit problème.

44voto

Nicolas C. Points 534

Vous devez probablement faire quelque chose comme :

Paint red = new Paint();

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

Et utilisez cette couleur pour votre chemin, au lieu de votre ARGB. Assurez-vous que le dernier point de votre chemin se termine sur le premier, cela a aussi du sens.

Dites-moi si ça marche, s'il vous plaît !

0 votes

Malheureusement, cela n'aide pas

0 votes

@Nicolas Que faut-il utiliser à la place de ARGB, si nous devons personnaliser la couleur avec la valeur RGB au lieu d'utiliser des valeurs prédéfinies ?

11voto

GBouerat Points 335

Vous pouvez également utiliser 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 votes

Je ne pense pas que cette solution gère les formes remplies. (je ne peux pas tester, je n'ai pas mon IDE en ce moment)

3 votes

Cela semble être la solution la plus performante, mais malheureusement cette méthode n'est pas prise en charge par les vues accélérées par le matériel. Vous pouvez désactiver l'accélération matérielle, mais vous perdez alors ses gains de performance : developer.Android.com/guide/topics/graphics/hardware-accel.html

8voto

Daniel Nyamasyo Points 981

enter image description here

Cette fonction montre comment créer un triangle à partir d'un bitmap. C'est-à-dire, créer une image recadrée de forme triangulaire. Essayez le code ci-dessous ou télécharger l'exemple de démonstration

 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 fonction ci-dessus renvoie une image triangulaire dessinée sur le canevas. Lire la suite

7voto

scottyab Points 6760

En utilisant la réponse de @Pavel comme guide, voici une méthode d'aide si vous n'avez pas les points mais que vous avez les points de départ x, y, hauteur et largeur. Elle permet également de dessiner à l'envers, ce qui m'a été utile car elle a été utilisée comme fin de graphique à barres vertical.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X