Как нарисовать заполненный многоугольник? - программирование
Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

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

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

и др.

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

Ответ 2

Android не имеет удобного действия drawPolygon(x_array, y_array, numberofpoints), такого как Java. Вы должны пройти через создание объекта Path по точкам. Например, чтобы создать заполненную форму трапеции для 3D-стены подземелья, вы можете поместить все свои точки в массивы 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 для получения дополнительных параметров, таких как градиенты, определяемые массивом, добавление дуг и установка растрового изображения над вашим полигоном.

Ответ 3

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

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

/**
 * 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

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

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

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

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

Ответ 5

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

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

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

Ответ 6

Нарисуйте многоугольник со сторонами 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();
}