2011-02-23 15 views
5

私はOpenGLで遊んでいて、楽しい図形を描く方法を考えようとしています。パスに沿ったOpenGLチューブ

今、私はチューブに取り組んでいます。私はうまく直管を描くことができます:

void tube(GLfloat radius, GLfloat segment_length) { 
    glPolygonMode(GL_BACK, GL_NONE); 
    glPolygonMode(GL_FRONT, GL_FILL); 

    glPushMatrix(); { 
     GLfloat z1 = 0.0; 
     GLfloat z2 = segment_length; 

     GLfloat y_offset = 0.0; 
     GLfloat y_change = 0.00; 

     int i = 0; 
     int j = 0; 
     for (j = 0; j < 20; j++) { 
      glPushMatrix(); { 
       glBegin(GL_TRIANGLE_STRIP); { 
        for (i = 360; i >= 0; i--) { 
         GLfloat theta = i * pi/180; 
         GLfloat x = radius * cos(theta); 
         GLfloat y = radius * sin(theta) + y_offset; 

         glVertex3f(x, y, z1); 
         glVertex3f(x, y, z2); 
        } 
       } glEnd(); 
      } glPopMatrix(); 

      // attach the front of the next segment to the back of the previous 
      z1 = z2; 
      z2 += segment_length; 

      // make some other adjustments 
      y_offset += y_change; 
     } 
    } glPopMatrix(); 
} 

しかし、私は、チューブは、スパイラルのような任意の定義済みのパス、あるいはシンプルなラインをたどるようにする方法を考え出したていません。 y_changeを0.01などに変更すると、各チューブセグメントがy方向にさらに0.01オフセットされます。それは素晴らしいですが、どのように各セグメントをその方向に向けることができますか?言い換えれば、今のところ、各セグメントはすべて同じ方向を向くように描かれており、方向はチューブの方向ではありません(y_change = 0.01の場合、方向はわずかに上になります)。

私はどのように処理するかわかりません。私は前のセグメントと現在のセグメントの間にベクターを入れてベクターで遊んだことがありますが、それをどうしたらいいのか分かりません。

+1

あなたは(1など)で、レッドブックのトーラスの例を見たことがありますか? http://www.opengl.org/resources/code/samples/redbook/torus.c –

答えて

17

この考え方は、パス制御押出と呼ばれています。すなわち、基本的なn次元形状を持ち、それをn + 1次元の曲線に沿って押し出します。私はあなたの顔を読むことができます: "ああ、彼は何を言っていますか?"

ここでは粗い概要です。まず、通常はtと呼ばれる値を空間内の連続した滑らかな曲線にマップする関数が必要です。例えばスクリュー:アイデアがある

path(t): R → R³, t ↦ (a·sin(k·t), b·cos(k·t), c·t) 

は、そのパスに関連してあなたの頂点の位置を定義する座標局在塩基を見つける - それは、座標の一方が経路に平行に配向されていることを、意味をなしますあなたはそれが接しているのを見たいと思っています。

tangent(t): R → R³, t ↦ (k·a·cos(k·t), -k·b·sin(k·t), c) = d/dt path(t) 

したがって、この曲線の点tにおける局所座標系の原点と、曲線に沿ってポインティングのローカル基底ベクトルである:これは、その勾配を求めることによって行われます。

しかし、完全な3dベースを形成するには、2つの他のベクターが必要です。

normal(t): R → R³, t ↦ (-k²·a·sin(k·t), -k²·b·cos(k·t), 0) = d/dt tangent(t) = d²/dt² path(t) 

これが正常に呼び出されます。あなたが接線のカールを見つけることによって取得され、曲率に垂直な第2の基点を持っていることは通常は良い選択です。

通常の値と正の値とのクロス積をとって、ビトリノルムを得ることができる。私はあなたが運動としてそれを理解させるでしょう。

図形を曲線に沿って押し出すには、パスを分割して、単に範囲を選択してtを繰り返して、ローカルの起点を与えます。押し出された形状のポイントは、この起点パス(t)に相対的です。さんがあなたの形状は、その後のx-y平面でのポイントP_Nで構成されて言ってみましょう:

for t in [k..l]: 
    for p in P_n: 
     yield_vertex(path(t).x + binormal(t).x * p.x, 
         path(t).y + normal(t).y * p.y, 
         path(t).z) 

私はあなたがそれについて考えることで何かを学ぶ必要があり、すべての後に、OpenGLのにこれを適応する方法を考え出す、あなたにそれを残しておきます。もしあなたが明日までそれを解決できないなら、私は喜んであなたに解決策を教えてくれるでしょうが、それはあなた自身で物事を考え出すのはもっと楽しいことです。

+1

+1:優れた答え。部分的線形関数に興味があれば、v(n)(最後の点からこの点までのベクトル)とv(n + 1)(この点からのベクトル)の平均として接線を見つけることができます次のものへ)。 –

+0

素晴らしい、この答えに感謝します。私はこれに取り組むのにある程度の時間を費やすつもりです。私はどのような進歩をしたのかを教えてあげます(学校や職場では私のレクリエーション時間を消費するかもしれませんが)。 – gregghz

+0

ええ、私は数学のスキルがこれまでではないことを恐れています(問題の一部は、私があなたの表記を完全に理解していない可能性があります)。私はそれをOpenGLに変換することはできません。私が何をしているかは関係ありませんが、チューブセグメントは常に一方向に直面しています。 – gregghz

1

previously-solved problemに減らしてください。このAPIは、パスに沿って押出成形を行うことがある

+0

GLE押出ライブラリは少し古いですが、いくつかのバグがあり、いくつかのリワークが必要です。 – sancelot

関連する問題