内容:
1.1 規格化座標と二次元グリッド番号
1.2 メッシュブロック
1.3 規格化座標から 実座標への射影
1.4 サンプルコード1(C++)
簡単な二次元のメッシュ分割について議論します。
まず、一般の四辺形で表される二次元ブロック内を分割する場合を考えます。
多角形ブロックへの拡張は後に行います。
ブロック内を三角形メッシュで分割する方法は多く発表されていますので、ここでは四辺形要素で分割する方法を考えます。
但し、条件として四辺形ブロックの各辺に関する分割数は与えられているものとして内部を分割するものとします。
問題を簡単にするため、四辺形ブロックを位相幾何学的に分割します。 ここでは、分割の対象となる四辺形ブロックが(0,0)-(1.0)-(1,1)-(0,1)の頂点座標を持つと規定します。 以下、これを規格化された四辺形ブロックと呼びます。
規格化された四辺形ブロックには、あらかじめ各辺がn1,n2,n3,n4 に分割されていると仮定します。
それぞれ、対辺の分割数の多い方の辺を元にしてグリッッド(赤四角点)を生成します。
このとき、規格化座標で一致する対辺の分割点は必ず一致させます。(青三角点)
分割プログラムを作るときは、このグリッド番号を二次元的なインデックスを持つ配列にします。
つまり、C++ で書きますと
class Grid {
public:
double x,y;
void set(cost double _x,const double _y) { x=_x; y=_y; }
}
Grid theGrids[20][20];
......
theGrids[0,0].set( 0.0,0.0 );
.......
こうすることにより、各辺にあるグリッド番号を簡単に見つけることができます。
たとえば、グリッドtheGrids[i][j]の両端点は
theGrids[0][j],theGrids[imax][j] と theGrids[i][0],theGrids[i][jmax]
になります。 ここで、 imax = Max(n2,n4), jmax = Max(n1,n3) です。
1.2 メッシュブロック
次の段階では、このブロックを青三角を頂点とした6個の小ブロックに分割します。
このとき、青四角も頂点として追加します。
要素分割を、外側の辺分割としてそのまま、採用しますと、左図のようになります。
不整合をなくすためには、ブロック間の中間節点を処理する必要があるのがわかります。
三角分割パターンを許すならば、分割は比較的単純で、たとえば左図のようなパターンになります。
左図の分割法は、小ブロック内で対辺の分割の違いを、分割数の少ないブロック側で三角形要素を採用し、整合させる方法です。
規格化座標から実座標へは、
が定まれば、決めることができます。
計算方法はいくつかありますが、以下のような制約条件や評価関数を設けるが妥当でしょう。
1.に関しては守らねばならない制約条件です。 2. , 3. に関しては分割を評価する評価関数を作成する上での指針となります。
もっとも、簡単な方法は、規格化座標で、各辺の分割を等差、等比あるいは任意で与え、対辺を互いに直線で結び、その交点を内側の点とすることです。
その規格化座標での内側交点の座標を、直接射影して実交点を求めます。
射影に使う座標変換としては、
1.4 サンプルコード1(C++)
1の方法は、一方向の情報しか使用しないのですが、次のように非常に簡単に計算できます。 その結果もまずまずです。
// V2.h ヘッダーファイルに定義 // Copyright 2001 (c) Shift Lock Corporation // 二次元ベクトルクラス class V2 { public: double x,y; // コンストラクタとデストラクタ V2():x(0),y(0) {} V2( const double _x, const double _y=0 ):x(_x),y(_y) {} virtual ~V2() {} // セット void setXY( const double _x=0,const double _y=0 ) { x=_x; y=_y; } // コピーコンストラクタ V2( const V2& a ) { copy(a); } // コピー void copy( const V2& a ) { if( this!=&a ) { x=a.x; y=a.y; } } // 代入演算子 const V2 operator = ( const V2& a ) { copy(a); return *this; } // 加算 friend V2 operator + ( const V2& a, const V2& b ) { return V2( a.x + b.x, a.y + b.y ); } // 減算 friend V2 operator - ( const V2& a, const V2& b ) { return V2( a.x - b.x, a.y - b.y ); } // スカラー倍 V2 operator * ( double s ) const { return V2( x*s, y*s ); } }; // .cpp ファイルに定義 #include "V2.h" int main() { V2 vN[5][8];// 規格化座標 // ここの間で5X8 の規格化座標を作る V2 vR[5][8];// 実座標 // ここの間で実座標は基準となる方向の相対する2辺の座標のみ与えておく // x方向を基準とするときは、辺2と辺4の分割実座標を与える。 // y方向を基準とするときは、辺1と辺3の分割実座標を与える。 for( int j=1;j<7;j++ ) { V2 vL2 = vR[4][j]; // 辺2の分割実座標 V2 vL4 = vR[0][j]; // 辺4の分割実座標 for( int i=1;i<4;i++ ) { V2 vP = vL2 - vL4; vP = vP*vN[i][j].x; // 規格化座標のx成分のみ使用 vP = vP + vL4; vR[i][j] = vP; } } for( j=0;j<8;j++ ) for( int i=0;i<5;i++ ) printf("%lg,%lg \n",vR[i][j].x,vR[i][j].y ); return 0; }