AviUtlスクリプトと和解せよ その3 コード解読編1
ライン(移動軌跡)のコードを見る会
前回より、AviUtl拡張編集Pluginで入手出来るスクリプトのコードについては自由に扱ってよいと解釈した。という訳でまずはドン。
コード
--track0:ライン幅,2,200,16 --track1:先端,0,500,48 --track2:固定速度,0,100,0,0.01 --track3:描画間隔,0,400,10 --dialog:色/col,col=0xffffff;先端図形/fig,fig="三角形";先端位置補正(%),f_pos=70;最小間隔(dot),min_step=2;主線描画(%),c_size=100;補助描画(%),l_size=0; -- ライン部分 base_x = obj.getvalue("x") base_y = obj.getvalue("y") obj.load("figure","円",col,obj.track0) obj.effect() obj.ox = obj.ox-base_x obj.oy = obj.oy-base_y w2 = obj.w/2 h2 = obj.h/2 t = 0; f = 0; l = 0; n = 1; d = 0 s = w2*obj.track3/50; if( s < min_step ) then s = min_step end if( s < 1 ) then s = 1 end ex = obj.getvalue("x",0) ey = obj.getvalue("y",0) x0 = ex y0 = ey while( t < obj.time ) do r = s while( r > 0 ) do if( l <= 0 ) then if( t >= obj.time ) then break end sx = ex sy = ey f = f+1 t = f/obj.framerate ex = obj.getvalue("x",t) ey = obj.getvalue("y",t) l = math.sqrt((ex-sx)*(ex-sx)+(ey-sy)*(ey-sy)) n = l end if( l > r ) then d = d+r l = l-r r = 0; x1 = ex+(sx-ex)*l/n y1 = ey+(sy-ey)*l/n else d = d+l r = r-l l = 0 x1 = ex y1 = ey end if( obj.track2 > 0 ) then if( t >= obj.totaltime ) then break end t = d/(obj.framerate*obj.track2) elseif( l > 0 ) then t = (f-l/n)/obj.framerate end end if( c_size > 0 ) then lx = w2*c_size/100 ly = w2*c_size/100 obj.drawpoly(x0-lx,y0-ly,0,x0+lx,y0-ly,0,x0+lx,y0+ly,0,x0-lx,y0+ly,0, 0,0,obj.w,0,obj.w,obj.h,0,obj.h) end if( l_size > 0 ) then r = math.atan2(y1-y0,x0-x1) lx = math.sin(r)*w2*l_size/100 ly = math.cos(r)*w2*l_size/100 obj.drawpoly(x0-lx,y0-ly,0,x0+lx,y0+ly,0,x1+lx,y1+ly,0,x1-lx,y1-ly,0, 0,h2,obj.w,h2,obj.w,h2,0,h2) end x0 = x1 y0 = y1 end if( obj.track2 > 0 ) then t = (f-l/n)/obj.framerate else t = obj.time; x0 = base_x y0 = base_y end obj.drawpoly(x0-w2,y0-h2,0,x0+w2,y0-h2,0,x0+w2,y0+h2,0,x0-w2,y0+h2,0, 0,0,obj.w,0,obj.w,obj.h,0,obj.h) obj.ox = obj.ox+base_x obj.oy = obj.oy+base_y -- 先端部分 if( obj.track1 > 0 ) then obj.load("figure",fig,col,obj.track1) obj.effect() obj.ox = obj.ox-base_x obj.oy = obj.oy-base_y r = 0 l = 4*4 s = t e = t t = 0.5/obj.framerate while( s > 0 or e < obj.totaltime ) do s = s-t e = e+t if( s < 0 ) then s = 0 end if( e > obj.totaltime ) then e = obj.totaltime end x = obj.getvalue("x",s)-obj.getvalue("x",e) y = obj.getvalue("y",s)-obj.getvalue("y",e) if( math.sqrt(x*x+y*y) >= l ) then r = math.atan2(x,y) break end end x0 = x0-math.sin(r)*obj.h*(f_pos-50)/100 y0 = y0-math.cos(r)*obj.h*(f_pos-50)/100 sx = math.sin(r)*obj.w/2 cx = math.cos(r)*obj.w/2 sy = math.sin(r)*obj.h/2 cy = math.cos(r)*obj.h/2 obj.drawpoly(x0-cx-sy,y0+sx-cy,0,x0+cx-sy,y0-sx-cy,0,x0+cx+sy,y0-sx+cy,0,x0-cx+sy,y0+sx+cy,0, 0,0,obj.w,0,obj.w,obj.h,0,obj.h) obj.ox = obj.ox+base_x obj.oy = obj.oy+base_y end obj.setoption("focus_mode","fixed_size")
オアー!(瀕死)
解読
…ひとまず上から見ていくことにする。なお所々に挟んでいる所感は概ね2023/03当時のものである。
トラックバーと値入力ダイアログ
--track0:ライン幅,2,200,16 --track1:先端,0,500,48 --track2:固定速度,0,100,0,0.01 --track3:描画間隔,0,400,10 --dialog:色/col,col=0xffffff;先端図形/fig,fig="三角形";先端位置補正(%),f_pos=70;最小間隔(dot),min_step=2;主線描画(%),c_size=100;補助描画(%),l_size=0;
これらはスクリプト用インターフェースを設定するための記述である。詳細は以下を参照。
track
は以下画像の右側部分の内、「回転」より下の4項目(トラックバー)を好きな様に変更できる。都度変更するパラメーターがある場合はここを使用すればよいであろう。
dialog
は上記画像の「設定」内の項目(値入力ダイアログ)を変更できる。要はコンフィグである。
先頭に--
と記載されているが、これはLuaのコメント記法にあたる。なぜコメントアウトする必要があるのかと一瞬思ったが、そういうものだと思いなおすことにした。
トラックバーに設定した項目は、obj.track*
という変数として使用できる。*には0~3の数字が対応する。値入力ダイアログに設定した項目はその後に続くcol
やfig
を変数として使用できる。なお、これらは仕様上すべてグローバル変数として宣言されることになる。
続いて「ライン部分」とコメントされた部分以降を見ていく。
obj.getvalue
base_x = obj.getvalue("x") base_y = obj.getvalue("y")
obj
と付くものはAviUtl専用に定義された変数や関数である。逐一WiKiを見るべし。
「指定した時間のトラックバーの値を取得します」とな。なんのこっちゃと思ったが、上記をざっくりいくと、base_x
は「ナウのx座標」、base_y
は「ナウのy座標」を取得したことになる様だ。なぜは一旦置いておく。
obj.load
obj.load("figure","円",col,obj.track0)
様々読み込みができるようだが、ここでは図形を読み込むモードが使われている。その後の引数はname、color、sizeと続いているので「col
色の円をobj.track0
サイズで読み込む」という操作をしている。で、後でobj.drawpoly
で実際に描画をするのであろう。ちなみにライン(移動軌跡)は、実際は線ではなく円の集合体でラインを表現している。はえーあたまいい。
obj.effect()
obj.effect()
フィルタ効果、要はエフェクトをかけるために必要なのだと思われる。随分中途半端な位置にあるなと思ったがそういうもんだと(以下略)。
obj.ox,obj.oy
obj.ox = obj.ox-base_x obj.oy = obj.oy-base_y
基準座標からの相対座標である。オーン。で、基準座標とはobj.x
やobj.y
である。つまりトラックバーのxやyである。オーン。とまあ当時(2023/03)は仕様をよく理解していなかった。そのため現相対座標から現基準座標を引く理由が分からぬ。このツケの結果は後日紹介する。
obj.w,obj.h
w2 = obj.w/2 h2 = obj.h/2
名前の通り、オブジェクトの幅と高さである。ここでは上でロードした円の情報を取得し、その半分の値をw2
とh2
に代入している。何に使うかは後で分かるであろう。
変数群その1
t = 0; f = 0; l = 0; n = 1; d = 0 s = w2*obj.track3/50;
ン゙ン゙ン゙ン゙
謎の変数初期化祭りにたどり着いた。唯一s
については「円の幅に描画間隔を掛け50で割る」計算をしていることは分かった。意味が分かったとは言っていない。ひとまず後のコードを見てから考えることにする。
制御文その1
if( s < min_step ) then s = min_step end if( s < 1 ) then s = 1 end
これを見た時の感情は外国で道に迷ったときに日本語の看板を見つけた時の安心感に似ていた(?)。こういうのでいいんだよ。ただし意味が分かったとは(以下略)。変数s
がmin_step
(初期値2)より小さければ強制的にmin_step
にする。さらにそれが2より小さければ強制的に1にする。
コーヒーブレイク
大分頭も厳しくなってきたので、ここで改めて動作確認を行う。特にトラックバー、ダイアログ、s
あたりは何かつかめるかもしれない。
ライン幅
track0
。文字通り線幅が変わる。
先端
track1
。先端サイズが変わる。
固定速度
track2
。分かりにくいがフレーム毎の移動距離が変わる。
描画間隔
track3
。円の設置間隔が変わる。
色
dialog
のcol
。カラーパレットがガビガビなのはご愛敬。
先端図形
dialog
のfig
。未紹介。矢印はこの三角形で表現していた。
先端位置補正
dialog
のf_pos
。未紹介。図形の中心が描画の中心という訳では無い様子。
最小間隔
dialog
のmin_step
。1 < min_step
の時に円同士の最小間隔に指定される。
主線描画
dialog
のc_size
。未紹介。これも結局の所線の幅が変わる。
補助描画
dialog
のl_size
。未紹介。新しく線が生えてくる。半点線の様なものが描画出来る。
一旦まとめ
26/130にしてこの文量となってしまったため、キリも良いので残りは次回に回す。ともあれトラックバーとダイアログが何者か、記すことはできたのでよし。以上。