メインページ | ネームスペース一覧 | クラス階層 | 構成 | Directories | ファイル一覧 | ネームスペースメンバ | 構成メンバ | ファイルメンバ | 関連ページ

CDQuickHull3D.h

00001 #ifndef CDQUICKHULL3D_H
00002 #define CDQUICKHULL3D_H
00003 
00004 #include <Base/Affine.h>
00005 #include <Base/TQuaternion.h>
00006 #include <iosfwd>
00007 #include <vector>
00008 
00009 #define HULL_EPSILON 1e-6f  ///<    QuickHullで扱う最小の数値
00010 #define HULL_INFINITE 1e8f  ///<    QuickHullで扱う最大の数値
00011 
00012 //#define HULL_DEBUG        //  デバッグ出力
00013 #ifdef HULL_DEBUG
00014  #define HULL_DEBUG_EVAL(x) x
00015 #else
00016  #define HULL_DEBUG_EVAL(x)
00017 #endif
00018 
00019 namespace Spr{;
00020 
00021 /// QuickHullで作られる面
00022 template <class TVtx>
00023 class CDQHPlane{
00024 public:
00025     Vec3d normal;           ///<    面の法線
00026     double dist;            ///<    面の原点からの距離
00027     
00028     TVtx* vtx[3];           ///<    面を構成する頂点
00029     CDQHPlane* neighbor[3]; ///<    隣の面 vtx[0]-vtx[1] の隣が neighbor[0]
00030     bool deleted;           ///<    削除された面はtrue
00031     void Clear();           ///<    メモリクリア.使う前に呼ぶ.
00032     bool Visible(TVtx* p);  ///<    頂点 v から表側が見えるかどうか
00033     /// vの頂点番号を返す(0..2を返す).見つからなければ3を返す.
00034     int GetVtxID(TVtx* v);
00035     void CalcNormal();      ///<    法線ベクトルと距離を計算する.
00036     void Reverse();         ///<    表裏をひっくり返す.        
00037     /// 点との距離を計算する.精度を考慮して一番近い点で計算する.
00038     double CalcDist(TVtx* v);
00039     /// デバッグ用表示
00040     void Print(std::ostream& os) const;
00041 };
00042 
00043 /// 面のバッファ
00044 template <class TVtx>
00045 class CDQHPlanes{
00046 public:
00047     TVtx** vtxBeginInput;   ///<    残っている頂点の先頭
00048     TVtx** vtxEndInput;     ///<    残っている頂点の最後の次
00049     /// 頂点のVector
00050     class TVtxs: public std::vector<TVtx*>{
00051     public:
00052         void Print(std::ostream& os) const{
00053             for(TVtxs::const_iterator it = begin(); it != end(); ++it){
00054                 (*it)->Print(os);
00055             }
00056         }
00057     };
00058     typedef CDQHPlane<TVtx> CDQHPlane;
00059 
00060     CDQHPlane* buffer;      ///<    バッファへのポインタ new する.
00061     int len;            ///<    バッファの長さ
00062     CDQHPlane* begin;       ///<    最初の面
00063     CDQHPlane* end;     ///<    最後の面の次
00064     TVtx** vtxBegin;    ///<    残っている頂点の先頭
00065     TVtx** vtxEnd;      ///<    残っている頂点の最後の次
00066     int nPlanes;        ///<    面の数
00067     unsigned size();    ///<    使用済みバッファのサイズ
00068     CDQHPlanes(int l);
00069     void Clear();
00070     ~CDQHPlanes();
00071     /** bからeまでの頂点から凸包を作る.使用した頂点はbからvtxBegin,
00072         使用しなかった頂点は,vtxBeginからeに移動する. 
00073         beginからendは頂点を3つ含む面になる.それらの面うち凸包に使われた面
00074         は CDQHPlane::deleted が false になっている.   */
00075     void CreateConvexHull(TVtx** b, TVtx** e);
00076     void Print(std::ostream& os) const;
00077 
00078 private:
00079     /** 最初の凸多面体=2枚の三角形(表裏)を作る.
00080         できるだけ大きい3角形を作ると効率が良いので,x最大,x最小,
00081         2点が作る直線から一番遠い頂点で3角形を作る.
00082         使用した頂点は,vtxBeginの手前に移動して,頂点リストからはずす.
00083     */
00084     void CreateFirstConvex();
00085     /** horizon を作る. cur が穴をあける面,vtx が新しい頂点.
00086     rv にhorizonを辺に持つ3角形を1つ返す.*/
00087     void FindHorizon(TVtx*& rv, CDQHPlane* cur, TVtx* vtx);
00088     /** 頂点とhorizonの間にコーンを作る.*/
00089     void CreateCone(TVtx* firstVtx, TVtx* top);
00090     /** 一番遠くの頂点を見つける.見つけたらそれを頂点リストからはずす  */
00091     bool FindFarthest(CDQHPlane* plane);
00092     /*  外側 内側 の順に並べる.
00093         外側の終わり=内側の始まりが inner  */
00094     TVtx** DivideByPlaneR(CDQHPlane* plane, TVtx** start, TVtx** end);
00095     TVtx** DivideByPlane(CDQHPlane* plane, TVtx** start, TVtx** end);
00096     /** 一つの面に対する処理を行う.一番遠くの頂点を見つけ,
00097         地平線を調べ,コーンを作り,内部の頂点をはずす.*/
00098     void TreatPlane(CDQHPlane* cur);
00099 };
00100 
00101 /// 頂点クラスの例
00102 class CDQHVtx3DSample{
00103 public:
00104     ///@name QuickHullが使用するメンバ.必須.
00105     //@{
00106     /** QuickHullアルゴリズム用ワークエリア.
00107         一番遠い頂点から見える面を削除したあと残った形状のエッジ部分
00108         を一周接続しておくためのポインタ.
00109         頂点→面の接続.    面→頂点は頂点の並び順から分かる.  */
00110     CDQHPlane<CDQHVtx3DSample>* horizon;
00111     ///  頂点の位置
00112     Vec3f GetPos() const;
00113     //@}
00114     /// 位置の設定
00115     void SetPos(Vec3f p);
00116 public:
00117     Vec3f dir;      ///<    原点からの向き
00118     float dist;     ///<    原点からの距離
00119 public:
00120     int id_;
00121 
00122     /// デバッグ用表示
00123     void Print(std::ostream& os) const;
00124 };
00125 
00126 }
00127 
00128 #endif

Springheadに対してSun Apr 16 01:57:49 2006に生成されました。  doxygen 1.4.1