DrawCircle function for 1.3

Hi there, staff and enthusiasts.
I see you’ve added a line drawing function, dissimilar with the one I made for my own program, but that’s mostly optimization.
So I decided maybe my Circle Drawing function might go through some optimization and join the process.
It basically follows the (x-x1)(x-x1)+(y-y1)(y-y1)=r*r geometry formula by x and y, drawing between the 45 degree diagonals (hence the division by square root of 2). I have some ideas about modifying it to work for making an ellipse, and a simple tweak that could determine fill (0 = no fill, otherwise give fill color). I realize the three color parameters can be put into one, and there are other tweaks to be done for supporting multiple bpp formats, but I want your opinions on this. It’s “void” because I didn’t really need program level confirmation, but visual.

Code:

void SDL_DrawCircle(SDL_Surface *screen, const Uint16 x, const Uint16 y, const Uint8 r, const Uint8 bpp, const Uint8 R, const Uint8 G, const Uint8 B)
{
Uint32 color1 = SDL_MapRGB(screen->format, R, G, B);
Uint32 *bufp1,bufp2;
Uint16 rsqr = r
r,tx,tx1,tx2,ty,ty1,ty2;
float tmpy,tmpx;

tmpx= -ceil(r/sqrt((float)2));
while(tmpx <= (float) r)
{
	if( (float)fabs(tmpx) < (float)r/sqrt((float)2)){
		tmpy = sqrt((float)(rsqr - pow(tmpx,2)));
		ty1=y+ (Uint16) floor(tmpy+0.5);
		ty2=y- (Uint16) floor(tmpy+0.5);
		tx=x-(Uint16) tmpx;
		bufp1 = (Uint32 *)screen->pixels + ty1*screen->pitch/bpp + tx;
		bufp2 = (Uint32 *)screen->pixels + ty2*screen->pitch/bpp + tx;
		*bufp1 = color1;
		*bufp2 = color1;
	}
	tmpx++;
}
tmpy = -ceil(r/sqrt((float)2));
while(tmpy <= (float) r)
{
	if( (float)fabs(tmpy) < (float)r/sqrt((float)2)){
		tmpx = sqrt((float)(rsqr - pow(tmpy,2)));
		tx1=x+ (Uint16) floor(tmpx+0.5);
		tx2=x- (Uint16) floor(tmpx+0.5);
		ty=y-(Uint16) tmpy;
		bufp1 = (Uint32 *)screen->pixels + ty*screen->pitch/bpp + tx1;
		bufp2 = (Uint32 *)screen->pixels + ty*screen->pitch/bpp + tx2;
		*bufp1 = color1;
		*bufp2 = color1;
	}
	tmpy++;
}

}

Thanks for the post. There is a much faster way to draw a circle using
this:

I copied the code from the article below. You will see there are no SQRT or
POW calls in the loop.

It has not been modified for SDL.
void rasterCircle(int x0, int y0, int radius)

{

int f = 1 - radius;

int ddF_x = 1;

int ddF_y = -2 * radius;

int x = 0;

int y = radius;



setPixel(x0, y0 + radius);

setPixel(x0, y0 - radius);

setPixel(x0 + radius, y0);

setPixel(x0 - radius, y0);



while(x < y)

{

  // ddF_x == 2 * x + 1;

  // ddF_y == -2 * y;

  // f == x*x + y*y - radius*radius + 2*x - y + 1;

  if(f >= 0) 

  {

    y--;

    ddF_y += 2;

    f += ddF_y;

  }

  x++;

  ddF_x += 2;

  f += ddF_x;    

  setPixel(x0 + x, y0 + y);

  setPixel(x0 - x, y0 + y);

  setPixel(x0 + x, y0 - y);

  setPixel(x0 - x, y0 - y);

  setPixel(x0 + y, y0 + x);

  setPixel(x0 - y, y0 + x);

  setPixel(x0 + y, y0 - x);

  setPixel(x0 - y, y0 - x);

}

}_____

From: sdl-bounces@lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org] On
Behalf Of katz
Sent: Monday, October 12, 2009 5:34 PM
To: sdl at lists.libsdl.org
Subject: [SDL] DrawCircle function for 1.3

Hi there, staff and enthusiasts.
I see you’ve added a line drawing function, dissimilar with the one I made
for my own program, but that’s mostly optimization.
So I decided maybe my Circle Drawing function might go through some
optimization and join the process.
It basically follows the (x-x1)(x-x1)+(y-y1)(y-y1)=r*r geometry formula by
x and y, drawing between the 45 degree diagonals (hence the division by
square root of 2). I have some ideas about modifying it to work for making
an ellipse, and a simple tweak that could determine fill (0 = no fill,
otherwise give fill color). I realize the three color parameters can be put
into one, and there are other tweaks to be done for supporting multiple bpp
formats, but I want your opinions on this. It’s “void” because I didn’t
really need program level confirmation, but visual.

Code:

