2010-12-21 86 views
3

我試圖沿樣條生成一個3d管。我有樣條曲線(x1,y1,z1 - x2,y2,z2 - 等)的座標,你可以在圖中看到黃色。在這些點上,我需要生成圈子,其頂點將在稍後的體育場連接。圓圈需要垂直於花鍵的兩條線段的「拐角」以形成正確的管。請注意,爲了便於說明,分段保持較低。矢量數學,找到兩個向量之間的平面上的coördinates

[顯然我不能張貼圖片,請在此鏈接查看圖像] http://img191.imageshack.us/img191/6863/18720019.jpg

我只要能在花鍵的每一個點來計算每個環的頂點,但它們都在同一平面上,即相同的角度。我需要他們根據他們的'腿'旋轉(例如,A & B是C)。

我一直在思考以下的這種過度和思想:

  • 兩條線段可以被看作是2個載體(在插圖& B)
  • 角落(在illustraton C)是其中需要頂點的環來計算
  • 我需要找到在其上的所有頂點的將駐留
  • 然後我可以使用該平面的平面(=矢量?),以從中心點,計算新的矢量,其是C
  • 和使用半徑*正弦和餘弦

但是發現他們的X,Y,Z,我對這個數學部分真的很困惑。我讀了點積,但是返回了一個標量,我不知道如何應用這種情況。

有人能指引我進入正確的方向嗎?

[編輯] 爲了給出一個位上的情況的詳細信息:

我需要構造浮筒,其中-in 3-組描述頂點位置,將被OpenGL ES的連接的一個緩衝器,給定另一個帶索引的緩衝區可以形成多邊形。

爲了給管子定形,我首先創建了一個浮點陣列,它們在三維空間中描述控制點。

然後,隨着段密度的變量,我將這些控制點傳遞給一個函數,該函數使用這些控制點創建一個CatmullRom樣條曲線,並以另一個浮點數組的形式返回它 - 描述catmull rom樣條的頂點。

在這些頂點的每一個上,我想要創建一個也可以在密度上不同的頂點環(每個環的平滑度/頂點數)。

所有以前的頂點(控制點和描述catmull ROM樣條曲線的點)都被丟棄。

只有形成管環的頂點纔會被傳遞給OpenGL,而OpenGL又會將這些頂點連接起來以形成最終的管子。

我儘可能創建catmullrom樣條曲線,並在其頂點位置創建環,但是,它們都處於同一個角度的平面上,而不是遵循樣條曲線路徑。

[編輯]

謝謝!

+0

請允許我歡迎你的堆棧Oveflow並記住三件事,我們通常在這裏做的:1)當你收到的幫助,儘量給它太**回答問題**在你的專業領域2)**閱讀常見問題解答!! ** 3)當您看到很好的問題和答案時,請使用灰色三角形**對其進行提升**,因爲系統的可信度基於用戶通過共享獲得的聲譽他們的知識。還請記住接受更好地解決您的問題的答案,如果有的話,**按複選標記** – 2010-12-22 02:25:36

+0

謝謝!由於我對這個論壇的專業知識和活動感到非常驚訝,我將註冊一個帳戶,並開始分享我的知識:)從2)開始.. – 2010-12-22 02:42:48

回答

10

假設有一個參數曲線,例如:

xx[t_] := Sin[t]; 
yy[t_] := Cos[t]; 
zz[t_] := t; 

其中給出: alt text

的切線向量,以我們的曲線是通過在每個方向上的衍生物形成的。在我們的例子

Tg[t_]:= {Cos[t], -Sin[t], 1} 

正交平面到矢量登場求解隱式方程:

Tg[t].{x - xx[t], y - yy[t], z - zz[t]} == 0 

在我們的情況是這樣的:

-t + z + Cos[t] (x - Sin[t]) - (y - Cos[t]) Sin[t] == 0 

現在我們發現在平面中的圓,以曲線爲中心。即:

c[{x_, y_, z_, t_}] := (x - xx[t])^2 + (y - yy[t])^2 + (z - zz[t])^2 == r^2 

解決兩個方程,你得到的方程爲界:

alt text

HTH!

編輯

而且通過借鑑了很多圈子,你可能會得到一個(效率不高)管:

alt text

還是有不錯的圖形3D庫:

alt text

編輯

既然你堅持:)這裏是一個程序來計算在路口的圈子。

