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

CDQuickHull2D.h

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

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