1

我是 C# 和 XNA 的新手。刚刚设法编写了一个生成三角形网格的类。但是有一个问题。我可以获得最大 27 个节点长度的三角形。在 28 它抛出 Out of memory 异常和在 31 -overFlow 异常。

我不明白它是如何溢出或内存不足的......试图计算所有这些内存值,但它们看起来非常小。

它只是受变量影响的节点数组。节点类不是很大:

浮动 x; 4 B 浮动 y;4 B 浮动 z;4 B int[] con; int[6] 4*6=24 B 字节传递;1 B 颜色 col; 32 乙 = 4 乙

            Total:  41B

创建三角形所需的节点序列和为 n(n+1)/2

28岁内存不足

28*29/2=406 个节点

总内存:

41*406 = 16646 B = 16.26 kB

31 时溢出:496 个节点为 19.9 kB

我确实读过关于“内存不足异常”的文章,结构大小比看起来要大,内存不足发生在 500MB 的大小......我的小三角形不可能达到如此巨大的大小。

这是我的全班:

class TriMatrix
    {
        int len;
        int Lenght;
        Node[] node;
        VertexPositionColor[] vertex;

        public class Node
        {
            public float x;
            public float y;
            public float z;
            public int[] con;
            public byte pass;
            public Color col;
            public Node(byte passable)
            {
                pass = passable;
                if (pass > 0)
                { col = Color.Green; }
                else
                { col = Color.DarkRed; }
                x = 0;
                z = 0;
                con = new int[6];
            }
        }

        public TriMatrix(int lenght)
        {
            len = lenght;
            Lenght = 0;
            byte pass;
            Random rnd = new Random();
            for (int i = 0; i <= len; i++)
            {
                Lenght += Lenght + 1;
            }
            node = new Node[Lenght];
            int num = 0;
            for (int i = 0; i < len; i++)
            {
                for (int j = 0; j <= i; j++)
                {

                    if (rnd.Next(0, 5) > 0) { pass = 1; } else { pass = 0; }
                    node[num] = new Node(pass);
                    node[num].x = (float)i - (float)j / 2.0f;
                    node[num].y = 0;
                    node[num].z = (float)j * 0.6f;
                    if (i < len - 1) { node[num].con[0] = num + i; } else { node[num].con[0] = -1; node[num].col = Color.Violet; }
                    if (i < len - 1) { node[num].con[1] = num + i + 1; } else { node[num].con[1] = -1; }
                    if (j < i) { node[num].con[2] = num + 1; } else { node[num].con[2] = -1; node[num].col = Color.Violet; }
                    if (j < i) { node[num].con[3] = num - i; } else { node[num].con[3] = -1; }
                    if (i > 0) { node[num].con[4] = num - i - 1; } else { node[num].con[4] = -1; }
                    if (i > 0) { node[num].con[5] = num - 1; } else { node[num].con[5] = -1; }
                    if (j == 0) { node[num].col = Color.Violet; }
                    num++;
                }
            }
        }

        public void Draw(Effect effect, GraphicsDevice graphics)
        {
            VertexPositionColor[] verts = new VertexPositionColor[3];
            int num = 0;
            for (int i = 0; i < len-1; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Apply();

                        verts[0] = new VertexPositionColor(new Vector3(node[num].x, node[num].y, node[num].z), node[num].col);
                        verts[1] = new VertexPositionColor(new Vector3(node[num + i + 1].x, node[num + i + 1].y, node[num + i + 1].z), node[num + i + 1].col);
                        verts[2] = new VertexPositionColor(new Vector3(node[num + i + 2].x, node[num + i + 2].y, node[num + i + 2].z), node[num + i + 2].col);
                        graphics.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, verts, 0, 1);

                        if ( j < i)
                        {
                            verts[0] = new VertexPositionColor(new Vector3(node[num].x, node[num].y, node[num].z), node[num].col);
                            verts[1] = new VertexPositionColor(new Vector3(node[num + i + 2].x, node[num + i + 2].y, node[num + i + 2].z), node[num + i + 2].col);
                            verts[2] = new VertexPositionColor(new Vector3(node[num + 1].x, node[num + 1].y, node[num + 1].z), node[num + 1].col);
                            graphics.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, verts, 0, 1);
                        }
                    }
                    num++;
                }
            }
        }
    }// endclass
4

1 回答 1

7

我假设您的错误位于此循环中(冒昧更正您的拼写):

for (int i = 0; i <= len; i++)
{
    Length += Length + 1;
}

在循环中,您将Length 自身的值加一。这实际上意味着您将Length每次迭代的值加倍,从而导致指数增长。

在最初的几次迭代中, 的值Length将是:1, 3, 7, 15, 31, 63, ...。我们可以推广这个序列,使得在迭代i时, 的值Length将是 2 i +1 -1。在第 28 次迭代中,这将是 536,870,911。在第 31 次迭代中,这将是 4,294,967,295。

编辑:正如您在下面的评论中提到的,计算三角形长度网格中元素数量的正确len方法是:

for (int i = 1; i <= len; i++)
{
    Length += i;
} 

这相当于求和1 + 2 + 3 + … + len,计算所谓的三角数。可以使用以下公式简洁地计算:

Length = len * (len + 1) / 2;

这个数字增长如此之大的原因是它是一个平方关系;对于一条边的长度n,你需要大约一半的面积

于 2012-10-12T21:16:56.357 回答