前回の宿題の答え

まずは前回の宿題の解答例から。斜交座標変換の式などは同じなので省いてあります。前回のサンプルの後半にこのプログラムを挿入してみてください。斜交座標上に歪んだ円が描かれます。

斜交座標2(宿題の答え).nako
θとは数値
線太さは2。線色は赤色
8,4をX1,Y1へ斜交座標変換
Iを0から36まで繰り返す
 θ=DEG2RAD(I*10)
 3*COS(θ)+5,3*SIN(θ)+4をX2,Y2へ斜交座標変換
 X1,Y1からX2,Y2へ線
 X1=X2;Y1=Y2
 0.05秒待つ
 

一次変換 on なでしこ

さてそれでは今回のお題目は一次変換です。一次変換という名前は、数Cで出てくるので知っている人もいるでしょう[*1]。教科書ではさらっと流されがちの一次変換を、前回の内容と関連させながら解説していきましょう。前回のプログラムの斜交座標変換を一般化して色々な斜交座標変換をできるようプログラムを作っていきます。

それではまずプログラム例です。

一次変換1.nako
線色は青色。線太さは1。# 描画命令の属性設定

Aとは行列。  # 変換行列
uとはベクトル。# 始点位置ベクトル
vとはベクトル。# 終点位置ベクトル
Iとは整数。  # カウンタ

#1
Aは『25,15
5,20』

#2
Iを0から10まで繰り返す
 u="0{~}{I}";v="11{~}{I}" #2−a
 Aでuを一次変換 #2−b
 Aでvを一次変換
 uからvへ線分を引く #2−c
 u="{I}{~}0"; v="{I}{~}11"
 Aでuを一次変換
 Aでvを一次変換
 uからvへ線分を引く

#3
# 線分UVを描く。u,vは2×1行列で指定する
●線分を引く({グループ}uから{グループ}vへ)
 母艦のu→要素[0],u→要素[1]からv→要素[0],v→要素[1]へ線


#4
■行列
 ・{配列}要素 #4−a
 ・データ ←行列設定 →行列取得 デフォルト #4−b
 ・行列設定(V)〜
  要素=VをCSV取得
 ・行列取得〜
  それは要素
 ・掛ける({行列}Mを)〜 #4−c
  Iとは整数。Jとは整数
  ARRとは配列=M→要素
  返り値とは配列
  #4−d
  Iを0から(ARRの表行数-1)まで繰り返す
   Jを0から(要素の表列数-1)まで繰り返す
    ARR[I]を反復、返り値[I][J]に対象*要素[回数-1][J]を直接足す。#4−e
  返り値を戻す
#5
■ベクトル +行列
 ・一次変換({行列}Mで)〜
  要素=自身→掛ける(M)
 

一次変換 on Math

それでは前回同様、数学的な解説から入りませう。数Cの教科書で、一次変換の説明は恐らく、書いてあったとしてもさらっとこんな感じで流されていると思います[*2]

一次変換f:P(x,y)→Q(X,Y) とは、X=ax+by Y=cx+dy で引き起こされる変換である。
これは、2×2行列Aによりq=Ap とも表わされる。

「ふーん」で終わりの典型的なパターンですね。しかも、線形代数を知っている人間からしてみると、なんじゃそりゃな説明になっています。まぁたかが高校の教科書なんてその程度ということですね。しかし、この式は前回見たのと同じ形をしています。分かりますでしょうか。ひとまず前回のおさらいしてみましょう。

一次(線型)結合
係数×変数の和の形の式
式で書けば蚤nxn
斜交座標変換
一次結合式 X=ax+by Y=cx+dy により引き起こされる変換
別の書き方で書くと、(x,y)→(ax+by,cx+dy)

ところで、数Cで行列というものを習いますね。習っていない人のために簡単に説明すると、行列とは、なでしこで言う所の二次元配列のことです。行列の掛け算は次のように定義されています。

l×m行列A=(aij)とm×n行列B=(bij)の積C=ABはl×n行列で、その各成分は
cij=蚤ik・bkj  [k=1〜m][*3]  …… ☆

では上の☆式でl=2,m=2,n=1として計算してみましょう。すると下記のように斜交座標変換と同じ、一次結合の式が出てきます。行列の積の定義で、各成分が一次結合の形になっているから当然ですね。

