アプリ版:「スタンプのみでお礼する」機能のリリースについて

OpenGLで境界表現によってソリッドモデルを表現したいのですが、うまくできません。
ウィングドエッジデータ構造やHalf-Edgeデータ構造などのデータ構造を用いることによって表現する方法があるようなのですが、どのように実装したらよいでしょうか?

A 回答 (2件)

> OpenGLで境界表現によってソリッドモデルを表現したいのですが、うまくできません。



そりゃそうです.OpenGL が扱う幾何モデルは,
バラバラの頂点や多角形の集まりに過ぎません.

OpenGL とソリッドモデルはほとんど無関係で,
モデルを表示するときに OpenGL を使うというだけのことです.
実際,OpenGL にはソリッドモデルを扱うためのデータ構造も関数もありません.

OpenGL が行うことは,ぶっちゃけて言えば,3次元空間内の
多角形を座標変換して2次元平面に描画することだけです.
したがって OpenGL にとっては,複数の多角形の間の関係など
どうでもよくて,表示すべきすべての多角形を片っ端から
描画していけばいいわけです.

他方,境界表現では,頂点,稜線,面などの位相構造
(隣接関係,順序,向きなど) を管理する必要があります.
これらは OpenGL とは全く無関係なものです.


> どのように実装したらよいでしょうか

一例を挙げると,頂点,稜線,面をそれぞれオブジェクトとして,

・頂点は,それに接続する稜線と面へのポインタを,(立体の外側から見て左回りに)
 稜線 → 面 → 稜線 → 面 → … とつないだ双方向リストを持つ.

・面は,それを構成する頂点と稜線へのポインタを,(立体の外側から見て左回りに)
 頂点 → 稜線 → 頂点 → 稜線 → … とつないだ双方向リストを持つ.

・稜線は次のデータを持つ.
 ・両端に接続する頂点A,Bへのポインタ.
 ・立体の外側から見て,A→B方向に対して右側にある面へのポインタ.
 ・立体の外側から見て,B→A方向に対して右側にある面へのポインタ.


CGによる画像生成の流れ (同志社大学 知識情報処理研究室)
http://indy.doshisha.ac.jp/~watabe/cg/99/polygon …

情報組織論III Advanced Computer Graphics
http://graphics.c.u-tokyo.ac.jp/lectures/io3/not …
→ Half-Edge データ構造 (p.5)

産業情報システム (東大 生産システム工学研究室)
http://www.msel.t.u-tokyo.ac.jp/class/IMI/PDF/IM …
→ 境界表現によるソリッドモデル (p.21~)

厳密に正確な演算を用いたソリッドモデリングに関する研究
http://dspace.wul.waseda.ac.jp/dspace/bitstream/ …

「"境界表現" 面 稜線 頂点」で検索
http://www.google.co.jp/search?q=%22%E5%A2%83%E7 …

この回答への補足

たびたび申し訳ありません。

>頂点は,それに接続する稜線と面へのポインタを,(立体の外側から見て左回りに)
 稜線 → 面 → 稜線 → 面 → … とつないだ双方向リストを持つ.

・面は,それを構成する頂点と稜線へのポインタを,(立体の外側から見て左回りに)
 頂点 → 稜線 → 頂点 → 稜線 → … とつないだ双方向リストを持つ.

・稜線は次のデータを持つ.
 ・両端に接続する頂点A,Bへのポインタ.
 ・立体の外側から見て,A→B方向に対して右側にある面へのポインタ.
 ・立体の外側から見て,B→A方向に対して右側にある面へのポインタ.

これを実際に簡単な立体(立方体やリブなど)に対して実装するとどのようなプログラムになるのでしょうか?

補足日時:2007/06/19 22:59
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2007/06/19 16:20

> これを実際に簡単な立体(立方体やリブなど)に対して


> 実装するとどのようなプログラムになるのでしょうか?

作ったことはないけど,基本的なデータ構造は↓こんな感じかな.

typedef struct Vertex Vertex_t; // 頂点
typedef struct Edge Edge_t; // 稜線
typedef struct Face Face_t; // 面

// Vertex_t,Edge_t,Face_t へのポインタの双方向リストの要素
typedef struct VEFListElement VEFListElement_t;

struct VEFListElement {
 // 双方向リストを構成するポインタ
 VEFListElement_t *next; // 次の要素
 VEFListElement_t *previous; // 直前の要素

 union {
  Vertex_t *vertex;
  Edge_t *edge;
  Face_t *face;
 };
};

// Vertex_t,Edge_t,Face_t へのポインタの双方向リスト
typedef struct {
 VEFListElement_t *first; // 先頭要素を指す.
 VEFListElement_t *last; // 末尾要素を指す.
} VEFList_t;

struct Vertex {
 // 幾何データ
 double x, y, z; // 座標

 // 位相構造:この頂点に接続する稜線と面へのポインタの双方向リスト
 // (立体の外側から見て左回り順,稜線と面を交互に)
 VEFList_t edgesAndFaces;
};

struct Edge {
 // 位相構造

 Vertex_t *vertex[2]; // この辺の両端点

 // face[0]:立体の外側から見て,vertex[0] → vertex[1]
 //     方向に対して右側にある面へのポインタ.
 // face[1]:立体の外側から見て,vertex[1] → vertex[0]
 //     方向に対して右側にある面へのポインタ.
 Face_t *face[2];
};

struct Face {
 // 位相構造:この面を構成する頂点と稜線へのポインタの双方向リスト
 // (立体の外側から見て左回り順,頂点と稜線を交互に)
 VEFList_t verticesAndEdges;
};

このデータ構造に対してどういう操作をすればいいかは,
#1 で挙げた3番目の URL の「オイラー操作」を参考にしてください.
実装方法がわからなければ,双方向リストの勉強も必要.

上記データ構造以外に,1つの立体を構成する頂点,稜線,面をひとまとめに
するコンテナが必要.特に,同時に複数の立体を扱う場合は必須.

複雑な立体であっても,単連結な立体ならば基本的にこれでできると思う.
逆に穴が明いてたりすると,追加の情報が必要になるかも.

また,頂点数などが膨大な場合には,幾何学的処理 (最も近い頂点を
検索する,指定された領域内の頂点を列挙するなど) を効率良く行う
ために多次元木などのデータ構造も必要になる.
(その場合,計算幾何学も勉強してください.)
    • good
    • 0
この回答へのお礼

とても参考になりました。ありがとうございます。
実装するには足りない知識が多いようなのでまずは、その部分の勉強をしていきたいと思います。
ありがとうございました!

お礼日時:2007/06/21 15:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!