如何生成/计算十二面体的顶点?

时间:2012-05-05 08:59:36

标签: c# algorithm graphics

如何以算法方式生成十二面体的顶点?

我希望四面体的质心位于(0, 0, 0)

4 个答案:

答案 0 :(得分:7)

来自Wikipedia

  

以下笛卡尔坐标定义a的顶点   十二面体以原点为中心并适当缩放   导向:

     

(±1,±1,±1)

     

(0,±1 /φ,±φ)

     

(±1 /φ,±φ,0)

     

(±φ,0,±1 /φ)

     

其中φ=(1 +√5)/ 2是黄金比率(也写成τ)≈1.618。   边长为2 /φ=√5-1。包含球的半径为   √3。

我发现这个描述比一大块C#代码更简洁,更有用。 ( - :

答案 1 :(得分:4)

由于这个问题现在是谷歌搜索的最佳结果(数学的重复是#2),我想我也可以添加一些代码。

完整的控制台程序如下所示,应编译并运行,并且通常不言自明。

该算法基于Wikipedia article(谢谢你,mt_ from math.stackoverflow.com

此代码应为您打印正确的顶点列表。您关心的主要是方法Program.MakeDodecahedron,但不要只是复制和粘贴它,因为您需要修改它以使用您自己的顶点数据结构而不是我的模拟Vertex对象。您可以轻松使用XNA's Vector3,其构造函数与我的Vertex具有完全相同的签名。另外因为我的Vertex.ToString方法很麻烦,所以当与Vector3一起使用时,这个程序可能会打印一个丑陋的输出表,所以请记住这一点。

另外,请注意这是一个(不完美)演示。例如,如果生成许多四面体,您将不必要地重新计算每次调用的常量(例如黄金比例)。

使用XNA,尤其是使用Microsoft.Xna.Framework时,您还可以轻松地在3D中渲染十二面体。为此,您可以调整this tutorial的代码。

using System;
using System.Collections.Generic;

namespace DodecahedronVertices
{
    class Program
    {
        static void Main()
        {
            // Size parameter: This is distance of each vector from origin
            var r = Math.Sqrt(3);

            Console.WriteLine("Generating a dodecahedron with enclosing sphere radius: " + r);

            // Make the vertices
            var dodecahedron = MakeDodecahedron(r);

            // Print them out
            Console.WriteLine("       X        Y        Z");
            Console.WriteLine("   ==========================");
            for (var i = 0; i < dodecahedron.Count; i++)
            {
                var vertex = dodecahedron[i];
                Console.WriteLine("{0,2}:" + vertex, i + 1);
            }

            Console.WriteLine("\nDone!");
            Console.ReadLine();
        }

        /// <summary>
        /// Generates a list of vertices (in arbitrary order) for a tetrahedron centered on the origin.
        /// </summary>
        /// <param name="r">The distance of each vertex from origin.</param>
        /// <returns></returns>
        private static IList<Vertex> MakeDodecahedron(double r)
        {
            // Calculate constants that will be used to generate vertices
            var phi = (float)(Math.Sqrt(5) - 1) / 2; // The golden ratio

            var a = 1 / Math.Sqrt(3);
            var b = a / phi;
            var c = a * phi;

            // Generate each vertex
            var vertices = new List<Vertex>();
            foreach (var i in new[] { -1, 1 })
            {
                foreach (var j in new[] { -1, 1 })
                {
                    vertices.Add(new Vertex(
                                        0,
                                        i * c * r,
                                        j * b * r));
                    vertices.Add(new Vertex(
                                        i * c * r,
                                        j * b * r,
                                        0));
                    vertices.Add(new Vertex(
                                        i * b * r,
                                        0,
                                        j * c * r));

                    foreach (var k in new[] { -1, 1 })
                        vertices.Add(new Vertex(
                                            i * a * r,
                                            j * a * r,
                                            k * a * r));
                }
            }
            return vertices;
        }
    }

    /// <summary>
    /// A placeholder class to store data on a point in space. Don't actually use this, write a better class (or just use Vector3 from XNA).
    /// </summary>
    class Vertex
    {
        double x;
        double y;
        double z;

        public Vertex(double x, double y, double z)
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public override string ToString()
        {
            var s = String.Format("{0,8:F2},{1,8:F2},{2,8:F2}", x, y, z);

            return s;
        }
    }
}

由于我的代码可能非常详细和分散,我建议在支持for循环和其他代码结构折叠的东西中读取它。

答案 2 :(得分:2)

以P(0,0,0)为中心的十二面体的笛卡尔坐标和由半径为r的球体界定的顶点由下式给出:

P(±r /√3,±r /√3,±r /√3)

0(±r /(√3*φ),±(r *φ)/√3)

P(±r /(√3*φ),±(r *φ)/√3,0)

P(±(r *φ)/√3,0,±r /(√3*φ))

  

其中φ=(1 +√5)/ 2是黄金比率(也写成τ)≈1.618。

答案 3 :(得分:1)

这是一个以0顶点为中心的黎曼表面立体投影。 (对不起,我无法找到如何发布数学符号)

其中T是黄金比率,设a = 1 / T ^ 2,并且将复共轭对b + -ic定义为b = sqrt(5)/ 4和c = sqrt(3)/ 4。将这三个点旋转0度,120度和240度,这样你现在有九个点,全部在单位圆内。

使用地图z - &gt;将每个点映射到单位圆外的图像。 -1 / Z。在零和无穷大处添加一个点,您现在拥有了十二面体的所有顶点。

如果你想在球体上使用十二面体,可以使用通常的立体背景图,使单位圆圈进入赤道。通过刻录的通常过程,这也会给你一个以顶点为中心的立方体或四面体,但分别旋转约37.76或22.24度。