2015-10-28 207 views
2

我想渲染圍繞3d曲線每個點的圓圈。基本上試圖爲曲線創建一個像結構一樣的管。但是如圖所示,圓的方向是錯誤的。下面是我計算frenet幀後計算圓形對象的模型矩陣。我哪裏錯了? 作爲參考,綠線是切線,藍色是正常的,紅色是正常。沿着3d曲線渲染圓形

view 1 view 2

Frenet Frame Calculations

glm::vec3 pointback = curve_points[i-1]; 
glm::vec3 pointmid = curve_points[i]; 
glm::vec3 pointforward = curve_points[i+1]; 

glm::vec3 forward_tangent_vector = glm::vec3(glm::normalize(pointforward - pointmid)) ; 
glm::vec3 backward_tangent_vector = glm::vec3(glm::normalize(pointmid - pointback)) ; 

glm::vec3 second_order_tangent = glm::normalize(forward_tangent_vector - backward_tangent_vector); 

glm::vec3 binormal = glm::normalize(glm::cross(forward_tangent_vector, second_order_tangent)); 

glm::vec3 normal = glm::normalize(glm::cross(binormal, forward_tangent_vector)); 

Model Matrix for Circle calculations

glm::mat3 tbn = glm::mat3(forward_tangent_vector,binormal,normal); 

glm::vec3 normal_axis = glm::vec3(0, 1, 0); 
//normal_axis = forward_tangent_vector; 

glm::vec3 circleNormal = glm::normalize(tbn * normal_axis); 
glm::vec3 rotationAxis = glm::cross(normal_axis, circleNormal); 
float rotationAngle = glm::acos(glm::dot(normal_axis, circleNormal)); 

R = glm::rotate(R, glm::degrees(rotationAngle), rotationAxis); 

T = glm::translate(T, pointmid); 

glm::mat4 Model = T*R; 
+2

圓圈必須建立從正常和副法向量。 –

+0

我不確定我是否關注你。你能否詳細說明一下? – jaykumarark

+0

看來,他們目前似乎是從切線和法線向量構建的。 –

回答

2

最簡單的方法來做到這一點是通過使用的Frenet-Serret幀,通常稱爲TBN幀或一TBN矩陣。方法如下:

  1. 在曲線上採樣兩個點。我們稱他們爲「當前」和「下一個」。
  2. 構建Frenet標架如下:

    vec3 T = normalize(next - current); 
    vec3 B = normalize(cross(T, next + current)); 
    vec3 N = normalize(cross(B, T)); 
    
  3. 計算你的2D圈,與此類似:

    float x = cos(angle); 
    float y = sin(angle); 
    
  4. 現在,使用Frenet標架計算出正確的方向:

    vec3 tangent = T; 
    vec3 normal = normalize(B * x + N * y); 
    vec3 vertex = current + B * x + N * y; // note: not normalized! 
    

一個易於理解的解釋可以在這裏找到: http://www.blackpawn.com/texts/pqtorus/

+1

謝謝!你的解釋和相關鏈接非常棒!只需要數學,我需要更好地理解這一點。 – jaykumarark

+0

如果您有解析曲線,無論是樣條曲線還是某種其他類型的數學函數,我認爲分析計算方向矢量會更好。考慮兩點之間的差異只是一個近似值。如果您有曲線的參數化表示,則方向矢量可以簡單地由座標的參數化函數的導數給出。 –

+0

@RetoKoradi:你說得對,分析解決方案更準確,但我認爲它不一定更好。例如,如果您正在構建網格,並且想要對其應用常規映射着色器,則需要沿曲面運行切線。在這篇文章中的算法將確保這是事實。更準確的切線和法線不會爲光照計算產生巨大的視覺差異,但您可能會看到正常的映射工件。所以這取決於你的用例,分析方法是否更好。 –