N88-BASICで行列(matrix) (1回目)
2021/6/22(火)
N88-BASICで行列(matrix) (1回目)
(by ULproject for N88-BASIC, NL-BASIC)
点を併進、回転移動させる行列を作り
ワイヤーフレーム(線画)の立体を
ラジコンや自分が移動する
(1,2キーで切り替え、キー操作はプログラムの
最終行のコメントに書いています)
ように動かしていきます
今回は併進移動です
ここから、行列は大文字、
ベクトルとスカラーは小文字で表す事にします
行列は4×4(4行4列)とし、
ベクトルは3次元(4次元目は常に1)とします
またベクトル上部の矢印は省いています
行列の演算を2×2で説明します
行列Aのi行j列の成分をaijで
表します。
A=|a11 a12| B=|b11 b12|
|a21 a22| |b21 b22|
A+B=|a11+b11 a12+b12|
|a21+b21 a22+b22|
AB=|a11 a12||b11 b12|
|a21 a22||b21 b22|
=|a11b11+a12b21 a11b12+a12b22|
|a21b11+a22b21 a21b12+a22b22|
ベクトルとの積はp=(x,y)を列ベクトルにして
Ap=|a11 a12||x| = |a11x a12y|
|a21 a22||y| = |a21x a22y|
スカラー倍は
kA=k|a11 a12| = |ka11 ka12|
|a21 a22| = |ka21 ka22|
4×4の行列の場合
Σa1ibi1 (i = 1~4) = a11b11+a12b21+a13b31+a14b41
|a11 a12 a13 a14||b11 b12 b13 b14|
|a21 a22 a23 a24||b21 b22 b23 b24|
|a31 a32 a33 a34||b31 b32 b33 b34|
|a41 a42 a43 a44||b41 b42 b43 b44|
|Σa1ibi1 Σa1ibi2 Σa1ibi3 Σa1ibi4|
=|Σa2ibi1 Σa2ibi2 Σa2ibi3 Σa2ibi4|
|Σa3ibi1 Σa3ibi2 Σa3ibi3 Σa3ibi4|
|Σa4ibi1 Σa4ibi2 Σa4ibi3 Σa4ibi4|
となります
BASICでは行列Aの成分を、
DIM A(15)として、
|A(0) A(4) A( 8) A(12)|
|A(1) A(5) A( 9) A(13)|
|A(2) A(6) A(10) A(14)|
|A(3) A(7) A(11) A(15)|
で表す事にします
M=MAとM=AMは次のようになります。
*MULT
IF MODE THEN *MULT.AM
*MULT.MA
FOR IY=0 TO 3
M1 = M(IY): M2 = M(IY+4): M3 = M(IY+8): M4 = M(IY+12)
FOR IX=0 TO 12 STEP 4
M(IX+IY) = M1*A(IX) + M2*A(IX+1) + M3*A(IX+2) + M4*A(IX+3)
NEXT
NEXT
RETURN
*MULT.AM
FOR IX=0 TO 12 STEP 4
M1 = M(IX): M2 = M(IX+1): M3 = M(IX+2): M4 = M(IX+3)
FOR IY=0 TO 3
M(IX+IY) = A(IY)*M1 + A(IY+4)*M2 + A(IY+8)*M3 + A(IY+12)*M4
NEXT
NEXT
RETURN
M=MAはラジコンのような移動、
M=AMは自分が動く動作になり、
MODEの値で切替えています
どちらも物体を動かす方向になり、
M=AMでは自分が逆向きに動く
指定方法になりますので注意が必要です
プログラムではキー入力の所で、
M=AMの時は、符号を変える処理を
しています
ベクトルp=(x,y,z)、p1=(x',y',z')
Mを行列として上記式はp1=Mp
と表せます
今回のベクトルは3次元ですので
4次元目は無視(常に1と)します
BASICではP(ip,0~2)で、点番号ipの
点のx,y,z成分を表すことにします。
p1=Mpは次のようになります。
*PRODUCT
FOR IP=0 TO IN
FOR IY= 0 TO 2
P1(IP,IY) = M(IY)*P(IP,0)+M(IY+4)*P(IP,1)+M(IY+8)*P(IP,2)+M(IY+12)
NEXT
NEXT
RETURN
何もしない行列
A=MA=AMやp=Mpとなる行列Mを
単位行列といいます。
今回ベクトルに掛ける行列Mの
初期値になります
|1 0 0 0|
M=|0 1 0 0|
|0 0 1 0|
|0 0 0 1|
BASICでは以下のようにMを
単位行列にします。
*IDENTITY
M(0) = 1: M(4) = 0: M( 8) = 0: M(12) = 0
M(1) = 0: M(5) = 1: M( 9) = 0: M(13) = 0
M(2) = 0: M(6) = 0: M(10) = 1: M(14) = 0
M(3) = 0: M(7) = 0: M(11) = 0: M(15) = 1
RETURN
次の行列Aは点p(px,py,pz)を(x,y,z)
だけ平行移動させます
p' = Ap
|px'| |1 0 0 x||px| |px + x|
|py'|= |0 1 0 y||py|=|py + y|
|pz'| |0 0 1 z||pz| |pz + z|
|1 | |0 0 0 1||1 | |1 |
3×3の行列とベクトルの積で
平行移動を表す事ができないため、
4×4の行列を使います。
行列の左上の3×3の要素が回転を
表します
M=MA、p'=Mpとしたとき、点pを
x,y,zだけ移動させる事ができます。
M=MAはBASICでは、以下のようになります
*TRANSLATE
A(0) = 1: A(4) = 0: A( 8) = 0: A(12) = X
A(1) = 0: A(5) = 1: A( 9) = 0: A(13) = Y
A(2) = 0: A(6) = 0: A(10) = 1: A(14) = Z
A(3) = 0: A(7) = 0: A(11) = 0: A(15) = 1
GOSUB *MULT.MA
RETURN
NL-BASICとblg~.zip(mat001.bas)は
以下のリンクからダウンロードできます
Readme.txtを読んで遊んで下さい
次回