制作具有等距顶点的球体

时间:2014-07-29 10:02:40

标签: c# math unity3d geometry

我试图制作一个球形爆发射线以检查碰撞,但是根据每条射线击中的内容或位置发生特定的相互作用。因此,为什么我使用光线而不是更简单的东西,例如OverlapSphere

我正在寻找如何制作球体的原因是因为我可以使用相同的数学计算我的光线,让它们到达球体所在的顶点。但是我能找到制作球体的每一种方式都会让线条越来越接近极点,这很有意义,因为它很容易做到。但是你可以想象,它对我当前的项目没那么有用。

TL; DR: 如何制作具有等距顶点的球体?如果它不是完全等距离它的罚款,它只需要非常接近。如果发生这种情况,如果你能给出差异的多少,以及在适当的地方,那就太好了。

额外备注: 我已经查看了thisthis了,但数学是方式超过我的头脑,所以我一直在寻找的可能是&#?这一直只是一直盯着我。

6 个答案:

答案 0 :(得分:5)

你可以使用一个icosphere。由于顶点分布在等边三角形上,因此保证顶点等距。

enter image description here

要构建icosphere,首先制作一个二十面体,然后按照此article中的说明以小三角形递归地分割这些面。

答案 1 :(得分:5)

你是否意识到Unity 给你的 这个领域实际上是设计的

牢记这个目标?

也就是说,内置于Unity的球体的整个存在理由是,这些点是相当平滑的空间......大致等距,正如你所说的那样。

enter image description here

要在Unity中调出这样的球体,只需这样做:

enter image description here

然后,您可以立即访问顶点,如您所知

Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vv = mesh.vertices;
int kVerts=vv.Length
for (int i=0; i<kVerts; ++i)
  Debug.Log ... vv[i] 

请注意,您可以轻松检查它们所在的“球体的哪个部分”(例如)检查它们与“城市”(或其他)的距离,或者只检查(例如)z值以查看哪个他们所在的半球......等等。

此外...

请注意。关于你想要这样做的总体原因:

  

但是根据每条射线命中的内容或位置发生特定的相互作用

请注意,使用PhysX执行此操作并不容易。 (Unity中完全内置的游戏物理。)事实上,我从来没有看过碰撞而没有根据“击中的位置”做一些“具体”的事情。

例如,您可以获得联系人所在的位置http://docs.unity3d.com/ScriptReference/RaycastHit-point.html

值得注意的是,在休闲编程中可以写出接近PhysX性能的东西是绝对不可思议的。

我希望这会让事情变得更容易!

答案 2 :(得分:3)

  1. 将球体切成N个圆圈
  2. 计算它的周长
  3. 将其除以创建切片的相同角度
    • 这为您提供了顶点数
    • 以及圆圈内的角度步骤
  4. 投射光线
  5. 这是我用C ++ + OpenGL编写代码的方式:

    // draw unit sphere points (r=1 center=(0,0,0)) ... your rays directions
    int ia,na,ib,nb;
    double x,y,z,r;
    double a,b,da,db;
    na=16;                                  // number of slices
    da=M_PI/double(na-1);                   // latitude angle step
    for (a=-0.5*M_PI,ia=0;ia<na;ia++,a+=da) // slice sphere to circles in xy planes
        {
        r=cos(a);                           // radius of actual circle in xy plane
        z=sin(a);                           // height of actual circle in xy plane
        nb=ceil(2.0*M_PI*r/da);
        db=2.0*M_PI/double(nb);             // longitude angle step
        if ((ia==0)||(ia==na-1)) { nb=1; db=0.0; }  // handle edge cases
        for (b=0.0,ib=0;ib<nb;ib++,b+=db)   // cut circle to vertexes
            {
            x=r*cos(b);                     // compute x,y of vertex
            y=r*sin(b);
            // this just draw the ray direction (x,y,z) as line in OpenGL
            // so you can ignore this
            // instead add the ray cast of yours
            double w=1.2;
            glBegin(GL_LINES);
            glColor3f(1.0,1.0,1.0); glVertex3d(x,y,z);
            glColor3f(0.0,0.0,0.0); glVertex3d(w*x,w*y,w*z);
            glEnd();
            }
        }
    

    这就是它的样子:

    sphere vertexes

    • R,G,B线是球体坐标系轴X,Y,Z
    • 白色线条是您的顶点(白色)+方向(灰色)

    coordinate systems

    [注释]

    • 不要忘记包含math.h
    • 并用您的
    • 替换OpenGL内容

答案 3 :(得分:2)

如果你想要4个,6个,8个,12个或20个顶点,那么你可以得到与Platonic solid完全等距的顶点,这些顶点都适合球体。这些的实际坐标应该很容易获得。对于其他数量的顶点,您可以使用其他多面体并缩放顶点,使它们位于球体上。如果你需要很多积分,那么geodesic dome可能是一个很好的基础。 C60 bucky-ball可能是60分的良好基础。对于大多数这些,您应该能够找到可以从中提取坐标的3D模型。

答案 4 :(得分:0)

我认为控制球体上点的最简单方法是使用spherical coordinates。然后,您可以使用两个角度(rho和phi)和半径来控制球体周围点的位置。

围绕旋转球体均匀填充点的示例代码(为了好玩):

var time = 1; // Increment this variable every frame to see the rotation
var count = 1000;
for (int i = 0; i < count; i++)
{
    var rho = time + i; 
    var phi = 2 * Math.PI * i / count;
    var x = (float)(radius * Math.Sin(phi) * Math.Cos(rho));
    var z = (float)(radius * Math.Sin(phi) * Math.Sin(rho));
    var y = (float)(radius * Math.Cos(phi));
    Draw(x, y, z); // your drawing code for rendering the point
}

答案 5 :(得分:0)

正如一些答案已经提出的那样,使用基于二十面体的解决方案。这个来源非常容易(并且我已经写了好几次)但是我发现优秀的 Primitives Pro 插件在许多其他情况下非常方便,并且总是使用他们的球体而不是内置Unity one。

Link to Primitives Pro component

Primitives Pro options