问题描述
|
在XNA的另一个线程中,Callum Rogers编写了一些代码来创建带有圆形轮廓的纹理,但是我试图创建一个填充有颜色的圆形。我必须对此代码进行哪些修改才能用颜色填充圆圈?
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;
}
解决方法
不要对此类东西使用纹理(特别是对于一种单色的东西!)-也不要尝试逐像素地进行处理。您的3D加速是有原因的。
只需使用三角扇绘制类似于饼图的圆即可。您将需要以下顶点。
圆心
在圆的边界上的x点。
前两个点将在圆心与其边界之间定义一条线。第三个顶点将定义第一个多边形。然后,顶点1、3和4将定义第二个多边形,依此类推。
要获取圆边界上的点,请使用示例中的公式。第一个角度将为0°,随后为(360°/圆点)的倍数。要获得一个完整的圆圈,您需要一个与第二个点(边界上的第一个点)匹配的附加点。
根据圆上顶点的数量,您将获得不同的n角。您使用的形状越圆的顶点越多(某些性能成本):
(由于多边形需要至少绘制3个顶点,因此不可能少于2个顶点。)
总共4点(圆上3点)将产生一个三角形。
总共5点(圆上为4点)将形成一个正方形。
总共6分(5分是圆形)将形成一个五边形
...
实际上,用于绘制图素的XNA示例说明了如何使用三角形扇形绘制圆(或n形)。
,对于想逐个像素地做的人来说很好...我根据给出的信息提出了解决方案。在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;
,如果您需要从头开始(尽管我猜有更简单的方法),请更改执行渲染的方式。而不是遍历角度并绘制像素,而是遍历像素并确定它们相对于圆的位置。如果它们是<R
,则绘制为填充色。如果它们是“ 3”,则绘制为边框颜色。
,我知道我来晚了,但是我修改了您的代码以填写中心
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);
}
}
}
texture.SetData(data);
return texture;
}