Best way to fill a circle partially

Hi guys,

I have a use case where I need to paint a partially filled circle in the device context. The SDK provides 2 methods to draw a filled circle:

dc.fillCircle
dc.fillRoundedRectangle (by providing the radius as half of the rectangles height/width)

I tried the second one hoping that something like this would work:

dc.drawCircle(dc.getWidth()/2, dc.getHeight()/2, 10);
dc.fillRoundedRectangle(dc.getWidth()/2, dc.getHeight()/2, 10, 20, 10);

I expected the circle to be filled till half of the width. The problem is that, as the rectangle has only a width of 10 the radius of 10 is invalid and reduced to 5 automatically, which is not giving me a clear circle.

One way I have in mind would be to use the drawPoint method and calculate all points that I would need to fill inside a circle drawn by drawCircle, but this seems to be a difficult "workaround". Anybody has an idea about a better way to achieve the goal via APIs?

Thanks!

Bye
  • Former Member
    Former Member over 7 years ago
    I can't really picture exactly what you are attempting from the code you posted, but to draw a partial filled circle (like a pac-man shape?) there are few options. Assuming blanking the whole circle area is possible, you can just draw the full circle, and then draw a wedge shaped piece over it with fillPolygon() to cover up the area you want to remove with the background color.

    Another option would be to use draw arc with a penWidth the same size as your radius, but I am not sure if this will or will not fill in exactly the way it should. I could see this method having issues at the center of the circle.
  • I can't really picture exactly what you are attempting from the code you posted, but to draw a partial filled circle (like a pac-man shape?) there are few options. Assuming blanking the whole circle area is possible, you can just draw the full circle, and then draw a wedge shaped piece over it with fillPolygon() to cover up the area you want to remove with the background color.

    Another option would be to use draw arc with a penWidth the same size as your radius, but I am not sure if this will or will not fill in exactly the way it should. I could see this method having issues at the center of the circle.


    Thanks for your suggestions, but I finally ended up in calculating the points to fill and drawing them via drawPoint:

    var fDotRadius = iCurrentDotSize.toFloat()/2;

    for (var iOuterCounter = 0; iOuterCounter < iWidth; iOuterCounter++) {
    for (var iInnerCounter = 0; iInnerCounter < iCurrentDotSize; iInnerCounter++) {
    var fRadius = Math.sqrt(
    Math.pow(iOuterCounter - fDotRadius, 2)
    + Math.pow(iInnerCounter - fDotRadius, 2)
    );

    if (fRadius <= fDotRadius) {
    dc.drawPoint(iX + iOuterCounter, iY + iInnerCounter);
    }
    }
    }


    This works great.

    Bye
  • It looks like you are trying to draw a filled circle (disc) inside a circle. Is there some reason you can't just use the provided API?

    dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_BLACK);
    dc.clear();

    var cx = dc.getWidth() / 2;
    var cy = dc.getHeight() / 2;

    // draw the filled area
    dc.setColor(Gfx.COLOR_YELLOW, Gfx.COLOR_BLUE);
    dc.fillCircle(cx, cy, 17);

    // draw the border
    dc.setColor(Gfx.COLOR_RED, Gfx.COLOR_GREEN);
    dc.drawCircle(cx, cy, 20);
  • It looks like you are trying to draw a filled circle (disc) inside a circle. Is there some reason you can't just use the provided API?

    dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_BLACK);
    dc.clear();

    var cx = dc.getWidth() / 2;
    var cy = dc.getHeight() / 2;

    // draw the filled area
    dc.setColor(Gfx.COLOR_YELLOW, Gfx.COLOR_BLUE);
    dc.fillCircle(cx, cy, 17);

    // draw the border
    dc.setColor(Gfx.COLOR_RED, Gfx.COLOR_GREEN);
    dc.drawCircle(cx, cy, 20);


    This is not exactly the use case. What I was trying to achieve is something like this:



    Bye
  • Former Member
    Former Member over 7 years ago
    If you do not have to worry about transparency or variable background color, it would be more efficient to do as a Brian suggested and partially obscure a full circle with a rectangle before drawing the outer unfilled circle.
  • Former Member
    Former Member over 7 years ago
    Try the drawArc command and set the penWidth to the radius of the circle. You can determine where to start and where to end the semicircle (in degrees).

    for example :
    // Draw sunrise and sunset colored dial
    var sunrisehour = ((sunrise_h * 60) + sunrise_m)/60;
    sunrisehour = sunrisehour*360/24;
    var sunsethour = ((sunset_h * 60) + sunset_m)/60;
    sunsethour = sunsethour*360/24;

    dc.setColor(Gfx.COLOR_DK_GRAY, Gfx.COLOR_TRANSPARENT);
    dc.fillCircle(xlowerdial,ylowerdial,32);
    dc.setPenWidth(32);
    dc.setColor(Gfx.COLOR_BLUE, Gfx.COLOR_TRANSPARENT);
    dc.drawArc(xlowerdial, ylowerdial, 15, Gfx.ARC_CLOCKWISE, 450-sunrisehour, 450-sunsethour);