我不相信運行的每個層上的中點畫圓算法,一旦你達到了極點會得到期望的結果,因爲你將不得不在表面差距在哪裏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