名称 | ・・・・・・・ |
マトリックス(アフィン)関係サンプルセット 概略 |
ルーチン名 | ・・・・・・・ |
iniMat-----------マトリックスの要素を全て0に初期化する。(sub_set02-001) |
スクリプトNo | ・・・・・・・ | sub_set 02 |
DownLoad | ・・・・・・・ | scriptSet02.lzh(ANSI版) scriptSet02_u.lzh(UTF-8版) (右クリックのコンテクストメニューでダウンロードできます。windowsのみ) 関連するサブルーチンが全て含まれています。 圧縮されていますので解凍してreadme.htmlの説明を参考にして下さい。 |
概略 | ・・・・・・・ |
Shadeのマトリックスを操作する為のスクリプト集です。 |
使用前提 | ・・・・・・・ |
main()内のサンプルを実行する時は線形状の入ったパートを選択し、コメントアウトを解除してから実行してください。 |
依存関係 | ・・・・・・・ |
上記のルーチン名をクリックすると詳細情報の中に記述があります。 |
引数説明 | ・・・・・・・ |
スクリプト内に記述 詳細は上記のルーチン名をクリックして下さい。 |
戻り値説明 | ・・・・・・・ |
同上 |
変数説明 | ・・・・・・・ |
同上 |
全体の説明 | ・・・・・・・ |
全体を通じて共通して使用している変数mat(3,3)は4行4列の行列を配列に表わしたもの。 |
スクリプト | ||
option explicit call main() '/////////////////////テスト サンプルはここから///////////////////////////// 'サブルーチンmainはテスト用です。実行したいテストの「コメントアウト」を '解除して実行してください。 sub main() '線形状が入っているパートを選択してどれかひとつを実行してください 'X軸を中心に回転テスト ' dim mat0 ' mat0=GetTransMat() ' mat0=transMat(mat0,RoteMatX(xshade.pi/4)) ' ApplyTransMat(mat0) 'Y軸中心に回転テスト ' dim mat0 ' mat0=GetTransMat() ' mat0=transMat(mat0,RoteMatY(xshade.pi/4)) ' ApplyTransMat(mat0) 'Z軸中心に回転テスト ' dim mat0 ' mat0=GetTransMat() ' mat0=transMat(mat0,RoteMatZ(xshade.pi/4)) ' ApplyTransMat(mat0) '平行移動テスト ' dim mat0 ' dim Dt(2) ' mat0=GetTransMat() ' Dt(0)=100: Dt(1)=150: Dt(2)=50 ' mat0=transMat(mat0,MoveMat(Dt)) ' ApplyTransMat(mat0) '拡大縮小テスト ' dim mat0 ' dim Sc(2) ' mat0=GetTransMat() ' Sc(0)=0.7: Sc(1)=0.8: Sc(2)=0.9 ' mat0=transMat(mat0,ScaleMat(Sc)) ' ApplyTransMat(mat0) '位置ベクトル変化テスト '■このテストは2点からなる開いた線形状を入れたパートを選択して '実行してください。(2番目のポイントに変換をかけます。) ' dim mat0 ' dim vec0(3) ' dim newVec ' dim j ' for j=0 to 2 ' vec0(j)=Xshade.AnchorPoint(1,j) ' next ' newVec=transVecByMat(vec0,RoteMatZ(XShade.pi/6)) ' for j=0 to 2 ' XShade.AnchorPoint(1,j)=newVec(j) ' next '逆マトリックスで復帰テスト '■このテストは適当な線形状をパートに入れ、パートに何らかの変形 'を加えた上で実行してください。(計算誤差あり。) ' dim mat0 ' dim inv0 ' mat0=GetTransMat() ' inv0=invMat(mat0) ' mat0=transMat(mat0,inv0) ' applyTransMat(mat0) '変換のクリアテスト(逆マトリックスのテストと結果は同じ) '■このテストは適当な線形状をパートに入れ、パートに何らかの変形 'を加えた上で実行してください。 ' dim mat0 ' mat0=IdentityMat() ' applyTransMat(mat0) '複合変換テスト 'Y軸を中心にπ/3回転、X軸を中心にπ/3回転したものを平行移動する。 '角度の単位はラヂアンです。 ' dim mat0 ' dim Dt(2),Angle ' ' Dt(0)=100: Dt(1)=100: Dt(2)=100 ' Angle=XShade.pi/3 ' mat0=GetTransMat() ' mat0=transMat(mat0,RoteMatY(Angle)) ' mat0=transMat(mat0,RoteMatX(Angle)) ' mat0=transMat(mat0,MoveMat(Dt)) ' applyTransMat(mat0) end sub '/////////////////////テスト サンプルはここまで///////////////////////////// '//////////////////アフィン変換関連のプロシージャはここから////////////////// '---4行4列のマトリックス(アフィン変換用)の初期化 Sub iniMat(mat) '与えられたマトリックスの要素を全て0に初期化する。 '戻値--なし '引数-- ' mat :(in)(out)初期化するマトリックス[mat(3,3)形式] Dim i,j ':カウンタ用変数 for i=0 to 3 for j=0 to 3 mat(i,j)=0 next next end Sub Function IdentityMat() '単位行列(変換のない状態)を取得する。 '戻値--単位行列[mat(3,3)形式] '引数--なし Dim mat(3,3) ' :(in)(out) Dim i,j ':カウンタ用変数 for i=0 to 3 for j=0 to 3 if i=j then mat(i,j)=1 else mat(i,j)=0 end if next next identityMat=mat end Function '---アフィン変換用マトリックス(X軸周り回転移動) Function RoteMatX(Delta) 'X軸を中心に回転する時の変換マトリックスを取得する '戻値--4行4列の回転移動変換マトリックス[mat(3,3)]形式 '引数-- ' Delta :(in)X軸周の回転角度(ラヂアン) Dim mat(3,3) ':マトリックスを保持する変数 call iniMat(mat) mat(0,0)=1 mat(1,1)=cos(Delta) mat(1,2)=sin(Delta) mat(2,1)=-sin(Delta) mat(2,2)=cos(Delta) mat(3,3)=1 RoteMatX=mat end Function '---アフィン変換用マトリックス(Y軸周り回転移動) Function RoteMatY(Delta) 'Y軸を中心に回転する時の変換マトリックスを取得する '戻値--4行4列の回転移動変換マトリックス[mat(3,3)]形式 '引数-- ' Delta :(in)Y軸周の回転角度(ラヂアン) Dim mat(3,3) ':マトリックスを保持する変数 call iniMat(mat) mat(0,0)=cos(Delta) mat(0,2)=-sin(Delta) mat(1,1)=1 mat(2,0)=sin(Delta) mat(2,2)=cos(Delta) mat(3,3)=1 RoteMatY=mat end Function '---アフィン変換用マトリックス(Z軸周り回転移動) Function RoteMatZ(Delta) 'Z軸を中心に回転する時の変換マトリックスを取得する '戻値--4行4列の回転移動変換マトリックス[mat(3,3)]形式 '引数-- ' Delta :(in)Z軸周の回転角度(ラヂアン) Dim mat(3,3) ':マトリックスを保持する変数 call iniMat(mat) mat(0,0)=cos(Delta) mat(0,1)=sin(Delta) mat(1,0)=-sin(Delta) mat(1,1)=cos(Delta) mat(2,2)=1 mat(3,3)=1 RoteMatZ=mat end Function '---アフィン変換用マトリックス(平行移動) Function MoveMat(Dt) 'Dt方向に平行移動する時の変換マトリックスを取得する '戻値--4行4列の平行移動変換マトリックス[mat(3,3)]形式 '引数-- ' Dt :(in)x,y,z方向それぞれの移動距離[配列Dt(2)]形式 Dim mat(3,3) ':マトリックスを保持する変数 call iniMat(mat) mat(0,0)=1 mat(1,1)=1 mat(2,2)=1 mat(3,0)=Dt(0) mat(3,1)=Dt(1) mat(3,2)=Dt(2) mat(3,3)=1 MoveMat=mat End Function '---アフィン変換用マトリックス(スケール変換) Function ScaleMat(Sc) 'Sc方向に拡大縮小する変換マトリックスを取得する '戻値--4行4列のスケール変換マトリックス[mat(3,3)]形式 '引数-- ' Sc :(in)x,y,z方向それぞれの拡大縮小比率[配列Sc(2)]形式 Dim mat(3,3) ':マトリックスを保持する変数 call iniMat(mat) mat(0,0)=Sc(0) mat(1,1)=Sc(1) mat(2,2)=Sc(2) mat(3,3)=1 ScaleMat=mat End Function '---マトリックスの逆行列をもとめる。(Gauss-Jordan法) Function invMat(orgMat) '与えられたマトリックスの逆マトリックスを計算、取得する '戻値--4行4列の逆変換マトリックス[mat(3,3)]形式 '引数-- ' orgMat :(in)元のマトリックス dim B(),A() ':GaussJordan法で使用する一時マトリックス dim M,Q,P ':GausJordan法で使用する一時変数 dim Dummy,Max,s ':選択用に使う一時変数 dim i,j,k ':カウンタ用変数 M=4 'Shadeでは4次の行列なので固定。変更すればn次の計算も可 if UBound(orgMat,1)<>(M-1) or UBound(orgMat,2)<>(M-1) then invMat=false exit function '引数で渡された配列の次数が違うとき処理中止 end if redim B(M-1,M-1) redim A(M-1,2*M-1) For i=0 To M-1 A(i,M+i)=1 for j=0 to M-1 A(i,j)=orgMat(i,j) next Next 'Gauss-Jordan(PivotSelection) For K = 0 To M-1 '--Selection Area max=0 s=k for j=k to M-1 if abs(A(j,k))>Max then Max=abs(A(j,k)) s=j end if next if Max=0 then invMat=false '逆行列は存在しないので処理中止 exit function else for j=0 to 2*M-1 Dummy=A(k,j) A(k,j)=A(s,j) A(s,j)=Dummy next end if P = A(K, K) For j=k To 2*M-1 A(k,j)=A(k,j)/P Next For i=0 To M-1 If i<>k Then Q=A(i,k) For j=1 To 2*M-1 A(i,j) = A(i,j) - Q*A(k,j) Next end if Next Next 'Inverse Matrix For i=0 To M-1 For j=0 To M-1 B(i, j)=A(i, j + M) Next Next invMat=B End Function '--変換マトリックスの合成 Function transMat(mat1,mat2) '2つの変換マトリックスを合成する。Mat1をMat2で変換する '戻値--4行4列の合成変換マトリックス 配列[mat(3,3)]形式 '引数-- ' mat1 :(in)最初の変換マトリックス 配列[mat(3,3)]形式 ' mat2 :(in)次の変換マトリックス 配列[mat(3,3)]形式 Dim newMat(3,3) ':マトリックスを保持する変数 Dim i,j,k ':カウンタ用変数 for i=0 to 3 for j=0 to 3 newMat(i,j)=0 for k=0 to 3 newMat(i,j)=newMat(i,j)+mat1(i,k)*mat2(k,j) next next next transMat=newMat End Function '---座標データのマトリックスによる変換 Function transVecByMat(vec,mat) '位置ベクトル(または方向ベクトル等)vecに変換matをかける '戻値--変換後の位置ベクトル(または方向ベクトル等)配列[vec(2)]形式 '引数-- ' vec :(in)元の位置ベクトル(または方向ベクトル等)配列[vec(2)]形式 ' mat :(in)適用する変換マトリックス 配列[mat(3,3)]形式 Dim newVec(2) ':ベクトルを保持する変数 Dim i,j ':カウンタ用変数 for i=0 to 2 newVec(i)=0 for j=0 to 3 if j=3 then newVec(i)=newVec(i)+mat(j,i) else newVec(i)=newVec(i)+vec(j)*mat(j,i) end if next next transVecByMat=newVec end Function '---選択したパートのマトリックスを変数に取得する。 function GetTransMat() '現在選択しているパートの変換マトリックスを取得し変数matに格納する。 '戻値--4行4列のパートの変換マトリックス 配列[mat(3,3)]形式 '引数--なし dim mat(3,3) ':マトリックスを保持する変数 dim i,j ':カウンタ用変数 for i=0 to 3 for j=0 to 3 mat(i,j)=XShade.TransformationMatrix(i,j) next next GetTransMat=mat end Function '---選択したパートにマトリックスを適用する。 Sub ApplyTransMat(mat) '現在選択しているパートに変換マトリックスmatを適用する。 '戻値--なし '引数-- ' mat :パートに適用する変換マトリックス 配列[mat(3,3)]形式 dim i,j ':カウンタ用変数 for i=0 to 3 for j=0 to 3 XShade.TransformationMatrix(i,j)=mat(i,j) next next end sub /////////////////アフィン変換関連のプロシージャはここまで///////////////// |
||
使用例 | ||
個々のサブルーチンの詳細を見てください。 |