XNA Draw a filled circle

programad picture programad · Apr 12, 2011 · Viewed 12.8k times · Source

In another thread on XNA, Callum Rogers wrote some code which creates a texture with the outline of a circle, but I'm trying to create a circle filled with a color. What I have to modify on this code to fill the circle with color?

public Texture2D CreateCircle(int radius)
{
    int outerRadius = radius*2 + 2; // So circle doesn't go out of bounds
    Texture2D texture = new Texture2D(GraphicsDevice, outerRadius, outerRadius);

    Color[] data = new Color[outerRadius * outerRadius];

    // Colour the entire texture transparent first.
    for (int i = 0; i < data.Length; i++)
        data[i] = Color.Transparent;

    // Work out the minimum step necessary using trigonometry + sine approximation.
    double angleStep = 1f/radius;

    for (double angle = 0; angle < Math.PI*2; angle += angleStep)
    {
        // Use the parametric definition of a circle: http://en.wikipedia.org/wiki/Circle#Cartesian_coordinates
        int x = (int)Math.Round(radius + radius * Math.Cos(angle));
        int y = (int)Math.Round(radius + radius * Math.Sin(angle));

        data[y * outerRadius + x + 1] = Color.White;
    }

    texture.SetData(data);
    return texture;
}

Answer

Mario picture Mario · Apr 13, 2011

Don't use a texture for stuff like this (especially for things being in one single color!) - also don't try to do it pixel by pixel. You've got 3D acceleration for a reason.

Just draw the circle similar to a pie using a triangle fan. You'll need the following vertices.

  • Center of the circle
  • x points on the circle's border.

The first two points will define a line between the center of the circle and its border. The third vertex will define the first polygon. Vertices 1, 3 and 4 will then define the second polygon, etc.

To get the points on the circle's border use the formulas from your example. The first angle will be 0°, the following ones multiples of (360° / points on circle). To get a full circle you'll need one additional point that matches the second point (the first point on the border).

Depending on the number of vertices on the circle you'll get different n-gons. The more vertices you use the rounder the shape will look (at some performance cost):

  • (Less than 2 vertices aren't possible as a polygon requires at least 3 vertices to be drawn.)
  • Total of 4 points (3 points on circle) will result in a triangle.
  • Total of 5 points (4 point on circle) will result in a square.
  • Total of 6 points (5 points on circle) will result in a pentagon
  • ...

Actually the XNA example for drawing primites show how to draw a circle (or n-gon) using a triangle fan.