web-dev-qa-db-fra.com

Comment dessiner un triangle rempli dans la toile Android?

Donc, je dessine ce triangle dans Android les cartes 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);

Le pointX_retourné sont les coordonnées que je reçois des champs. Ce sont essentiellement des latitudes et des longitudes. Le résultat est un joli triangle mais l'initié est vide et je peux donc voir la carte. Y a-t-il un moyen de le remplir d'une manière ou d'une autre?

83
Pavel

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 également un sens.

Dis-moi si ça marche s'il te plait!

40
Nicolas C.

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'allusion Nicolas!

74
Pavel

vous pouvez aussi 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());
11
GBouerat

enter image description here

cette fonction montre comment créer un triangle à partir de bitmap. C'est-à-dire, créer une image recadrée de forme triangulaire. Essayez le code ci-dessous ou téléchargez 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 une toile. en savoir plus

6
Daniel Nyamasyo

En utilisant la réponse de @ Pavel comme guide, voici une méthode d'assistance si vous n'avez pas les points mais le début x, y ainsi que la hauteur et la largeur. Aussi peut dessiner inversé/à l'envers - ce qui est utile pour moi car il a été utilisé comme fin du graphique à barres verticales.

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

}
4
Faakhir

Vous devez supprimer path.moveTo après la première initiale.

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
kaftanati

Ne pas moveTo() après chaque lineTo()

En d'autres termes, supprimez tous les moveTo() sauf le premier.

Sérieusement, si je ne fais que copier-coller le code de l'OP et supprimer les appels inutiles moveTo(), cela fonctionne.

Rien d'autre ne doit être fait.


EDIT: Je sais que l’opérateur a déjà publié sa "solution de travail finale", mais il n’a pas indiqué pourquoi cela fonctionne. La raison réelle était assez surprenante pour moi, alors j’ai ressenti le besoin d’ajouter une réponse.

1
oli.G