Как нарисовать заполненный многоугольник? - PullRequest
50 голосов
/ 12 января 2010

Как нарисовать заполненный многоугольник в Android?

Ответы [ 7 ]

105 голосов
/ 04 июня 2012

Android не имеет удобного действия drawPolygon(x_array, y_array, numberofpoints), как Java. Вы должны пройти через создание объекта Path точка за точкой. Например, чтобы создать заполненную форму трапеции для трехмерной стены подземелья, вы можете поместить все свои точки в массивы x и y, а затем кодировать следующим образом:

Paint wallpaint = new Paint();
wallpaint.setColor(Color.GRAY);
wallpaint.setStyle(Style.FILL);

Path wallpath = new Path();
wallpath.reset(); // only needed when reusing this path for a new build
wallpath.moveTo(x[0], y[0]); // used for first point
wallpath.lineTo(x[1], y[1]);
wallpath.lineTo(x[2], y[2]);
wallpath.lineTo(x[3], y[3]);
wallpath.lineTo(x[0], y[0]); // there is a setLastPoint action but i found it not to work as expected

canvas.drawPath(wallpath, wallpaint);

Чтобы добавить постоянный линейный градиент для некоторой глубины, вы можете написать код следующим образом. Примечание y [0] используется дважды, чтобы сохранить горизонтальный градиент:

 wallPaint.reset(); // precaution when resusing Paint object, here shader replaces solid GRAY anyway
 wallPaint.setShader(new LinearGradient(x[0], y[0], x[1], y[0], Color.GRAY, Color.DKGRAY,TileMode.CLAMP)); 

 canvas.drawPath(wallpath, wallpaint);

См. Документацию Paint , Path и Canvas для получения дополнительных параметров, таких как градиенты, определенные в массиве, добавление дуг и наложение растрового изображения на полигоне.

41 голосов
/ 12 января 2010

Вам нужно установить объект рисования на FILL

Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);

Тогда вы можете нарисовать все, что захотите, и оно будет заполнено.

canvas.drawCircle(20, 20, 15, paint);
canvas.drawRectangle(60, 20, 15, paint);

и т.д.

Для более сложных фигур вам нужно использовать объект PATH .

12 голосов
/ 01 января 2013

Мне нравится делать это в три этапа ...

Шаг 1. Создайте заостренный класс; -)

/**
 * Simple point
 */
private class Point {

    public float x = 0;
    public float y = 0;

    public Point(float x, float y) {
        this.x = x;
        this.y = y;
    }
}

Шаг 2. Добавить метод / функцию для рисования

/**
 * Draw polygon
 *
 * @param canvas The canvas to draw on
 * @param color  Integer representing a fill color (see http://developer.android.com/reference/android/graphics/Color.html)
 * @param points Polygon corner points
 */
private void drawPoly(Canvas canvas, int color, Point[] points) {
    // line at minimum...
    if (points.length < 2) {
        return;
    }

    // paint
    Paint polyPaint = new Paint();
    polyPaint.setColor(color);
    polyPaint.setStyle(Style.FILL);

    // path
    Path polyPath = new Path();
    polyPath.moveTo(points[0].x, points[0].y);
    int i, len;
    len = points.length;
    for (i = 0; i < len; i++) {
        polyPath.lineTo(points[i].x, points[i].y);
    }
    polyPath.lineTo(points[0].x, points[0].y);

    // draw
    canvas.drawPath(polyPath, polyPaint);
}

Шаг 3. Розыгрыш

    drawPoly(canvas, 0xFF5555ee,
            new Point[]{
                new Point(10, 10),
                new Point(15, 10),
                new Point(15, 20)
            });

Да, вы могли бы сделать это более эффективно, но, вероятно, не намного более читабельно: -).

4 голосов
/ 22 апреля 2016

Рисование многоугольника с x сторонами и произвольным радиусом:

private void drawPolygon(Canvas mCanvas, float x, float y, float radius, float sides, float startAngle, boolean anticlockwise, Paint paint) {

    if (sides < 3) { return; }

    float a = ((float) Math.PI *2) / sides * (anticlockwise ? -1 : 1);
    mCanvas.save();
    mCanvas.translate(x, y);
    mCanvas.rotate(startAngle);
    Path path = new Path();
    path.moveTo(radius, 0);
    for(int i = 1; i < sides; i++) {
        path.lineTo(radius * (float) Math.cos(a * i), radius * (float) Math.sin(a * i));
    }
    path.close();
    mCanvas.drawPath(path, paint);
    mCanvas.restore();
}
2 голосов
/ 25 июня 2012

Кстати - я обнаружил, что как только вы начнете создавать свой путь, любые команды moveTo в пределах пути будут означать, что фигура остается незаполненной.

Имеет смысл подумать, что Android / Java оставит фигуру незаполненной, поскольку moveTo будет представлять разрыв в многоугольнике.

Однако я видел несколько подобных уроков Как нарисовать заполненный треугольник на холсте Android?

, которые имеют moveTo's после каждой строки To. Даже при том, что это может привести к непрерывному многоугольнику, Android предполагает, что moveTo представляет разрыв в многоугольнике.

1 голос
/ 17 апреля 2015

Старый вопрос, но уловка для тех, кто находит это. Если вы включили шрифт с нужным полигоном в качестве символа, вы можете использовать функцию drawText для рисования полигона.

Недостатком является то, что вы должны заранее знать, какие фигуры вам понадобятся. Плюс в том, что если вы заранее знаете, вы можете включить хорошую библиотеку форм. Этот код предполагает, что у вас есть шрифт с именем shape в папке assets / fonts вашего проекта.

            TypeFace shapesTypeFace = Typeface.createFromAsset(getAssets(), "fonts/shapes.ttf");
            Paint stopSignPaint = new Paint();
            stopSignPaint.setColor(Color.RED);
            //set anti-aliasing so it looks nice
            stopSignPaint.setAntiAlias(true);
            stopSignPaint.setTextSize(200);
            stopSignPaint.setTypeface(shapesTypeFace);

            //will show up as a box or question mark since 
            //the current display font doesn't have this glyph. 
            //open the shapes font in a tool like Character Map 
            //to copy and paste the glyph into your IDE
            //saving it as a variable makes it much easier to work with
            String hexagonGlyph = ""
            String triangleGlyph = ""


            ....whatever code you got...


            //arguments: text, x coordinate, y coordinate, paint
             canvas.drawText(hexagonGlyph, 200, 100, stopSignPaint);

            //make it into a go sign
            stopSignPaint.setColor(Color.Green);
             canvas.drawText(hexagonGlyph, 200, 100, stopSignPaint);


            //make a tiny one
            stopSignPaint.setTextSize(20);
            stopSignPaint.setColor(Color.RED);
             canvas.drawText(hexagonGlyph, 200, 100, stopSignPaint);


             //make a triangle
             canvas.drawText(triangleGlyph, 200, 100, stopSignPaint);
0 голосов
/ 01 января 2017

Попробуйте, или посмотрите полную демонстрацию

    Paint paint = new Paint();
    paint.setColor(Color.parseColor("#BAB399"));
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...