[英]XNA Draw a filled circle
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. 在XNA的另一个主题中, Callum Rogers编写了一些代码 ,用于创建一个带圆圈轮廓的纹理,但我正在尝试创建一个充满颜色的圆圈。 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;
}
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.
你有3D加速的原因。
Just draw the circle similar to a pie using a triangle fan. 只需使用三角形扇形绘制类似于饼图的圆圈即可。 You'll need the following vertices.
你需要以下顶点。
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.
然后,顶点1,3和4将定义第二个多边形等。
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 ).
第一个角度为0°,以下为倍数(360°/ 圆圈点 )。 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. 根据圆上顶点的数量,您将获得不同的n-gons。 The more vertices you use the rounder the shape will look (at some performance cost):
您使用圆形的顶点越多,形状就会看起来(以某些性能成本):
Actually the XNA example for drawing primites show how to draw a circle (or n-gon) using a triangle fan. 实际上,绘制图像的XNA示例显示了如何使用三角形扇形绘制圆(或n-gon)。
well for anyone who wants to do it pixel by pixel ... i made a solution based on the information given. 对于任何想要逐个像素地做的人来说......我根据给出的信息做了一个解决方案。 In your 2d texture method add the following code to fill the circle.
在您的2D纹理方法中,添加以下代码以填充圆圈。 I'm making a game and wanted to be able to make circles different colors and sizes.
我正在制作游戏,希望能够制作不同颜色和大小的圆圈。 So inside CreateCircle(int radius) method, add the following code after the outline has been created :
因此,在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;
If you need to do it from scratch (though I'm guessing there are easier ways), change the way you perform the rendering. 如果您需要从头开始(尽管我猜测有更简单的方法),请更改执行渲染的方式。 Instead of iterating through angles and plotting pixels, iterate through pixels and determine where they are relative to the circle.
而不是迭代角度和绘制像素,迭代像素并确定它们相对于圆的位置。 If they are
<R
, draw as fill color. 如果它们是
<R
,则绘制为填充颜色。 If they are ~= R
, draw as border color. 如果它们是
~= R
,则绘制为边框颜色。
I know that I'm a little late, but I modified your code to fill in the center 我知道我有点晚了,但我修改了你的代码以填补中心
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.