HOWTO draw circles, arcs and vector graphics in SDL?

effbiae picture effbiae · Jul 12, 2016 · Viewed 24.5k times · Source

(I'm using SDL2)

SDL is a relatively small library for "low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D" It's used for game development and, in my case, as simple audio visual output and mouse+keyboard input. It's not a "toolkit" like GTK, Qt, wxWindows, etc. But it is cross-platform.

But the only way I can find to draw a shape is with the line, rect and pixel functions.

Apart from using trig or the "equation of a circle", how could I draw a curve? How about general vector graphics?

Is SDL an appropriate starting point or should I look elsewhere?

Answer

Scotty Stephens picture Scotty Stephens · Jan 17, 2018

This is an example of the Midpoint Circle Algorithm as referenced above. It doesn't require a math library and is very fast. (Renders in about 500 microseconds) This is what Windows uses/used to rasterize circles.

void DrawCircle(SDL_Renderer * renderer, int32_t centreX, int32_t centreY, int32_t radius)
{
   const int32_t diameter = (radius * 2);

   int32_t x = (radius - 1);
   int32_t y = 0;
   int32_t tx = 1;
   int32_t ty = 1;
   int32_t error = (tx - diameter);

   while (x >= y)
   {
      //  Each of the following renders an octant of the circle
      SDL_RenderDrawPoint(renderer, centreX + x, centreY - y);
      SDL_RenderDrawPoint(renderer, centreX + x, centreY + y);
      SDL_RenderDrawPoint(renderer, centreX - x, centreY - y);
      SDL_RenderDrawPoint(renderer, centreX - x, centreY + y);
      SDL_RenderDrawPoint(renderer, centreX + y, centreY - x);
      SDL_RenderDrawPoint(renderer, centreX + y, centreY + x);
      SDL_RenderDrawPoint(renderer, centreX - y, centreY - x);
      SDL_RenderDrawPoint(renderer, centreX - y, centreY + x);

      if (error <= 0)
      {
         ++y;
         error += ty;
         ty += 2;
      }

      if (error > 0)
      {
         --x;
         tx += 2;
         error += (tx - diameter);
      }
   }
}