Drawing Circles

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Drawing Circles

Post by MrGodin » February 16th, 2017, 2:09 am

Was wondering which way is faster for drawing circles

Code: Select all

void D3DGraphics::DrawCircle( int centerX,int centerY,int radius,Color color )
{
	int rSquared = sq( radius );
	int xPivot = (int)( radius * 0.70710678118f + 0.5f );
	for( int x = 0; x <= xPivot; x++ )
	{
		int y = (int)(sqrt( (float)( rSquared - sq( x ) ) ) + 0.5f);
		PutPixel( centerX + x,centerY + y,color );
		PutPixel( centerX - x,centerY + y,color );
		PutPixel( centerX + x,centerY - y,color );
		PutPixel( centerX - x,centerY - y,color );
		PutPixel( centerX + y,centerY + x,color );
		PutPixel( centerX - y,centerY + x,color );
		PutPixel( centerX + y,centerY - x,color );
		PutPixel( centerX - y,centerY - x,color );
	}
}
as apposed to

Code: Select all

virtual void Rasterize(Graphics& gfx) const override
		{
			Vec2 pos = trans*Vec2(0.0f,0.0f);
			for (int angle = 0; angle <= 360; angle++)
			{
				float x = (pos.x + cosf((float)angle) * parent.radius);
				float y = (pos.y + sinf((float)angle) * parent.radius);
						
				if (gfx.InBounds(x, y))
				{
					gfx.PutPixel(x, y, Colors::White);
				}

			}
		}
Is sin and cos more expensive ? I'm drawing box2D circles (was a pain in the ass to transform until i tried Vec2 pos = trans*Vec2(0.0f,0.0f);), blind stupid luck that was lol
Cheers
Curiosity killed the cat, satisfaction brought him back

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Drawing Circles

Post by albinopapa » February 16th, 2017, 2:40 am

Her's the issue with the sin,cos method, make a large circle, there will probably be spaces between the points. Small circles there will probably be some overdraw, drawing to the same pixel. Chili's method seems to work no matter the size, the only drawback I've found is I haven't found a good way of clipping besides just checking each pixel like you did in your version.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Re: Drawing Circles

Post by MrGodin » February 16th, 2017, 2:45 am

albinopapa wrote:Her's the issue with the sin,cos method, make a large circle, there will probably be spaces between the points. Small circles there will probably be some overdraw, drawing to the same pixel. Chili's method seems to work no matter the size, the only drawback I've found is I haven't found a good way of clipping besides just checking each pixel like you did in your version.
Ahh, that makes sense, and yes I found that an issue as well, and well, it's the only way i could think of too.
I tried checking every pixel the way chilli did it, but thats a lot of checks, which drove me to this solution.
Cheers
Curiosity killed the cat, satisfaction brought him back

User avatar
chili
Site Admin
Posts: 3948
Joined: December 31st, 2011, 4:53 pm
Location: Japan
Contact:

Re: Drawing Circles

Post by chili » February 16th, 2017, 3:12 am

checking each pixel is fine and pretty fast for drawing a filled circle, but wont work for a thin line circle (you can test vs. r^2, and thus you don't need any sqrt calls, just multiplication).

Check this out for basically the best thin line circle algo, it has code too: https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
Chili

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Drawing Circles

Post by albinopapa » February 16th, 2017, 5:27 am

chili wrote:checking each pixel is fine and pretty fast for drawing a filled circle, but wont work for a thin line circle (you can test vs. r^2, and thus you don't need any sqrt calls, just multiplication).

Check this out for basically the best thin line circle algo, it has code too: https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
Yeah, with the filled circle, you don't even have to check each pixel for clipping off screen, you can use the same method you used for the sprite clipping. That will give you the starting and ending width and height, you just offset those by -radius before you do the loops and handle disc drawing like normal.

Me personally, I decided to do the filled circle routine, but have an inner and outer radius to check against. It's a lot more flexible and allows for the offscreen clipping setup. Yeah there's some wasted cycles checking the inner portions of the circle, but there's always going to be SOME waste somewhere.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Re: Drawing Circles

Post by MrGodin » February 16th, 2017, 6:45 am

Now for a challenge, to fill a circle with a texture :D.. Triangle fan, perhaps?
Curiosity killed the cat, satisfaction brought him back

User avatar
chili
Site Admin
Posts: 3948
Joined: December 31st, 2011, 4:53 pm
Location: Japan
Contact:

Re: Drawing Circles

Post by chili » February 16th, 2017, 7:43 am

MrGodin wrote:Now for a challenge, to fill a circle with a texture :D.. Triangle fan, perhaps?
In most 3D accelerated graphics, filled circles (textured or otherwise) are all drawn as triangle fans. You could be drawn with pixel shaders / maybe with the help of geometry shaders, but I think triangle fan is the most common.
Chili

Post Reply