ページ

2008年5月3日土曜日

rubberBand(その17)縦横比率を維持したままリサイズ(その4)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

縦横比維持のリサイズ続き。


コーディングを重ねるもなかなか思い通りに行かず混乱してきた。一旦立ち止まって整理してみることにした。

その結果、マウスの制約うんぬんよりも、ドラッグの方向のルールをきちんと決めないから意図通りの動きになっていないことに気がついた。

右下の Knob を例に取ると拡大縮小のルールは下記のようになる。


Knob上に45度の仮想的な直線を想定し、そこを境に右下方向へマウスがドラッグされた場合は x,y共に拡大させる。逆に左上の領域の場合は縮小させる。

どちらの領域になるかは、ある点が直線の上下どちらにあるかを判断すればわかる。


点(x1, y1)が直線 y=ax+b の上下どちらにあるかは、a*x1+b と y1 の値を比較すれば分かる。これを使って拡大・縮小処理を行なう。

この考えで四隅のKnobのルールをまとめると次のようになる。


左上・右下と、左下・右上は仮想線に対する拡大・縮小のルールが共通なのがわかる。つまりこの2グループ x 2領域 の4パターンを考えれば良い。グループ分けは Knobの位置で判断し、後者の領域は先の直線に対する点の位置判定で判断できる。

後はこれをコーディングに落とすだけ。

 CGFloat rule_s = rule.w * rule.h;
CGFloat sx, sy;
if (rule_s > 0) {
if (-dx < dy) {
sx = +1;
sy = +1;
} else {
sx = -1;
sy = -1;
}
resized = YES;
} else if (rule_s < 0) {
if (dx < dy) {
sx = -1;
sy = +1;
} else {
sx = +1;
sy = -1;
}
resized = YES;
}
if (resized) {
CGFloat dl = sqrt(dx*dx + dy*dy);
dx = sx * dl * pcos;
dy = sy * dl * psin;
}


・rules_s は以前定義したknobの位置情報からグループ判断に必要な情報を用意している。
・仮想線は切片b=0、傾き45度(or -45度)なので a=1 or -1。点の位置は (-dx < dy) もしくは (dx < dy)で判断できる。
・pcos , psin はあらかじめ 45度の cos, sin値を用意してある。

紆余曲折の上、やっとできた。やれやれ。


RubberBand-11.zip