Android Fill Partial Arc
Asked Answered
P

3

7

How could I fill the green portion between two arcs shown below using the paint and canvas methods?

Here is how I draw the two arcs, I also could figure out how to connect them with lines but I don't know how I can fill the inner area.

    // set to stroke black
    paint.setColor(Color.BLACK);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth((float) STROKE_WIDTH);

    // outside arc
    RectF arc_oval_outside = new RectF((float) (getX()), (float) (getY()),
            (float) (getX() + getWidth()), (float) (getY() + getHeight()));
    canvas.drawArc(arc_oval_outside, (float) (0.0), (45.0) (ARC_SWEEP), false, paint);

    // inside arc
    RectF arc_oval_inside = new RectF((float) (getX() + ARC_WIDTH), (float) (getY() + ARC_WIDTH),
            (float) (getX() + getWidth() - ARC_WIDTH), (float) (getY() + getHeight() - ARC_WIDTH));
    canvas.drawArc(arc_oval_inside, (float) (0.0), (float) (ARC_SWEEP), false, paint);
Pout answered 12/7, 2013 at 21:0 Comment(0)
P
9

Here is a simple way to draw filled arc with border:

Point center = new Point(canvas.getWidth()/2, canvas.getHeight()/2);
int inner_radius = 100;
int outer_radius = 150;
int arc_sweep = 90;
int arc_ofset = 30;

RectF outer_rect = new RectF(center.x-outer_radius, center.y-outer_radius, center.x+outer_radius, center.y+outer_radius);
RectF inner_rect = new RectF(center.x-inner_radius, center.y-inner_radius, center.x+inner_radius, center.y+inner_radius);

Path path = new Path();
path.arcTo(outer_rect, arc_ofset, arc_sweep);
path.arcTo(inner_rect, arc_ofset + arc_sweep, -arc_sweep);
path.close();

Paint fill = new Paint();
fill.setColor(Color.GREEN);
canvas.drawPath(path, fill);

Paint border = new Paint();
border.setStyle(Paint.Style.STROKE);
border.setStrokeWidth(2);
canvas.drawPath(path, border);

drawing result

(The Path and Paint allocation is made to be clear not optimal)

Philosophism answered 20/5, 2015 at 20:32 Comment(0)
O
1

I Know it could be a little bit late but I came with this approach from a iOS project, first draw contour and then draw the fillingenter image description here arc

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    float width = (float)getWidth();
    float height = (float)getHeight();
    float radius;

    //Get radius from the bigger size
    if (width > height){
        radius = height/2;
    }else{
        radius = width/2;
    }

    //Create Paint Object
    Paint paint = new Paint();

    paint.setColor(Color.RED);
    paint.setFilterBitmap(true);
    paint.setAntiAlias(true);
    paint.setStrokeWidth(5);
    paint.setStyle(Paint.Style.STROKE);


    //Create Contour Object
    Path path = new Path();

    float center_x, center_y;
    center_x = width/2;
    center_y = height/2;

    //Configure rect for the outer ring
    final RectF oval = new RectF();
    oval.set(center_x - radius + 5,
            center_y - radius + 5,
            center_x + radius - 5,
            center_y + radius - 5);
    //Add outer arc
    path.addArc(oval, 0, 90);

    //Configure rect for the inner ring
    oval.set(center_x - radius + 30,
            center_y - radius + 30,
            center_x + radius - 30,
            center_y + radius - 30);

    //Add inner arc to the path but draw counterclockwise
    path.arcTo(oval, -270, -90);

    //close path
    path.close();

    //Create Paint Object
    Paint fillPaint = new Paint();

    fillPaint.setColor(Color.YELLOW);
    fillPaint.setFilterBitmap(true);
    fillPaint.setAntiAlias(true);
    fillPaint.setStrokeWidth(21);
    fillPaint.setStyle(Paint.Style.STROKE);

    //Create Contour Object
    Path fillPath = new Path();

    //Configure rect for the fill ring
    oval.set(center_x - radius + 17,
            center_y - radius + 17,
            center_x + radius - 17,
            center_y + radius - 17);

    //Add fill arc
    fillPath.addArc(oval, 0, 90);


    //draw fill path
    canvas.drawPath(fillPath,fillPaint);
    //draw outer path
    canvas.drawPath(path, paint);
}

A helpfull link: http://www.programering.com/a/MDO1czNwATE.html where addarc maths are quite well explained

Orientalize answered 20/5, 2015 at 19:20 Comment(0)
R
1

Just posting another option using drawArc only. Basically we first draw the outer filled arc and then we draw the smaller inner arc using PorterDuff.Mode.CLEAR to erase and achieve the asked above.

Bitmap b = Bitmap.createBitmap(1200, 1200, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(b);
int radius = 40;
float startAngle = 45f;   // your start angle
float sweepAngle = 90f;   // your sweep angle
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.rgb(37, 181, 215));
paint.setStyle(Paint.Style.FILL);
// draw outer arc
RectF oval = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
canvas.drawArc(oval, startAngle, sweepAngle, true, paint);
// draw inner arc
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
oval = new RectF((canvas.getWidth() / 2) - radius, (canvas.getHeight() / 2) - radius, (canvas.getWidth() / 2) + radius, (canvas.getHeight() / 2) + radius);
canvas.drawArc(oval, startAngle, sweepAngle, true, paint);

ImageView.setImageBitmap(b);

Hope it helps someone.

enter image description here

Reluct answered 27/10, 2016 at 5:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.