我正在尝试光栅化和填充超球面。本质上,我有一个固定大小的d维网格和一个球体(中心,半径),想要找出网格的哪些单元格与球体重叠并存储它们的坐标。
我知道Midpoint circle algorithm利用8向镜像并生成圆的外部单元格(边框)。我还修改了链接的维基百科代码以填充圆圈(即,生成边框内所有单元格的坐标)。
但是我不知道任何更高维度的算法。例如在4d中,我一直在考虑通过生成所有可能的圆来实现,如下面的伪代码。基本思想是因为4d球是(x-x0) 2 +(y-y0)** 2 +(z-z0)** 2 +(k-k0)** 2 = r 2,这等于(x-x0) 2 +(y-y0)** 2 = r 2 - (z-z0)** 2 - (k-k0)** 2。由于我知道如何绘制圆,我只需要为z和k的所有可能值生成所有圆。
assume center=(x0,y0,z0,k0) and radius r
for all dimensions equal or higher than 2://this is z and k
//make a list of possible values this dimension can take
//from z0 to z0+radius with a step of 1
all_lists.append([dim0,dim0+1,...,dim0+radius])
produce the product of all the lists in all_lists
//now i have a list [[z0,k0],[z0,k0+1],....,[z0+1,k0],[z0+1,k0+1],....,[z0+radius,k0],...[z0+radius,k0+radius]]
for every element l of the list, compute the radius of the circular "cut"
l.append(r**2 - z**2 - k**2)
Now call the Midpoint Circle Algorithm, but for every (x,y) pair that it produces, we need to export 4 points, namely (x,y,±z,±k)
此question似乎相关,但我不明白答案。
答案 0 :(得分:1)
没有人回答一段时间,所以这里有简单而明显的C ++解决方案:
//---------------------------------------------------------------------------
const int N=10; // number of dimensions
struct point { double a[N]; }; // N-dimensional point
#define color DWORD // type of your color property
//---------------------------------------------------------------------------
// N x nested for(a=a0;a<=a1;a+=da) return false if ended
// it could be optimized a lot but for clarity I leve it as is
// ix=-1 at start and N = number of dimensions / nested count
bool nested_for(double *a0,double *a,double *a1,double *da,int &ix,int N)
{
if (ix<0)
{
int i;
if (N<1) return false; // N too low
for (i=0;i<N;i++) a[i]=a0[i];
for (i=0;i<N;i++) if (a[i]>a1[i]) return false; // a0>a1 for some i that is wrong !!!
ix=N-1;
return true;
}
for (;;) // a+=da
{
a[ix]+=da[ix];
if (a[ix]<=a1[ix]) break;
if (!ix) return false; // end of nested for
a[ix]=a0[ix];
ix--;
}
ix=N-1;
return true;
}
//---------------------------------------------------------------------------
void draw_point(point &p,color c)
{
// draw your point ...
}
//---------------------------------------------------------------------------
void fill_hypersphere(point &p0,double r,color c)
{
int i,ix;
bool init;
point a,b,a0,a1,da;
double aa,rr=r*r;
for (i=0;i<N;i++) a0.a[i]=-r; // loop boundary for all axises <-r,+r>
for (i=0;i<N;i++) a1.a[i]=+r;
for (i=0;i<N;i++) da.a[i]=1.0; // step between pixels
for (ix=-1;nested_for(a0.a,a.a,a1.a,da.a,ix,N);) // N x nested for
{
aa=0.0; // aa = distance from zero ^ 2
for (i=0;i<N;i++) aa+=a.a[i]*a.a[i];
if (aa<=rr) // if it is inside sphere
{ // compute the translated point by p0 to b
for (i=0;i<N;i++) b.a[i]=p0.a[i]+a.a[i];
draw_point(b,c); // and draw/fill it or whatever
}
}
}
//---------------------------------------------------------------------------
[Edit1]完成了一些测试