Как нарисовать заполненный треугольник в Android-холсте? - PullRequest
82 голосов
/ 17 августа 2010

Итак, я рисую этот треугольник на картах 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 - это координаты, которые я получаю из полей.Они в основном широты и долготы.В результате получается красивый треугольник, но инсайдер пуст, и поэтому я могу видеть карту.Есть ли способ как-нибудь его заполнить?

Ответы [ 8 ]

73 голосов
/ 17 августа 2010

Хорошо, я сделал это.Я делюсь этим кодом на тот случай, если кому-то еще понадобится:

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;

Спасибо за подсказку, Николас!

40 голосов
/ 17 августа 2010

Вам, вероятно, нужно сделать что-то вроде:

Paint red = new Paint();

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

И используйте этот цвет для вашего пути, вместо вашего ARGB. Убедитесь, что последняя точка вашего пути заканчивается первой, это также имеет смысл.

Скажите, пожалуйста, работает ли он?

11 голосов
/ 18 августа 2010

Вы также можете использовать вершину:

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());
6 голосов
/ 01 января 2017

enter image description here

эта функция показывает, как создать треугольник из растрового изображения.То есть создайте обрезанное изображение треугольной формы.Попробуйте приведенный ниже код или скачайте демонстрационный пример

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

Функция выше возвращает треугольное изображение, нарисованное на холсте. Читать дальше

5 голосов
/ 08 марта 2016

Используя ответ @ 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 голосов
/ 08 мая 2012
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);

}
3 голосов
/ 01 декабря 2014

Вам необходимо удалить 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();
1 голос
/ 14 июля 2017

Не moveTo() после каждого lineTo()

Другими словами, удалите все moveTo(), кроме первого.

Серьезно, если я просто скопирую и вставлю код OP и удалю ненужные вызовы moveTo(), это сработает.

Больше ничего не нужно делать.


РЕДАКТИРОВАТЬ: Я знаю, что ОП уже опубликовал свое "окончательное рабочее решение", но он не указал почему это работает. Фактическая причина была для меня довольно удивительной, поэтому я почувствовал необходимость добавить ответ.

...