XNA Нарисуй закрашенный круг - PullRequest
3 голосов
/ 13 апреля 2011

В другой теме по XNA Каллум Роджерс написал код , который создает текстуру с контуром круга, но я пытаюсь создать круг, заполненный цветом.Что мне нужно изменить в этом коде, чтобы закрасить кружок цветом?

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;
}

Ответы [ 4 ]

4 голосов
/ 13 апреля 2011

Не используйте текстуру для подобных вещей (особенно для вещей одного цвета!) - также не пытайтесь делать это попиксельно. У вас есть 3D ускорение по причине.

Просто нарисуйте круг, похожий на пирог, используя веер треугольника. Вам понадобятся следующие вершины.

  • Центр круга
  • х точек на границе круга.

Первые две точки будут определять линию между центром круга и его границей. Третья вершина будет определять первый многоугольник. Вершины 1, 3 и 4 будут определять второй многоугольник и т. Д.

Чтобы получить точки на границе круга, используйте формулы из вашего примера. Первый угол будет 0 °, следующие кратны (360 ° / точек на окружности ). Чтобы получить полный круг, вам понадобится еще одна точка, соответствующая второй точке (первой точке на границе).

В зависимости от количества вершин на окружности вы получите разные n-угольники. Чем больше вершин вы используете, тем больше будет выглядеть форма (при некоторой производительности):

  • (Менее 2 вершин невозможно, поскольку для многоугольника необходимо нарисовать как минимум 3 вершины.)
  • Всего 4 очка (3 очка по кругу) приведут к треугольнику.
  • Всего 5 очков (4 очка на окружности) приведут к квадрату.
  • Всего 6 очков (5 очков по кругу) приведет к пятиугольнику
  • ...

На самом деле пример XNA для рисования примитивов показывает, как нарисовать круг (или n-гон), используя веер треугольника.

4 голосов
/ 10 декабря 2011

хорошо для тех, кто хочет сделать это попиксельно ... я сделал решение на основе предоставленной информации. В вашем методе 2D текстуры добавьте следующий код, чтобы заполнить круг. Я делаю игру и хотел иметь возможность делать круги разных цветов и размеров. Поэтому внутри метода CreateCircle (int radius) добавьте следующий код после создания контура:

        bool finished = false;
        int firstSkip = 0;
        int lastSkip = 0;
        for (int i = 0; i <= data.Length - 1; i++)
        {
            if (finished == false)
            {
                //T = transparent W = White;
                //Find the First Batch of Colors TTTTWWWTTTT The top of the circle
                if ((data[i] == Color.White) && (firstSkip == 0))
                {
                    while (data[i + 1] == Color.White)
                    {
                        i++;
                    }
                    firstSkip = 1;
                    i++;
                }
                //Now Start Filling                       TTTTTTTTWWTTTTTTTT
                //circle in Between                       TTTTTTW--->WTTTTTT
                //transaparent blancks                    TTTTTWW--->WWTTTTT
                //                                        TTTTTTW--->WTTTTTT
                //                                        TTTTTTTTWWTTTTTTTT
                if (firstSkip == 1)
                {
                    if (data[i] == Color.White && data[i + 1] != Color.White)
                    {
                        i++;
                        while (data[i] != Color.White)
                        {
                                //Loop to check if its the last row of pixels
                                //We need to check this because of the 
                                //int outerRadius = radius * 2 + -->'2'<--;
                                for (int j = 1; j <= outerRadius; j++)
                                {
                                    if (data[i + j] != Color.White)
                                    {
                                        lastSkip++;
                                    }
                                }
                                //If its the last line of pixels, end drawing
                                if (lastSkip == outerRadius)
                                {
                                    break;
                                    finished = true;
                                }
                                else
                                {
                                    data[i] = Color.White;
                                    i++;
                                    lastSkip = 0;
                                }
                            }
                        while (data[i] == Color.White)
                        {
                            i++;
                        }
                        i--;
                    }


                }
            }
        }
        // Set the data when finished 
        //-- don't need to paste this part, already given up above
        texture.SetData(data);
        return texture;
1 голос
/ 13 апреля 2011

Если вам нужно сделать это с нуля (хотя я предполагаю, что есть более простые способы), измените способ выполнения рендеринга. Вместо перебора углов и построения пикселей, перебирайте пиксели и определяйте их расположение по отношению к окружности. Если они <R, нарисуйте цвет заливки. Если они ~= R, нарисуйте цвет рамки.

0 голосов
/ 27 июля 2013

Я знаю, что немного опоздал, но я изменил твой код, чтобы заполнить центр

public static Texture2D CreateCircle(GraphicsDevice importedGraphicsDevice, int radius)
    {
        int outerRadius = radius * 2 + 2; // So circle doesn't go out of bounds
        Texture2D texture = new Texture2D(importedGraphicsDevice, 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;
        }

                    //width
        for (int i = 0; i < outerRadius; i++)
        {
            int yStart = -1;
            int yEnd = -1;


            //loop through height to find start and end to fill
            for (int j = 0; j < outerRadius; j++)
            {

                if (yStart == -1)
                {
                    if (j == outerRadius - 1)
                    {
                        //last row so there is no row below to compare to
                        break;
                    }

                    //start is indicated by Color followed by Transparent
                    if (data[i + (j * outerRadius)] == Color.White && data[i + ((j + 1) * outerRadius)] == Color.Transparent)
                    {
                        yStart = j + 1;
                        continue;
                    }
                }
                else if (data[i + (j * outerRadius)] == Color.White)
                {
                    yEnd = j;
                    break;
                }
            }

            //if we found a valid start and end position
            if (yStart != -1 && yEnd != -1)
            {
                //height
                for (int j = yStart; j < yEnd; j++)
                {
                    data[i + (j * outerRadius)] = new Color(10, 10, 10, 10);
                }
            }
        }

        texture.SetData(data);
        return texture;
    }
...