a = {1, 2, 3}; b = {3, 2, 1}; c = {2, 3, 4}; 
l1 = Line[{a, b}]; 
l2 = Line[{b, c}]; 

k = Cross[(b - a), (c - b)] + b; (*Cross Product*) 
angle = -ArcCos[(a - b).(c - b)/(Norm[(a - b)] Norm[(c - b)])]/2; 
q = RotationMatrix[angle, k - b].(a - b); 
circle[t_] := (k - b)/Norm[k - b] [email protected] + (q)/Norm[q] [email protected] + b; 

Show[{Graphics3D[{ 
    Red, l1, 
    Blue, l2, 
    Black, Line[{b, k}], 
    Green, Line[{b, q + b}]}, Axes -> True], 
    ParametricPlot3D[circle[t], {t, 0, 2 Pi}]}] 

alt text

編輯

在這裏你有這種方法構建的網格。它不好看,恕我直言:

alt text

+0

+1僅用於漂亮的圖形。 – duffymo 2010-12-22 02:29:55

+0

我會upvote,但顯然我需要收穫我一些聲望;)在這種情況下,我正在建立一個頂點緩衝區管,最終需要使用OpenGL渲染。所以它確實是在我定義的樣條線中找到每個環的頂點。我真的很感謝你的答案,但我沒有看到如何將它鏈接到定義所提到的樣條的[x,y,z]數組。 – 2010-12-22 03:22:23

0

考慮到線段和向上矢量的交叉乘積,會給你一個與它們成直角的矢量(除非線段精確地指向上或下),我將它們稱爲水平線。將水平線和線段的交叉乘積給予另一個與線段成直角的矢量,另一個(我們稱之爲垂直)。然後,您可以通過lineStart + cos theta * horizo​​ntal + sin theta * vertical獲取圓形座標,以便在0 - 2Pi範圍內獲取θ。

編輯:要獲得兩個線段之間中點的點,請使用兩個線段向量的總和來查找平均值。

1

你需要看看在微分幾何菲奈特公式。有關螺旋的示例,請參見圖2.1。

Surfaces & Curves

1

我不知道你所選擇的語言是什麼,但是如果你講MatLab中已經有一些實現可用。即使你使用的是另一種語言,一些代碼可能足夠清晰,足以激發重新實現。

關鍵的一點是,如果您不希望在連接頂點時扭曲管,則無法在本地確定基準,但需要沿着曲線傳播它。由jalexiou提出的Frenet frame是一種選擇,但更簡單的東西也可以很好地工作。

在我成長的幾年裏(基於簡單的非Frenet傳播),我做了一個簡單的MatLab實現,名爲tubeplot.m,並且使用它搜索,我可以看到kth.se的Anders Sandberg已經完成了(re?)實現相同的名字,可在http://www.nada.kth.se/~asa/Ray/Tubeplot/tubeplot.html處獲得。

TubePlot.m illustration

編輯: 以下是在tubeplot.m簡單實現僞代碼。我發現它非常強大。

該計劃是傳播兩條法線沿着曲線ab,所以 ,在每個點的曲線ab和相切於曲線 上會形成正交基礎,這是「儘可能接近」到前一點使用的 基礎。 使用這個基礎,我們可以找到管的圓周上的點。

// *** Input/output *** 
// v[0]..v[N-1]: Points on your curve as vectors 
//    No neighbours should overlap 
// nvert: Number of vertices around tube, integer. 
// rtube: Radius of tube, float. 
// xyz: (N, nvert)-array with vertices of the tube as vectors 


// *** Initialization *** 
// 1: Tangent vectors 
for i=1 to N-2: 
    dv[i]=v[i+1]-v[i-1] 
dv[0]=v[1]-v[0], dv[N-1]=v[N-1]-v[N-2] 

// 2: An initial value for a (must not be pararllel to dv[0]): 
idx=<index of smallest component of abs(dv[0])> 
a=[0,0,0], a[idx]=1.0 

// *** Loop *** 
for i = 0 to N-1: 
    b=normalize(cross(a,dv[i])); 
    a=normalize(cross(dv[i],b)); 
    for j = 0 to nvert-1: 
     th=j*2*pi/nvert 
     xyz[i,j]=v[i] + cos(th)*rtube*a + sin(th)*rtube*b 

實現細節:您或許可以預先計算cossin加快東西。此外,爲了獲得強大的性能,您應該將輸入點融合得比例如0.1*rtube更接近,或者至少測試所有的dv向量都不爲零。

HTH