将立方体变形为球体

6
我创建了一个由小球模型构成的立方体,其作为点的作用。这些点具有以下坐标:
{0 <= x <= 9, 0 <= y <= -9, 0 <= z <= -9}
立方体内部为空,因此点只存在于立方体表面。空白空间表示为(100,100,100)的点,当我执行绘制循环时,我会忽略与它们匹配的点,这就是为什么在下面发布的代码中会将其作为某些条件执行或不执行某些操作的原因。
目标是将立方体的点应用变换映射到一个球体上。
这是转换点所使用的方程组的图示。
这是创建立方体位置数组然后创建球形位置数组的代码:
// initialize cube array
points = new Matrix[10, 10, 10];

for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        for (int k = 0; k < 10; k++)
        {
            points[i, j, k] = Matrix.CreateTranslation(new Vector3(100, 100, 100));
        }
    }
}

for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        points[i, j, 0] = Matrix.CreateTranslation(new Vector3(i, -j, 0));
        points[i, j, 9] = Matrix.CreateTranslation(new Vector3(i, -j, -9));
    }
}

for (int j = 0; j < 10; j++)
{
    for (int k = 0; k < 10; k++)
    {
        points[0, j, k] = Matrix.CreateTranslation(new Vector3(0, -j, -k));
        points[9, j, k] = Matrix.CreateTranslation(new Vector3(9, -j, -k));
    }
}

for (int i = 0; i < 10; i++)
{
    for (int k = 0; k < 10; k++)
    {
        points[i, 0, k] = Matrix.CreateTranslation(new Vector3(i, 0, -k));
        points[i, 9, k] = Matrix.CreateTranslation(new Vector3(i, -9, -k));
    }
}
// end cube array initialization

// create sphere array
double d;
double theta;
double phi;
double r = 10;

spherePoints = new Matrix[10, 10, 10];
for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        for (int k = 0; k < 10; k++)
        {
            if (points[i, j, k] != Matrix.CreateTranslation(new Vector3(100, 100, 100)))
            {
                d = Math.Sqrt(Math.Pow(i, 2) + Math.Pow(-j, 2) + Math.Pow(-k, 2));
                theta = Math.Acos(-k / d);
                phi = Math.Atan2(-j, i);

                spherePoints[i, j, k] = Matrix.CreateTranslation(new Vector3((float)(r * Math.Sin(theta) * Math.Cos(phi)),
                                                                            (float)(r * Math.Sin(theta) * Math.Sin(phi)),
                                                                            (float)(r * Math.Cos(theta))));
            }
            else
                spherePoints[i, j, k] = Matrix.CreateTranslation(new Vector3(100, 100, 100));
        }
    }
}
// end creation of sphere array

立方体: enter image description here

不是一个球体...: enter image description here

从我所能看出来,我完全按照公式操作,但它似乎只生成了八分之一的球体。边缘也出现了奇怪的分组。


6
@Leonardo 对不起,请问这个页面中哪里写了这个?http://stackoverflow.com/faq#dontask这个网站的目的是为了解决编程问题。我并不是在让任何人帮我做作业。我只是试图找出代码中奇怪行为的原因。询问帮助是否违反了一个旨在提供帮助的网站的规定? - Portaljacker
有关生成球面点的算法有很多。http://math.stackexchange.com/questions/299981/generating-evenly-distributed-points-on-a-sphere http://gamedev.stackexchange.com/questions/16585/how-do-you-programmatically-generate-a-sphere https://dev59.com/BFLTa4cB1Zd3GeqPZ2P1 - Pete
@Pete,这些似乎都是关于制作球体的。这个任务的目标是将立方体的点变形为球体上的位置。这些链接似乎是指从头开始制作球体。 - Portaljacker
那么你正在问什么问题呢?我认为问题围绕着你只生成了1/8的球这一事实。也许你可以在文字中更明显地表达你的问题。 - Pete
如果标签已经过时了...嗯...这有点提示不要做某事... @Portaljacker http://stackoverflow.com/questions/tagged/homework - Leonardo
显示剩余4条评论
1个回答

4
问题在于你只在一个“象限”(或者也许更适合说是“八分之一”的象限)中绘制了你的立方体,因此你只得到了你的球体的1/8。
将你的立方体从[0,9],[-9,0],[-9,0] 改为以原点为中心。
一旦你的立方体从[-5,5],[-5,5],[-5,5]开始,你的球面计算就没问题了。
只是为了更好地理解这个问题:
- 当你评估Acos(z/d)时,给定d始终为正数且z始终为负数,你的答案会在多少个象限中? - 当你评估Atan(y,x)时,给定y始终为负数且x始终为负数,你的答案会在多少个象限中?
在可能的8个象限组合中,你只填充了一个。

所以我的立方体现在在所有轴上都从[-5,5],并且我从转换部分中删除了负号。虽然我仍然得到一个象限,但它看起来更加圆润。http://i.imgur.com/UmGfins.png http://pastebin.com/6iK2rmbs - Portaljacker
修复了,我的球体部分没有正确地适应新的点。 - Portaljacker
很好,因为我没有发现你的粘贴有任何问题。 :-) 不过,你说的话是什么意思? - Scott Mermelstein
好的,我已经修复了立方体制作点位于{i,j,k} - 5,其中{i,j,k}在[0,11]之间。但是我没有在球形部分做{i,j,k} - 5。现在我只需要做动画部分,但那应该很简单。我为每个点从立方体到球体制作了一个方向向量,并将它们移动每一帧的一部分,直到百分比= 100。 - Portaljacker
啊,我明白了。我没有好好学习它,以为你是在使用你在立方体部分提到的点而不是重新创建新的点。你的方法可行,并且从长远来看可能更好。听起来你对动画有正确的想法,所以你应该没问题。 - Scott Mermelstein
1
我的意思是我没有直接使用它们,但我正在使用相同的坐标。我还在立方体数组中检查应该为空的点。顺便说一句,动画看起来非常流畅,我每帧移动点的2%。 - Portaljacker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接