Draw every second pixel of a circle

Hi again,

I would like to draw circles that are not solid. For example every second pixel. Has anyone done such a thing? I presume I would use the pixel command and feed to it the formula for a circle? Have one of you seen a technique like this in use and count point it out? Thank you.

If you do your own implemenation of https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm/ it would be pretty easy to have it skip drawing every other pixel, as it draws just one pixel per iteration. You’d probably not be able to use the symmetry parts of this and have to do the whole perimeter unless you could be sure that each quadrant was an even number of pixels.

Thanks @unwiredben. Indeed I took the Bres. circle algorithm from Arduboy2.cpp, I couldn’t work out how to alternate WHITE and BLACK pixels:

#include <Arduboy2.h>

// make an instance of arduboy used for many functions
Arduboy2 arduboy;


// This function runs once in your game.
// use it for anything that needs to be set only once in your game.
void setup() {
  // initiate arduboy instance
  arduboy.begin();
  // here we set the framerate to 15, we do not need to run at
  // default 60 and it saves us battery life
  arduboy.setFrameRate(15);
}


// our main game loop, this runs once every cycle/frame.
// this is where our game logic goes.
void loop() {
  // pause render until it's time for the next frame
  if (!(arduboy.nextFrame()))
    return;


  // first we clear our screen to black
  arduboy.clear();
  drawACircle(20,20,20,1);


  // then we finaly we tell the arduboy to display what we just wrote to the display
  arduboy.display();
}

void drawACircle(int16_t x0, int16_t y0, uint8_t r, uint8_t color)
{
  int16_t f = 1 - r;
  int16_t ddF_x = 1;
  int16_t ddF_y = -2 * r;
  int16_t x = 0;
  int16_t y = r;

  arduboy.drawPixel(x0, y0+r, color);
  arduboy.drawPixel(x0, y0-r, color);
  arduboy.drawPixel(x0+r, y0, color);
  arduboy.drawPixel(x0-r, y0, color);

  while (x<y)
  {
    if (f >= 0)
    {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }

    x++;
    ddF_x += 2;
    f += ddF_x;

    arduboy.drawPixel(x0 + x, y0 + y, color);
    arduboy.drawPixel(x0 - x, y0 + y, color);
    arduboy.drawPixel(x0 + x, y0 - y, color);
    arduboy.drawPixel(x0 - x, y0 - y, color);
    arduboy.drawPixel(x0 + y, y0 + x, color);
    arduboy.drawPixel(x0 - y, y0 + x, color);
    arduboy.drawPixel(x0 + y, y0 - x, color);
    arduboy.drawPixel(x0 - y, y0 - x, color);
  }
}

I didn’t have the first clue about how the circle drawing algorithm actually works,
but fortunately I made some lucky guesses…

Will this suffice?

#include <Arduboy2.h>

Arduboy2 arduboy;

void setup()
{
  arduboy.begin();
}


void loop()
{
  if (!arduboy.nextFrame())
    return;

  // Update the button state
  arduboy.pollButtons();

  // Clear the screen buffer
  arduboy.clear();

  // Draw a circle
  drawCircle(20,20,20,1);

  // Update the screen
  arduboy.display();
}

void drawCircle(int16_t x0, int16_t y0, uint8_t r, uint8_t color)
{
  int16_t f = 1 - r;
  int16_t ddF_x = 1;
  int16_t ddF_y = -2 * r;
  int16_t x = 0;
  int16_t y = r;

  // Draw the 4 endpoints (the tips of a + shape)
  arduboy.drawPixel(x0, y0 + r, ~color);
  arduboy.drawPixel(x0, y0 - r, ~color);
  arduboy.drawPixel(x0 + r, y0, ~color);
  arduboy.drawPixel(x0 - r, y0, ~color);

  while (x<y)
  {
    if (f >= 0)
    {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }

    x++;
    ddF_x += 2;
    f += ddF_x;

    arduboy.drawPixel(x0 + x, y0 + y, color);
    arduboy.drawPixel(x0 - x, y0 + y, color);
    arduboy.drawPixel(x0 + x, y0 - y, color);
    arduboy.drawPixel(x0 - x, y0 - y, color);
    arduboy.drawPixel(x0 + y, y0 + x, color);
    arduboy.drawPixel(x0 - y, y0 + x, color);
    arduboy.drawPixel(x0 + y, y0 - x, color);
    arduboy.drawPixel(x0 - y, y0 - x, color);

    color = ~color;
  }
}

Try it in the emulator:
Circles.ino.arduino_leonardo.hex (19.8 KB)

@Pharap WOW. How the heck…

Is there an ending to that sentence?
I don’t know what the implied question is supposed to be.


Thinking about it, technically the ~colors should actually be (~color & 0x01) because of the way black and white are defined by the library, but it ought to work anyway because of how drawPixel works.

@Pharap So cool. How does it work?

~ is ‘bitwise not’ which inverts the colour from white to black.

Which technically means the circle is actually drawing white and black rather than white and transparent which isn’t quite what you want… Hrm…

So on second thought you might was this instead:

void drawCircle(int16_t x0, int16_t y0, uint8_t r, uint8_t color)
{
  int16_t f = 1 - r;
  int16_t ddF_x = 1;
  int16_t ddF_y = -2 * r;
  int16_t x = 0;
  int16_t y = r;

  while (x<y)
  {
    if (f >= 0)
    {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }

    x++;
    ddF_x += 2;
    f += ddF_x;

    if(color != 0)
    {
      arduboy.drawPixel(x0 + x, y0 + y, color);
      arduboy.drawPixel(x0 - x, y0 + y, color);
      arduboy.drawPixel(x0 + x, y0 - y, color);
      arduboy.drawPixel(x0 - x, y0 - y, color);
      arduboy.drawPixel(x0 + y, y0 + x, color);
      arduboy.drawPixel(x0 - y, y0 + x, color);
      arduboy.drawPixel(x0 + y, y0 - x, color);
      arduboy.drawPixel(x0 - y, y0 - x, color);
    }

    color = ~color;
  }
}

As for how the circle drawing actually happens,
I haven’t a clue ¯\_(ツ)_/¯.
I’m not very good at maths, and I haven’t found a decent explanation of the algorithm online.

@Pharap using a not, very clever. And transparent is indeed what I wanted. Many thanks.

1 Like