戻る

名称 ・・・・・・・

マトリックス(アフィン)関係サンプルセット 概略

ルーチン名 ・・・・・・・

iniMat-----------マトリックスの要素を全て0に初期化する。(sub_set02-001)
IdentityMat-------単位行列(変換のない状態)を取得する。(sub_set02-002)
RoteMatX--------アフィン変換用マトリックス(X軸周り回転移動)(sub_set02-003)
RoteMatY--------アフィン変換用マトリックス(Y軸周り回転移動)(sub_set02-004)
RoteMatZ--------アフィン変換用マトリックス(Z軸周り回転移動)(sub_set02-005)
MoveMat---------アフィン変換用マトリックス(平行移動)(sub_set02-006)
ScaleMat---------アフィン変換用マトリックス(スケール変換)(sub_set02-007)
InvMat-----------マトリックスの逆行列をもとめる。(sub_set02-008)
transMat---------変換マトリックスの合成(sub_set02-009)
transVecByMat---座標データのマトリックスによる変換(sub_set02-010)
GetTransMat-----選択したパートのマトリックスを変数に取得(sub_set02-011)
ApplyTransMat---選択したパートにマトリックスを適用(sub_set02-012)

スクリプトNo ・・・・・・・ sub_set 02
DownLoad ・・・・・・・ scriptSet02.lzh(ANSI版)
scriptSet02_u.lzh(UTF-8版)
(右クリックのコンテクストメニューでダウンロードできます。windowsのみ)
関連するサブルーチンが全て含まれています。
圧縮されていますので解凍してreadme.htmlの説明を参考にして下さい。
概略 ・・・・・・・

Shadeのマトリックスを操作する為のスクリプト集です。
パートにある変換を持ったマトリックスを適用させたり、マトリックスを掛け合わせて別のマトリックスを作り出したりする処理ルーチンを集めまています。

使用前提 ・・・・・・・

main()内のサンプルを実行する時は線形状の入ったパートを選択し、コメントアウトを解除してから実行してください。

依存関係 ・・・・・・・

上記のルーチン名をクリックすると詳細情報の中に記述があります。

引数説明 ・・・・・・・

スクリプト内に記述 詳細は上記のルーチン名をクリックして下さい。

戻り値説明 ・・・・・・・

同上

変数説明 ・・・・・・・

同上

全体の説明 ・・・・・・・

全体を通じて共通して使用している変数mat(3,3)は4行4列の行列を配列に表わしたもの。
また、vec(2)は位置ベクトルや方向ベクトルを表わし、各要素は 0:x, 1:y, 2:z 方向を意味する。

 
スクリプト
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

/////////////////アフィン変換関連のプロシージャはここまで/////////////////

使用例
個々のサブルーチンの詳細を見てください。

戻る