拡大縮小

BREW で拡大縮小ルーチンを書く必要が出てきたので、考えてみる。
ただ、普通に考えると、倍率を出してどうこうするのかもしれないけれども、そんなのは低速すぎる気がするので、ブレゼンハムを使って実装してみる。


水平方向について考えてみると、dx を毎ループ加算して、sx の誤差が一定を超えた場合に、sx を加算すればいいらしいので、どこぞに落ちているルーチンをそのまま書いてみる。

int sx = 0;
int dx = 0;
int ex = 0; // src の誤差
while( true ){
    if( dx >= dw) break;
    dst[ dx ] = src[ sx ];
    dx++;
    ex += sw;
    if( sx > sw){
        sx++;
        ex -= dw;
    }
}

しかし、これだと縮小の時にうまくいかない。
これを何とかする前に、このアルゴリズムについて考えてみる必要がありそうだ。


拡大縮小は、src を 0 から、dst を 0 から走査していって、同じフレーム数でそれぞれ sw,dwにたどり着ければいい。
到達フレーム数をmax、現在のフレームをtとすれば、tの時のsx,dxは、
3$\begin{array}sx&=&\frac{sw}{max}~t\\dx&=&\frac{dw}{max}~t\end{array}
となる。max回で分割することによって一回の移動量を求めて、t倍しているだけだ。
数学的に考えるとこれで終わりだけれども、今回の場合、到達フレーム数は決まっている。転送先に穴を空けるわけにはいかないから、最低でもdw回移動させなければならないのだ。
なので、max=dwとして計算してみると、
3$\begin{array}sx&=&~&\frac{sw}{dw}~t&\\dx&=&~&\frac{dw}{dw}~t&=t\end{array}
となる。
なんと、dx=tとなっているではないか。