11

I want to draw a 2d, filled, circle. I've looked everywhere and cannot seem to find anything that will even remotely help me draw a circle. I simply want to specify a height and width and location on my canvas.

Anyone know how?

Thanks!

George Johnston
  • 31,652
  • 27
  • 127
  • 172

7 Answers7

14

XNA doesn't normally have an idea of a canvas you can paint on. Instead you can either create a circle in your favorite paint program and render it as a sprite or create a series vertexes in a 3D mesh to approximate a circle and render that.

Jake Pearson
  • 27,069
  • 12
  • 75
  • 95
9

Had the same problem, as others already suggested you need to draw a square or rectangle with a circle texture on it. Here follows my method to create a circle texture runtime. Not the most efficient or fancy way to do it, but it works.

Texture2D createCircleText(int radius)
{
    Texture2D texture = new Texture2D(GraphicsDevice, radius, radius);
    Color[] colorData = new Color[radius*radius];

    float diam = radius / 2f;
    float diamsq = diam * diam;

    for (int x = 0; x < radius; x++)
    {
        for (int y = 0; y < radius; y++)
        {
            int index = x * radius + y;
            Vector2 pos = new Vector2(x - diam, y - diam);
            if (pos.LengthSquared() <= diamsq)
            {
                colorData[index] = Color.White;
            }
            else
            {
                colorData[index] = Color.Transparent;
            }
        }
    }

    texture.SetData(colorData);
    return texture;
}
Anon
  • 181
  • 2
  • 2
  • 4
    [The diameter is defined as the radius time 2](https://en.wikipedia.org/wiki/Diameter). It would be better if you swapped those variable names. – cor Sep 20 '18 at 09:18
8

You could also check out the sample framework that Jeff Weber uses in Farseer:
http://www.codeplex.com/FarseerPhysics

The demos have a dynamic texture generator that let's him make circles and rectangles (which the samples then use as the visualization of the physics simulation). You could just re-use that :-)

Joel Martinez
  • 46,929
  • 26
  • 130
  • 185
3

Out of the box, there's no support for this in XNA. I'm assuming you're coming from some GDI background and just want to see something moving around onscreen. In a real game though, this is seldom if ever needed.

There's some helpful info here:

http://forums.xna.com/forums/t/7414.aspx

My advice to you would be to just fire up paint or something, and create the basic shapes yourself and use the Content Pipeline.

BFree
  • 102,548
  • 21
  • 159
  • 201
2

Another option (if you want to use a more complex gradient brush or something) is to draw a quad aligned to the screen and use a pixel shader.

Robert Fraser
  • 10,649
  • 8
  • 69
  • 93
1

What I did to solve this was to paint a rectangular texture, leaving the area of the rectangle which doesn't contain the circle transparent. You check to see if a point in the array is contained within a circle originating from the center of the rectangle.

Using the color data array is a bit weird because its not a 2D array. My solution was to bring in some 2D array logic into the scenario.

public Texture2D GetColoredCircle(float radius, Color desiredColor)
    {
        radius = radius / 2;
        int width = (int)radius * 2;
        int height = width;

        Vector2 center = new Vector2(radius, radius);

        Circle circle = new Circle(center, radius,false);

        Color[] dataColors = new Color[width * height];
        int row = -1; //increased on first iteration to zero!
        int column = 0;
        for (int i = 0; i < dataColors.Length; i++)
        {
            column++;
            if(i % width == 0) //if we reach the right side of the rectangle go to the next row as if we were using a 2D array.
            {
                row++;
                column = 0;
            }
            Vector2 point = new Vector2(row, column); //basically the next pixel.
            if(circle.ContainsPoint(point))
            {
                dataColors[i] = desiredColor; //point lies within the radius. Paint it.
            }
            else
            {
                dataColors[i] = Color.Transparent; //point lies outside, leave it transparent.
            }
            
        }
        Texture2D texture = new Texture2D(GraphicsDevice, width, height);
        texture.SetData(0, new Rectangle(0, 0, width, height), dataColors, 0, width * height);
        return texture;
    }

And here's the method to check whether or not a point is contained within your circle:

 public bool ContainsPoint(Vector2 point)
    {
        return ((point - this.Center).Length() <= this.Radius);
    }

Hope this helps!

-1
 public Texture2D createCircleText(int radius, GraphicsDevice Devise,Color color,int tickenes)
    {
        Texture2D texture = new Texture2D(Devise, radius, radius);
        Color[] colorData = new Color[radius * radius];
        if (tickenes >= radius) tickenes = radius - 5;
        float diam = radius / 2f;
        float diamsq = diam * diam;
        float intdiam = (radius-tickenes) / 2f;
        float intdiamsq = intdiam * intdiam;

        for (int x = 0; x < radius; x++)
        {
            for (int y = 0; y < radius; y++)
            {
                int index = x * radius + y;
                Vector2 pos = new Vector2(x - diam, y - diam);
                if (pos.LengthSquared() <= diamsq)
                {
                    colorData[index] = color;
                }
                else
                {
                    colorData[index] = Color.Transparent;
                }
                if (pos.LengthSquared() <= intdiamsq)
                {
                    colorData[index] = Color.Transparent; 
                }
            }
        }

        texture.SetData(colorData);
        return texture;
    }