#概要
2点間の線形補間とは,空間上の2点A,Bを端点とする線分AB上の任意の点を計算することである.
この考えを用いることによって,直線上に限るがUIなんかを動かすことが出来る.
また線形補間から発展して,イージングやベジェ曲線の話もしたいと思う.
以下の順序で話していく.
1.2点間の線形補間入門
2.実際に補間してみよう
3.イージングで気持ちいい動きに
4.ベジェ曲線
#1.2点間の線形補間入門
まず内分の公式について述べよう.
線分$AB$を$m:n$に内分する点$P$とは,線分$AB$上にあって$AP:PB=m:n$となる点のことをいう.
2次元上の点$P$の座標は次の式で求めることができる.
$(Aの座標)=(x_a,y_a),(Bの座標)=(x_b,y_b)$,とするとき,
$(Pの座標)=(\frac{nx_a+mx_b}{m+n},\frac{ny_a+my_b}{m+n}).$
証明(読みたい人だけ)
$x$座標と$y$座標を別々に計算していることから,$x$軸上,$y$軸上でそれぞれ考えればよい.
$x$成分に関して示せば$y$成分に関しても同様である.$x$成分に関して示す.
点$P$の座標=$(x_p,y_p)$とおく.線分$AP$の$x$成分の長さは,$|x_p-x_a|.$
また線分$PB$の$x$成分の長さは,$|x_b-x_p|$である.
今,$AP:PB=m:n$なので,
$|x_p-x_a|:|x_b-x_p|=m:n$,より比の計算から,$m|x_b-x_p|=n|x_p-x_a|.$
ここで,$x_p$は$x_a$と$x_b$の間にある,つまり$x_a<x_b$のときは,$x_a<x_p<x_b.$
$x_b<x_a$のときは,$x_b<x_p<x_a$,となるので,
$x_a<x_b$のとき,
$|x_p-x_a|=x_p-x_a,$
$|x_b-x_p|=x_b-x_p.$
$x_b<x_a$のとき,
$|x_p-x_a|=-(x_p-x_a),$
$|x_b-x_p|=-(x_b-x_p).$
となり,$m|x_b-x_p|=n|x_p-x_a|$の絶対値が外せて,$m(x_b-x_p)=n(x_p-x_a)$とできる.
$mx_p+nx_p=nx_a+mx_b$
$x_p(m+n)=nx_a+mx_b$
$x_p=\frac{nx_a+mx_b}{m+n}$
を得る.■
この証明により,この公式が任意の次元に拡張できることも分かる.
さて,$m=t,n=1-t,,(0\le t \le 1)$とおこう.$m+n=1$より,
$(点Pの座標)=((1-t)x_a+tx_b,(1-t)y_a+ty_b).$
分母を消すことができた.
$t=0$のとき,
$((1-0)x_a+0x_b,(1-0)y_a+0y_b)=(x_a,y_a)=(点Aの座標).$つまり点Aと点Pは一致する.
$t=1のとき,$
$((1-1)x_a+1x_b,(1-1)y_a+1y_b)=(x_b,y_b)=(点Bの座標).$つまり点Bと点Pは一致する.
$0<t<1$のとき,$P$は内分点になる.
(証明)
任意の内分が$t:1-t$でかけることを示す.
$P$を線分$AB$を$a:b$に内分する点とする.$(\forall a,b\in \mathbb{N})$
比に同じ数をかけても変わらないので,$\frac{1}{a+b}$をかけて,
$a:b=\frac{a}{a+b}:\frac{b}{a+b}$となる.
$t=\frac{a}{a+b}$とおけば,$a>0,b>0$だから,$0<t<1$.
また,$\frac{b}{a+b}=\frac{a+b}{a+b}-\frac{a}{a+b}=1-t$.
よって,$0<t<1$がとれて,$a:b=t:1-t$とかけることが示せた.■
例えば,$t=0.1$とすると,点$P$は$AB$を$1:9$に内分する点となる.
($t<0,1<t$では外分点を表現できる.)
この議論から,$t$を$0$から$1$まで変化させることによって,2点間の線形補間ができることをイメージしてくれると嬉しい.
#2.実際に補間してみよう
2点間の線形補間(Qiita記事用) pic.twitter.com/lAbFvcs1xL
— みるきーさいとう (@milky_saitou) September 27, 2019
t = obj.time / obj.totaltime
obj.ox = (1 - t) * (-192) + t * 217
obj.oy = (1 - t) * 70 + t * (-79)
非常に単純な線形補間移動をAviUtl上で再現してみた.
現在のフレーム番号を移動に使う総フレーム数で割ったものを$t$とすれば,$0\le t \le 1$,を得ることが出来る.
UIアニメーションとして見れば直線的で固い動きである.
#3.イージングで気持ちいい動きに
イージング関数の明確な定義を見つけることはできなかったが,閉区間[0,1]上の数値を良い感じに加工できる関数のことである.
UIアニメーションなどで視覚効果を得るために使える.4で述べるベジェ曲線を用いれば簡単にイージング関数が作れる(かもしれない).
2点間の線形補間 -EaseOut- (Qiita記事用) pic.twitter.com/oOLP9BqoYn
— みるきーさいとう (@milky_saitou) September 27, 2019
s = obj.time / obj.totaltime
t = -(1 / 4)^(s * 10) + 1
obj.ox = (1 - t) * (-192) + t * 217
obj.oy = (1 - t) * 70 + t * (-79)
2点間の線形補間 -EaseIn-(Qiita記事用) pic.twitter.com/EBY1vspUtQ
— みるきーさいとう (@milky_saitou) September 27, 2019
s = obj.time / obj.totaltime
t = s^5
obj.ox = (1 - t) * (-192) + t * 217
obj.oy = (1 - t) * 70 + t * (-79)
上記2つは以下のようにUIで使用可能である.
この他にも様々なイージング関数があるが,ここでは紹介しない. #4.ベジェ曲線 内分の応用としてベジェ曲線があげられる.ベジェ曲線はコンピュータ上で曲線を描く際にしばしば用いられる.2点間の線形補間 -Easing UI応用-(Qiita記事用) pic.twitter.com/n4tZtrTxyl
— みるきーさいとう (@milky_saitou) September 27, 2019
###2次ベジェ曲線
$2次ベジェ曲線は2点A,Bと1つの制御点Qで作ることができる.$
線分$AQ$を$t:1-t$に内分する点を$P_1$,線分$QB$を$t:1-t$に内分する点を$P_2$とする.線分$P_1P_2$を$t:1-t$に内分する点を$P$として,点$P$の軌跡を2次ベジェ曲線と定義する.
点$A$の座標を$(x_0,y_0)$,点$Q$の座標を$(x_1,y_1)$,点$B$の座標を$(x_2,y_2)$とする.
内分の公式から,
点$P_1$の座標は$((1-t)x_0+tx_1,(1-t)y_0+ty_1),$
点$P_2$の座標は$((1-t)x_1+tx_2,(1-t)y_1+ty_2),$となる.
したがって,Pの座標も内分の公式から求められて,
$(t^2(x_2-2x_1+x_0)+2t(x_1-x_0)+x_0,$
$t^2(y_2-2y_1+y_0)+2t(y_1-y_0)+y_0),$となる.
(計算略 物好きな人はやってみるとよい.)
$t=0$のとき,
$(0^2(x_2-2x_1+x_0)+2\cdot0(x_1-x_0)+x_0,$
$0^2(y_2-2y_1+y_0)+2\cdot0(y_1-y_0)+y_0)$
$=(x_0,y_0).$
$t=1$のとき,
$(1^2(x_2-2x_1+x_0)+2\cdot1(x_1-x_0)+x_0,$
$1^2(y_2-2y_1+y_0)+2\cdot1(y_1-y_0)+y_0)$
$=(x_2-2x_1+x_0+2x_1-2x_0+x_0,$
$y_2-2y_1+y_0+2y_1-2y_0+y_0)$
$=(x_2,y_2).$
となる.
###3次ベジェ曲線 3次ベジェ曲線は2点$A,B$と2つの制御点$Q_1,Q_2$で作ることが出来る. 線分$AQ_1$を$t:1-t$に内分する点を$P_1$,線分$Q_1Q_2$を$t:1-t$に内分する点を$P_2$,線分$Q_2B$を$t:1-t$に内分する点を$P_3$とする. さらに,線分$P_1P_2$を$t:1-t$に内分する点を$P_4$,線分$P_2P_3$を$t:1-t$に内分する点を$P_5$とする. さらに,線分$P_4P_5$を$t:1-t$に内分する点を$P$として,点$P$の軌跡を3次のベジェ曲線と定義する. $A$の座標を$(x_0,y_0)$,$Q_1$の座標を$(x_1,y_1)$,$Q_2$の座標を$(x_2,y_2)$,$B$の座標を$(x_3,y_3)$とすると, 内分の公式を用いて順番に点の座標を計算していけば,最終的に点$P$の座標, $(t^3(x_3-3x_2+3x_1-x_0)+t^2(3x_2-6x_1+3x_0)+t(3x_1-3x_0)+x_0,$ $t^3(y_3-3y_2+3y_1-y_0)+t^2(3y_2-6y_1+3y_0)+t(3y_1-3y_0)+y_0),$を得る.2次ベジェ曲線 点Pの軌跡(Qiita記事用) pic.twitter.com/j6nbtC8I7w
— みるきーさいとう (@milky_saitou) September 27, 2019
これも$t=0$のとき,$(x_0,y_0)$,$t=1$のとき,$(x_3,y_3)$となる.
3次ベジェ曲線 点Pの軌跡(Qiita記事用) pic.twitter.com/abXs5bwPHM
— みるきーさいとう (@milky_saitou) September 27, 2019
###n次ベジェ曲線
任意の次数のベジェ曲線を描きたくなることもあるだろう.私の予想を書いておく.
$A(x_0,y_0),B(x_n,y_n),Q_k(x_k,y_k),,(k=1,2,\cdots,n-1)$と各々座標をおくと,$n$次ベジェ曲線の点$P$の軌跡は,
(\sum_{l=0}^n(_nC_lt^l(\sum_{k=0}^l(-1)^k\,_lC_kx_{l-k})),\sum_{l=0}^n(_nC_lt^l(\sum_{k=0}^l(-1)^k\,_lC_ky_{l-k})))
$で与えられる(かもね).$
n次ベジェ曲線を描くプログラム(1000分割18次くらいで計算時間が膨大になる模様) pic.twitter.com/ZE8iJmHK5J
— みるきーさいとう (@milky_saitou) May 11, 2019
#おわりに
ベジェ曲線を用いてイージング関数を生成するなんてのも面白いかもしれないですね.