4 実装仕様
4.6 モデルの描画
4.6.10 NURBS 曲線
本節では,NURBS曲線の描画方法について説明する.
幾何情報
NURBS曲線の幾何情報を次に示す.
96
開閉区分とは,NURBS 曲線の開閉を指定する値である.開閉区分が 0 の場合,閉じた
NURBS曲線を描画する.開閉区分が1の場合,開いたNURBS曲線を描画する.制御点数
とは,作成するNURBS曲線全体で必要となる頂点の数である.階数とは,1次の NURBS 曲線を作成する際に必要となる頂点の数である.N次の階数で構成されるNURBS曲線をM 個作成する場合,制御点数は,(N-1)*M+1個になる.
位相情報
本システムでは,NURBS 曲線の位相情報として,頂点と稜線に関する情報を保持する.
NURBS曲線の位相情報を次に示す.
パラメータ パラメータ パラメータ
パラメータ 型型型型 説明説明説明説明
m_hEdge Hashtable 稜線に関する情報
本システムでは,ベジェ曲線同様,NURBS曲線の始点座標と終点座標を位相情報の頂点 に定義し,頂点と各頂点からなる稜線を保持する.NURBS曲線の位相情報を次に示す.
97
NURBS曲線の稜線と頂点の対応を次に示す.
稜線番号稜線番号
稜線番号稜線番号 頂点番号頂点番号頂点番号頂点番号 始点 始点 始点
始点 終点終点終点終点
1 a b
2 b c
描画方法
本システムでは,モデル空間上においてマウス操作で各制御点を指定することNURBS曲 線を描画する.NURBS曲線の描画手順を次に示す.
X軸 Y軸
(x,y,z)
Z軸
①制御点を指定
X軸 Y 軸
Z軸
②終点を指定
(ダブルクリック)
(x,y,z)
X軸 Y 軸
③曲線を描画
※階数はオプションで設定
98
本システムでは,まず,各制御点(X ,Y ,Z)をマウス操作で指定する.次に,終点(X ,Y ,Z)
をマウス操作(ダブルクリックイベントを使用)で指定する.最後に,各制御点からNURBS 曲線を描画する.ただし,各制御点の投影方法は,折線と同様の方法とする.また,NURBS 曲線の階数については,オプションで指定するものとする.さらに,NURBS曲線の描画の 際,ラバーバンド表示を行う.NURBS曲線のラバーバンド表示では,ベジェ曲線の同様に 制御点を頂点とする折線を描画する.
NURBS 曲 線 を 描 画 す る に は ,gluNewNurbsRenderer 関 数 ,gluNurbsProperty 関 数 , gluNurbsCurve 関 数 ,gluBeginCurve 関 数 と gluEndCurve 関 数 を 使 用 す る . ま ず , gluNewNurbsRenderer 関 数 を 使 用 し て ,NURBS オ ブ ジ ェ ク ト を 作 成 す る . 次 に ,
gluNurbsProperty関数を使用して,作成したNURBSオブジェクトの属性を設定する.そし
て,gluNurbsCurve関数を使用して作成したNURBSオブジェクトの形状を定義し,NURBS 曲線を描画する.最後に,gluBeginCurve関数とgluEndCurve関数を使用して描画するNURBS 曲線を設定する.
gluNewNurbsRenderer関数の定義を次に示す.
GLUnurbsObj* gluNewNurbsRenderer (void)
gluNewNurbsRenderer関数を使用することで,NUBRSオブジェクトを生成する.引数は
なく,戻り値は,作成したNURBSオブジェクトを参照するポインタである.
gluNurbsProperty関数の定義を次に示す.
void gluNurbsProperty ( GLUnurbs *nobj, GLenum property, GLfloat value)
gluNurbsProperty関数は,3つの引数をとり,戻り値はない.gluNurbsProperty関数の引数 を次に示す.
引数名引数名
引数名引数名 型型 型型 引数引数引数引数ののの意味の意味意味意味
nobj GLUnurbs* NURBSオブジェクトを示す定数
property GLenum 設定する属性を示す定数
value GLfloat Propertyで設定した属性の値
本システムでは,gluNurbsProperty関数の引数であるpropertyは,GLU_SAMPLING _TO
LERANCEを設定する.この場合,valueは,NURBS曲線の描画に使用する多角形の線分や
辺の最大の長さを定義する.そのため,valueの値が小さいほど滑らかな曲線を描画できる.
本システムでは,gluNurbsProperty関数の引数valueは,0.1を設定する.
99 gluNurbsCurve関数の定義を次に示す.
gluNurbsCurve( GLUnurbs* nobj, GLint nknots, GLfloat* knot, GLint stride, GLfloat* ctlarray, GLint order, GLenum type);
gluNurbsCurve関数は,7つの引数をとり,戻り値はない.gluNurbsCurve関数の引数を次
に示す.
引数名引数名
引数名引数名 型型型型 引数引数引数引数のののの意味意味意味 意味
nobj GLUnurbsObj* NURBSオブジェクトを示す定数
nknots Glint ノットベクトルの要素数
knot GLfloat* ノットベクトルの配列
stride GLint 1頂点に必要な要素数
ctlarray GLfloat* 制御点の配列
order GLint 制御点の数
type GLenum 曲線の型を示す定数
gluNurbsCurve関数の引数であるtypeにGL_MAP1_VERTEX_3を設定することで,NURBS 曲線を3次元空間上に描画する.
gluBeginCurve関数とgluEndCurve関数の定義を次に示す.
gluBeginCurve() 描画する NURBS 曲線 gluEndCurve()
gluBeginCurve 関数と gluEndCurve 関数は対になる.この 2 つの関数の間に設定した
gluNurbsCurve関数がNURBS曲線を描画する.NURBS曲線の描画方法の例を次に示す.
// Nurbs曲線の座標を格納する配列の生成
float *fCtlPoint;
// メモリの確保
fCtlPoint=new float[m_iNumber*4];
// 配列に値を格納するための繰り返し for(int i=0;i<m_iNumber*4;i++){
// 配列に値を格納
if(i%4 == 0) fCtlPoint[i] = (double)alX[i/4];
if(i%4 == 1) fCtlPoint[i] = (double)alY[i/4];
if(i%4 == 2) fCtlPoint[i] = (double)alZ[i/4];
if(i%4 == 3) fCtlPoint[i] = (double)m_alWeight[i/4];
100 }
// knotベクトルの値を格納する配列の生成
float *fKnot;
// knotベクトルのメモリ確保
fKnot=new float[m_alKnot->Count];
// knotベクトルに値を格納するための繰り返し
for(int i=0;i<m_alKnot->Count;i++){
// knotベクトルに値を格納 fKnot[i] = (double)(m_alKnot[i]);
}
// Nurbsオブジェクトの宣言
GLUnurbsObj *NurbsObj;
// Nurbsオブジェクト作成
NurbsObj = gluNewNurbsRenderer();
// サンプリング範囲の設定(小さいほど滑らか)
gluNurbsProperty(NurbsObj, GLU_SAMPLING_TOLERANCE,0.1);
gluNurbsCurve(NurbsObj, m_alKnot->Count, fKnot, 4, fCtlPoint, m_iOrder, GL_MAP1_VERTEX_4);