математика — вычисление нормалей для каждой из 8 вершин для моего куба в переполнении стека

Я изо всех сил пытаюсь вычислить нормали для каждой из 8 вершин для моего куба в c ++.
Я думал, что так должно быть:
— вычислить нормали для каждой из 6 граней куба
— каждая вершина касается трех граней, поэтому вычисляется нормализованный вектор для всех трех граней.

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

Что я делаю не так?
Спасибо!

1

Решение

Нормали граней куба просто

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

8 нормалей для вершины, если такая концепция имеет смысл, еще проще vertex - center или же vertex это само в этом случае, так как центр находится в начале координат.

Это, конечно, можно рассчитать путем сложения 8 линейных комбинаций нормалей лица и нормализации, давая

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

Но, по сути, не так много, чтобы рассчитать …

2

Другие решения

  1. Каждое лицо может быть определено всего 3 вершинами. У вас есть список 6, почему?

  2. Если вы делаете это: vec1 = B - A; vec2 = C - A тогда в случае куба они будут ортогональны 🙂

  3. Нормалы можно масштабировать по любой константе, они все равно будут нормальными. Вероятно, принято считать их единичными векторами. Чтобы сделать это, просто разделите каждый на его норму (длину вектора). 0,577 — это квадрат (1/3), вероятно. (+ -0,577, + -0,577, + -0,577) — единичные векторы.

0

По вопросам рекламы [email protected]