void SDL_DrawCircle(SDL_Surface *screen, const Uint16 x, const Uint16 y,
const Uint8 r, const Uint8 bpp, const Uint8 R, const Uint8 G, const Uint8 B)
{
Uint32 color1 = SDL_MapRGB(screen->format, R, G, B);
Uint32 *bufp1,bufp2;
Uint16 rsqr = r
r,tx,tx1,tx2,ty,ty1,ty2;
float tmpy,tmpx;

tmpx= -ceil(r/sqrt((float)2));
while(tmpx <= (float) r)
{
if( (float)fabs(tmpx) < (float)r/sqrt((float)2)){
tmpy = sqrt((float)(rsqr - pow(tmpx,2)));
ty1=y+ (Uint16) floor(tmpy+0.5);
ty2=y- (Uint16) floor(tmpy+0.5);
tx=x-(Uint16) tmpx;
bufp1 = (Uint32 )screen->pixels + ty1screen->pitch/bpp + tx;
bufp2 = (Uint32 )screen->pixels + ty2screen->pitch/bpp + tx;
*bufp1 = color1;
*bufp2 = color1;
}
tmpx++;
}
tmpy = -ceil(r/sqrt((float)2));
while(tmpy <= (float) r)
{
if( (float)fabs(tmpy) < (float)r/sqrt((float)2)){
tmpx = sqrt((float)(rsqr - pow(tmpy,2)));
tx1=x+ (Uint16) floor(tmpx+0.5);
tx2=x- (Uint16) floor(tmpx+0.5);
ty=y-(Uint16) tmpy;
bufp1 = (Uint32 )screen->pixels + tyscreen->pitch/bpp + tx1;
bufp2 = (Uint32 )screen->pixels + tyscreen->pitch/bpp + tx2;
*bufp1 = color1;
*bufp2 = color1;
}
tmpy++;
}

}

There’s a lot more like this, including filled circles, ellipses, and arcs
in Sprig and SDL_gfx, though I haven’t gotten around to adding rotated
ellipses.
Jonny DOn Mon, Oct 12, 2009 at 7:02 PM, Ken Rogoway wrote:

Thanks for the post. There is a much faster way to draw a circle using
this:

http://en.wikipedia.org/wiki/Midpoint_circle_algorithm

I copied the code from the article below. You will see there are no SQRT
or POW calls in the loop.

It has not been modified for SDL.

void rasterCircle(int x0, int y0, int radius)
{
int f = 1 - radius;
int ddF_x = 1;
int ddF_y = -2 * radius;
int x = 0;
int y = radius;

setPixel(x0, y0 + radius);
setPixel(x0, y0 - radius);
setPixel(x0 + radius, y0);
setPixel(x0 - radius, y0);

while(x < y)
{
  // ddF_x == 2 * x + 1;
  // ddF_y == -2 * y;
  // f == x*x + y*y - radius*radius + 2*x - y + 1;
  if(f >= 0)
  {
    y--;
    ddF_y += 2;
    f += ddF_y;
  }
  x++;
  ddF_x += 2;
  f += ddF_x;
  setPixel(x0 + x, y0 + y);
  setPixel(x0 - x, y0 + y);
  setPixel(x0 + x, y0 - y);
  setPixel(x0 - x, y0 - y);
  setPixel(x0 + y, y0 + x);
  setPixel(x0 - y, y0 + x);
  setPixel(x0 + y, y0 - x);
  setPixel(x0 - y, y0 - x);
}

}


From: sdl-bounces at lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org]
*On Behalf Of *katz
Sent: Monday, October 12, 2009 5:34 PM
To: sdl at lists.libsdl.org
Subject: [SDL] DrawCircle function for 1.3

Hi there, staff and enthusiasts.
I see you’ve added a line drawing function, dissimilar with the one I made
for my own program, but that’s mostly optimization.
So I decided maybe my Circle Drawing function might go through some
optimization and join the process.
It basically follows the (x-x1)(x-x1)+(y-y1)(y-y1)=r*r geometry formula
by x and y, drawing between the 45 degree diagonals (hence the division by
square root of 2). I have some ideas about modifying it to work for making
an ellipse, and a simple tweak that could determine fill (0 = no fill,
otherwise give fill color). I realize the three color parameters can be put
into one, and there are other tweaks to be done for supporting multiple bpp
formats, but I want your opinions on this. It’s “void” because I didn’t
really need program level confirmation, but visual.

Code:

void SDL_DrawCircle(SDL_Surface *screen, const Uint16 x, const Uint16 y,
const Uint8 r, const Uint8 bpp, const Uint8 R, const Uint8 G, const Uint8 B)
{
Uint32 color1 = SDL_MapRGB(screen->format, R, G, B);
Uint32 *bufp1,bufp2;
Uint16 rsqr = r
r,tx,tx1,tx2,ty,ty1,ty2;
float tmpy,tmpx;

tmpx= -ceil(r/sqrt((float)2));
while(tmpx <= (float) r)
{
if( (float)fabs(tmpx) < (float)r/sqrt((float)2)){
tmpy = sqrt((float)(rsqr - pow(tmpx,2)));
ty1=y+ (Uint16) floor(tmpy+0.5);
ty2=y- (Uint16) floor(tmpy+0.5);
tx=x-(Uint16) tmpx;
bufp1 = (Uint32 )screen->pixels + ty1screen->pitch/bpp + tx;
bufp2 = (Uint32 )screen->pixels + ty2screen->pitch/bpp + tx;
*bufp1 = color1;
*bufp2 = color1;
}
tmpx++;
}
tmpy = -ceil(r/sqrt((float)2));
while(tmpy <= (float) r)
{
if( (float)fabs(tmpy) < (float)r/sqrt((float)2)){
tmpx = sqrt((float)(rsqr - pow(tmpy,2)));
tx1=x+ (Uint16) floor(tmpx+0.5);
tx2=x- (Uint16) floor(tmpx+0.5);
ty=y-(Uint16) tmpy;
bufp1 = (Uint32 )screen->pixels + tyscreen->pitch/bpp + tx1;
bufp2 = (Uint32 )screen->pixels + tyscreen->pitch/bpp + tx2;
*bufp1 = color1;
*bufp2 = color1;
}
tmpy++;
}

}


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Thanks Ken Rogoway, that was an interesting read, but I still don’t understand how does the algorithm draw the 1/8 of a circle. it seems to disconnect from the xx + yy = radius*radius formula, so I definitely couldn’t believe it before I tried it.