2016-04-02 54 views
1

我想將2d形狀輪廓附加到樣條曲線。在樣條中的某些點處,我會在圖像中顯示幾何體中奇怪的扭曲僞像。我怎樣才能避免使用Frenet-Frame方程?避免扭曲樣條曲線中的僞像[OpenGL,C++]

我爲正常,副法線和切線電流計算:

forward_tangent_vector = glm::normalize(pointforward - pointmid); 
backward_tangent_vector = glm::normalize(pointmid - pointback); 
second_order_tangent = glm::normalize(forward_tangent_vector - backward_tangent_vector); 
binormal = glm::normalize(glm::cross(forward_tangent_vector,second_order_tangent)); 
normal = glm::normalize(glm::cross(binormal, forward_tangent_vector)); 

//translation matrix 
T = glm::translate(T, pointmid); 

normal_axis = glm::vec3(0, 1, 0); 
rotationAxis = glm::cross(normal_axis, forward_tangent_vector); 
rotationAngle = glm::acos(glm::dot(normal_axis, forward_tangent_vector)); 

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

enter image description here

回答

3

你犧牲品的hairy ball theorem

在計算機圖形學中的一個常見問題是產生R3中的非零矢量與給定的非零矢量正交。對於所有非零矢量輸入,沒有單個連續函數可以做到這一點。這是毛球定理的必然結果。爲了看到這一點,將給定的向量看作球體的半徑,並且注意到找到與給定的向量正交的非零向量相當於找到非零向量,該向量與該球體接觸半徑。然而,多毛球定理說,不存在連續的函數,可以對球體上的每個點(即每個給定的矢量)進行此操作。

也看到這一點:http://blog.sigfpe.com/2006/10/oriented-fish-and-hairy-balls.html

問題就出在這兩條線:

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

forward_tangent_vector是共線與(0,1,0)rotationAxis變得(0,0,0)。這就是爲什麼你在管道中發生顛簸。

你需要做的而不是硬編碼(0,1,0),是取樣線的一階導數(速度/切線向量),取樣線的二階導數(加速度/法向量),並取其交叉乘積(副法線)。對這三個向量進行歸一化,得到所謂的Frenet-frame,這是一組圍繞樣條線的3個相互垂直的向量。注意你的樣條必須是C2連續的,否則你會得到類似的由二階導數中的不連續性(即加速度/法向量)引起的「扭曲」。

一旦你有了Frenet-frame,那麼在這個座標系下工作的基礎是一個簡單的基礎改變。不要混淆glm::rotate,只需將x,y,z單位向量作爲行(或列?我不確定GLM使用什麼約定...),那將是您的轉換矩陣。

+1

那麼問題是我不能確保曲線將C2連續。該曲線由可能或不可以提供C2連續曲線的算法生成。一旦我有了'tbn'矩陣,我該如何改變這些圓形輪廓的基礎(二維形狀)。 – jaykumarark

+0

只需將頂點與此矩陣相乘即可​​。另外不要忘了將原點翻譯成Frenet-frame的原點。 –