アプリケーションのジオメトリを扱う部分の設計に問題があります。特に、クラスの階層と交差のための個別のメソッドが必要です。
問題
階層は次のようになります。
- ジオメトリ
- メッシュ
- パラメトリック
- 箱
- 球体
そして、交差メソッドは次のようになります。
namespace intersections
{
bool intersection( const Box &, const Box &);
bool intersection( const Box &, const Sphere &);
}
これは非常に簡単です。std::vector
問題が発生するのは、すべてのジオメトリを 1 つの構造(または KD ツリーなど) にまとめて格納したい場合です。
そのためには、を使用する必要がありますstd::vector<Geometry*>
。ただし、このベクトルから読み取るとGeometry*
オブジェクトが取得されるため、適切な交差関数を呼び出す方法がありません。
問題の例:
std::vector<Geometry*> arrGeometry;
// add the elements
arrGeometry.push( new Box() );
arrGeometry.push( new Sphere() );
// ... some more code
// try to intersect them?
Geometry* g1 = arrGeometry[0];
Geometry* g2 = arrGeometry[1];
bool intersecting = intersections::intersection( g1, g2 ); //< As expected, this does
// not work
ジオメトリ オブジェクト内にアルゴリズムを実装した場合、問題はビジターと非常に奇妙な関数呼び出しのバウンスによって解決される可能性があります。
ただし、交差アルゴリズムは Geometry クラスの外に置きたいと思います。理由は次のとおりです。
どちらが所有権を持つべきかの決定を避けるため (例えば、ボックスと球の間の交差をどこに実装します
Box
かSphere
?)ジオメトリ オブジェクトが乱雑になるのを避けるために、ジオメトリに対してできることはすべてです。これは非常に多くのことです (ほんの数例を挙げると、ボクセル化、交点の計算、建設的なジオメトリ オペレータの適用など)。したがって、ロジックをデータから分離することは、ここでは非常に望ましいことです。
一方、特定のジオメトリを抽象化できるものがあるため、テンプレートの代わりに階層が必要です... (たとえば、std::vector
、または KD ツリー、または... に格納するため)。
これをどのように解決しますか?これに適したデザインパターンはありますか?私はいくつかのライブラリを見てみましたが、私はすでにそうであったことにもっと混乱しました...
最も簡単な方法 (時々使用される) は、RTTI (またはそれを偽造する) とダウンキャストを使用することですが、それは正確には維持できません... (新しいジオメトリを追加すると、すべてのコードで多くの switch ステートメントを変更する必要があります)。
何かご意見は?
よろしくお願いします。