2013-11-27 94 views
1

我正在努力爲C++中的立方體計算8個頂點中的每個頂點的法線。 我想應當去這樣的: - 計算法線爲每個立方體 的6個面的 - 每個頂點接觸3個面,所以計算所有的3個面在C++中爲我的立方體計算8個頂點中的每個頂點的法線。

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 

請告訴我的事情我做錯了嗎? 謝謝!

+2

很奇怪我的老師的法線沒有X分量。那麼左邊的頂點與右邊的頂點具有相同的法線?他們不應該以35度的角度彼此指向嗎? – Kevin

回答

2

立方體的面的法線是簡單

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

8個法線爲頂點,如果這樣的概念是有意義的,甚至更簡單地vertex - centervertex在此它自因爲中心在原點。

這可以通過將面法線和規範化的8個線性組合計算,當然,給

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

但在本質上,有沒有那麼多的計算...

+0

多數民衆贊成在物體座標系統。但是我的魔方在世界空間中定義。如果我旋轉整個事物,表面的法線會改變,或者? – p4si

+0

法線將相應改變。 「頂點」法線始終是從立方體的中心朝向旋轉的拐角==頂點的線,但具有歸一化的量值,其也是旋轉不變的。當然,通過計算交叉產品和平均連接面的法線,沒有任何東西可以用來計算法線。 –

0
  1. 每個面只能由3個頂點定義。你有6個清單,爲什麼?

  2. 如果你這樣做:vec1 = B - A; vec2 = C - A然後在立方體的情況下,他們將是正交:)

  3. 法線可以通過任何常數進行縮放,他們仍然是正常的。將它們擴展爲單位向量可能是慣例。要做到這一點,只需將它們的標準(向量長度)分開即可。可能是0.577 sqrt(1/3)。 (+ -0.577,+ -0.577,+ -0.577)是單位向量。

+0

1.我有一個6個頂點的列表,稍後再繪製立方體。每張臉都有2個三角形。好的,現在我知道0.577從哪裏來。我仍然想知道爲什麼我的老師沒有x值。 – p4si