我不相信运行的每个层上的中点画圆算法,一旦你达到了极点会得到期望的结果,因为你将不得不在表面差距在哪里LED未发光的。这可能会给你想要的结果,但是,这将取决于美学。这篇文章是基于使用中点圆算法来确定通过中间两个垂直八分圆的图层的半径,然后绘制每个圆时也设置极点八分的点。
我认为基于@Nick Udall的评论和回答here使用圆算法来确定您的水平切片的半径将与我在他的回答评论中提出的修改一起使用。应该修改圆算法以将初始误差作为输入,并且还为极点八分区绘制附加点。
- 在
y0 + y1
和y0 - y1
绘制标准圆算法点:x0 +/- x, z0 +/- z, y0 +/- y1
,x0 +/- z, z0 +/- x, y0 +/- y1
,总16分。这形成了球体垂直的大部分。
- 另外画出点
x0 +/- y1, z0 +/- x, y0 +/- z
和x0 +/- x, z0 +/- y1, y0 +/- z
,总共16点,这将形成球体的极顶。
通过将外部算法的误差传递给圆形算法,它将允许每个图层圆的子体素调整。如果不将误差传递到内部算法中,则圆的赤道将近似为圆柱体,并且x,y和z轴上的每个近似球面将形成一个正方形。在包含错误的情况下,给定足够大半径的每个面将近似为实心圆。
以下代码从维基百科的Midpoint circle algorithm修改而来。 DrawCircle
算法的命名法更改为在xz平面中操作,第三个初始点y0
的添加,y偏移y1
和初始错误error0
。 DrawSphere
从相同功能的修改,以第三初始点y0
并调用DrawCircle
而非DrawPixel
public static void DrawCircle(int x0, int y0, int z0, int y1, int radius, int error0)
{
int x = radius, z = 0;
int radiusError = error0; // Initial error state passed in, NOT 1-x
while(x >= z)
{
// draw the 32 points here.
z++;
if(radiusError<0)
{
radiusError+=2*z+1;
}
else
{
x--;
radiusError+=2*(z-x+1);
}
}
}
public static void DrawSphere(int x0, int y0, int z0, int radius)
{
int x = radius, y = 0;
int radiusError = 1-x;
while(x >= y)
{
// pass in base point (x0,y0,z0), this algorithm's y as y1,
// this algorithm's x as the radius, and pass along radius error.
DrawCircle(x0, y0, z0, y, x, radiusError);
y++;
if(radiusError<0)
{
radiusError+=2*y+1;
}
else
{
x--;
radiusError+=2*(y-x+1);
}
}
}
对于半径4(其实际上需要9x9x9)的球体,这将运行的三次迭代DrawCircle
例程,第一次绘制一个典型的半径4个圆(三个步骤),第二个绘制一个初始误差为0(也是三个步骤)的半径为4的圆,然后第三个绘制具有初始误差0的半径3个圆三个步骤)。最终得到9个计算点,每个点绘制32个像素。 这使得32(每圈点数)×3(每点添加或减少操作)+6(每次迭代增加,减少,移位操作)= 102每个计算点的加,减或移位操作。在这个例子中,每个圆圈3点=每层306个操作。半径算法每层增加6个操作并迭代3次,因此306 + 6 * 3 = 936
对于半径为4的示例的基本算术运算。 这里的成本是,您将重复设置某些像素而无需附加条件检查(即x = 0,y = 0或z = 0),所以如果你的I/O速度很慢,你可能会更适合添加条件检查。假设所有LED在开始时都被清除,示例圆将设置288个LED,而由于重复设置,实际上会点亮的LED更少。
看起来像这样会比适用于8x8x8网格的所有球体的bruteforce方法执行得更好,但是bruteforce方法会有一致的计时而不管半径如何,而当绘制大半径球体时,该方法会减慢只会显示一部分。然而,随着显示器立方体分辨率的提高,此算法时序将保持一致,而强力将增加。
来源
2013-12-04 20:38:47
rjp
通过LED球体判断,我们是否应该假定您需要绘制球体的内部以及以某种方式? – NominSim 2012-01-31 17:43:28
@NominSim我不这么认为。在这种情况下,他不会谈论Bresenham的圆光栅化,只能使用japreiss的蛮力解决方案。 – 2012-01-31 18:09:55
@Christian其实,我想有两个选择。 – 2012-01-31 20:14:28