【问题标题】:calculating the normals for each of the 8 vertices for my cube in c++在 C++ 中计算我的立方体的 8 个顶点中的每一个的法线
【发布时间】:2013-11-27 13:14:14
【问题描述】:

我正在努力计算 C++ 中我的立方体的 8 个顶点中的每一个的法线。 我认为它应该是这样的: - 计算立方体 6 个面中每个面的法线 - 每个顶点接触 3 个面,因此计算所有 3 个面的归一化向量

m_iNoVerts=8;
Vertex verts[8];
verts[0].position = XMFLOAT3(-1.0f, -1.0f,  1.0f);
verts[1].position = XMFLOAT3(-1.0f,  1.0f,  1.0f);
verts[2].position = XMFLOAT3( 1.0f, -1.0f,  1.0f);
verts[3].position = XMFLOAT3( 1.0f,  1.0f,  1.0f);
verts[4].position = XMFLOAT3(-1.0f, -1.0f, -1.0f);
verts[5].position = XMFLOAT3(-1.0f,  1.0f, -1.0f);
verts[6].position = XMFLOAT3( 1.0f, -1.0f, -1.0f);
verts[7].position = XMFLOAT3( 1.0f,  1.0f, -1.0f);

m_iNoIndices = 36;
int indices[36] = {0, 1, 2, // front face   0
                  1, 2, 3,

                  4, 5, 6,  // back face    1
                  5, 6, 7,

                  4, 5, 0,  // left face    2
                  5, 0, 1,

                  2, 3, 6,  // right face   3
                  3, 6, 7,

                  1, 5, 3,  // top face     4
                  5, 3, 7,

                  0, 4, 2,  // bottom face  5
                  4, 2, 6};

// Calculate the normals for each face
XMVECTOR result[6]; // cross product of vec1 and vec2 represents the normal of the face
XMVECTOR vec1;      // vec1 = B - A example first calc: B = verts[1] and A = verts[0]
XMVECTOR vec2;      // vec2 = C - B
int ii = 0;
for(int i = 0; i < 6; ++i)
{
    vec1.x = verts[indices[ii+1]].position.x - verts[indices[ii]].position.x;
    vec1.y = verts[indices[ii+1]].position.y - verts[indices[ii]].position.y;
    vec1.z = verts[indices[ii+1]].position.z - verts[indices[ii]].position.z;

    vec2.x = verts[indices[ii+2]].position.x - verts[indices[ii+1]].position.x;
    vec2.y = verts[indices[ii+2]].position.y - verts[indices[ii+1]].position.y;
    vec2.z = verts[indices[ii+2]].position.z - verts[indices[ii+1]].position.z;

    // calculate the cross product
    //result[i].x = (vec1.y * vec2.z) - (vec1.z * vec2.y);
    //result[i].y = (vec1.z * vec2.x) - (vec1.x * vec2.z);
    //result[i].z = (vec1.x * vec2.y) - (vec1.y * vec2.x);
    //result[i].w = 0;
    result[i] = XMVector3Cross(vec1, vec2);

    ii += 6;    // increasing the counter for the indices to jump to the next face 
}

// calculating the normals of each vertex
XMVECTOR normal[8];
// building the resulting vector of the 3 sites on each vertex
normal[0] = result[0] + result[2] + result[5];
normal[1] = result[0] + result[2] + result[4];
normal[2] = result[0] + result[3] + result[5];
normal[3] = result[0] + result[3] + result[4];
normal[4] = result[1] + result[2] + result[5];
normal[5] = result[1] + result[2] + result[4];
normal[6] = result[1] + result[3] + result[5];
normal[7] = result[1] + result[3] + result[4];

for(int i = 0; i < m_iNoVerts; ++i)
{
    normal[i] = XMVector3Normalize(normal[i]);  // normalization of the vector
    verts[i].normal.x = normal[i].x;
    verts[i].normal.y = normal[i].y;
    verts[i].normal.z = normal[i].z;
}

当我在调试器中检查法线时,值为 +-0.577.. 我老师给的价值观是

0.0  0.5  0.5
0.0  0.5  0.5
0.0 -0.5  0.5
0.0 -0.5  0.5
0.0  0.5 -0.5
0.0  0.5 -0.5
0.0 -0.5 -0.5
0.0 -0.5 -0.5

我做错了什么? 谢谢!

【问题讨论】:

  • 我很奇怪你老师的法线没有 X 分量。那么左边的顶点与右边的顶点有相同的法线吗?它们不应该以 35 度角相互指向吗?

标签: c++ math cube normals


【解决方案1】:

立方体面的法线很简单

[+-1, 0, 0],   [0,+-1,0],    [0,0,+-1]
(Left/Right), (Top/Bottom), (Front/Back)

顶点的 8 个法线,如果这样的概念有意义的话,在这种情况下甚至更简单地是 vertex - centervertex 它本身,因为中心位于原点。

这当然可以通过将人脸法线的8个线性组合相加并归一化来计算,得到

[+-1, +-1, +-1] / sqrt(3)

但从本质上讲,没有那么多可计算的......

【讨论】:

  • 对象坐标系没问题。但是我的立方体是在世界空间中定义的。如果我旋转整个物体,表面的法线会改变,还是?
  • 法线会相应改变。 “顶点”法线始终是一条从立方体中心到旋转角 == 顶点的线,但具有归一化的大小,这也是旋转不变的。当然,没有什么可以禁止您通过计算叉积和平均连接面的法线来计算法线。
【解决方案2】:
  1. 每个面只能由 3 个顶点定义。你有 6 个列表,为什么?

  2. 如果你这样做:vec1 = B - A; vec2 = C - A 那么在立方体的情况下它们将是正交的:)

  3. 法线可以按任何常数缩放,它们仍然是法线。将它们缩放为单位向量可能是惯例。为此,只需将每个除以其范数(向量长度)即可。 0.577 可能是 sqrt(1/3)。 (+-0.577, +-0.577, +-0.577) 是单位向量。

【讨论】:

  • 1.我有一个包含 6 个顶点的列表,以便稍后绘制立方体。每张脸有2个三角形。好吧,现在我知道 0.577 是从哪里来的了。我仍然想知道为什么我的老师没有 x 值。
猜你喜欢
  • 2013-09-02
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
相关资源
最近更新 更多