c11=a11b11+a12b21 (☆式でi=1,j=1とした)
c21=a21b11+a22b21 (☆式でi=2,j=1とした)
図:l=2,m=2,n=1とした場合の☆の式

成分毎に分けずにまとめて、行列として表すと図のようになります。見ての通り、これは前回の★式と同じ形をしていますよね。このように、行列とベクトルは違う物と見るよりも、1×n行列はn列ベクトルと、n×1行列はn行ベクトルと同一視した方が便利です。こう考えると、行ベクトルと列ベクトルを同一視してはいけない[*4]理由は、1×n行列とn×1行列が全く違うものだからだと説明できます。

プログラム解説

前置きが長かったですが、プログラムの解説に移りませう。今回はプログラムも長い目ですが、豪華なことにグループ変数の重要な機能がほぼ全て使われています。自分で言うのも何ですが、良いサンプルなので是非参考にしてください。

#1
前回の斜交座標変換と同じ変換を引き起こす行列。値の並びに注目!
#2
斜交座標軸を描画する部分
#2-a
u,vは2列ベクトル、つまり2×1行列で指定する必要がある。
#2-b
変換行列Aを左からu,vに掛ける。u,vは書き換えられる。
#2-c
#3の命令を呼び出す。斜交座標における線分 Y=I (0≦X≦11)
#3
点Uから点Vへ線分を引くユーザ定義命令。引数は2×1行列で指定する。
#4
グループで一般の行列を定義する。
#4-a
#4-bでセッターゲッターが設定されたメンバ変数「データ」で参照される実質上のデータ。
#4-b
セッターゲッターとデフォルトの設定。実質的な行列データは#4-aのメンバ「要素」を介してやり取りされる。
#4-c
自身に左から行列Mを掛け、返り値は配列型で返す。AをBに掛けるのように使う。メンバ関数のため、BにAを掛けるという語順では書けない。そもそも行列の積ABとBAは全く違う物だから、左右の順序には要注意。
#4-d
☆式の定義通り各成分の計算をする。配列のインデックスは0からなので、I=0〜l-1,J=0〜n-1で繰り返し、反復内の回数がk=1〜mに対応している。
#5
ベクトルはn×1行列と同一視して、行列とベクトルで掛け算をできるようにしたいので、行列をグループミックスする。ここで扱う一次変換は、行列ではなくベクトルに対する操作なので、「ベクトル」グループのメンバ関数として追加する。

まとめ

  • 斜交座標変換一次変換(の一種)
  • 行列を左から列ベクトルに掛けることで一次変換が引き起こされる
  • ⇒行列の積を定義することで、斜交座標変換できる

今回は内容を詰め込みすぎた所為で、何だか既に最終回まで行ってしまったような気分です。次回のネタが・・・ありません、いや、あるんですが、いや、すみません。とりあえず次回は、普通に今回の復習を丁寧にしていくことにしましょう。

#1の変換行列を他の2次正方行列に換え、別の一次変換では前回の宿題の円がどのように描画されるか確かめよ。

注釈

*1
実は大学数学における線形代数と切って離せない一次変換のうちのほんの一部が高校数学にも顔を出しているだけであって、高校数学の一次変換を理解しても線形代数の一次変換を理解したことにはなりません。しかし、高校数学の範囲でも一次変換のイメージがあれば、線形代数における一次変換の理解もしやすくなるでしょう。
*2
大学数学的により正確な定義を与えると、写像f:U→Vが一次写像であるとは、写像fが∀x,y∈U、∀a∈Kに対して以下を満たすことであると定義される。
  • f(x+y)=f(x)+f(y)
  • f(ax)=af(x)
*3
インデックスi,jは0から始まるのか、1から始まるのかという問題があります。ご存じの通りプログラミングでは配列のインデックスは0から始まる慣習ですが、数学の行列のインデックスは1から始まるという風に習います。しかし、実際には0から始まる方が便利なこともあるため、そもそも自然数に0を含めるという考え方も、計算機科学などの数学の分野で存在します。
*4
ただ直観に沿うように、1×n行列・n×1行列・n列ベクトル・n行ベクトルのいずれも、単純にnの元として同一視できるのも事実です。しかし普通は、nの元はn列の数ベクトルです。基本的に、大学で数ベクトルが出てきたら列ベクトルだと考えた方がいいでしょう。もっとも数ベクトル以外を扱うことの方が多いですが(ふふふふふ…)。