6

ある長方形を別の長方形に合わせて、うまく収まるように中央に配置することがよくあります。ホワイトボードに何かを描いて、ロジックが何であるかを写真に撮りますが、暗くなり、ろうそくの明かりでそれを行うのが楽しくなくなります。

とにかくシンプルで分かりやすいです。これは、私が最初から書き直さなければならなかった関数です (今回は PHP で):

// Fit rectangle 2 into rectangle 1 to get rectangle 3
// Rectangle 3 must be centered
// Return dimensions of rectangle and position relative to rectangle 1

function fitrect($w1,$h1,$w2,$h2){

    // Let's take a chance with rectangle 3 width being equal to rectangle 1 width
    $w3=$w1;
    $h3=$w3*($h2/$w2);

    // Check if height breaks rectangle 1 height
    if($h3>$h1){
        // Recalculate dimensions and then position
        $h3=$h1;
        $w3=$h3*($w2/$h2);
        $x3=($w1-$w3)/2;
        $y3=0;
    }else{
        // Just calculate position
        $y3=($h1-$h3)/2;
        $x3=0;
    }

    // Tidy up
    $x3=round($x3);
    $y3=round($y3);
    $w3=round($w3);
    $h3=round($h3);

    // Result array
    $res=array($x3,$y3,$w3,$h3);

    return($res);

}

ペンと紙 (またはホワイトボード) に二度と頼る必要がないように、このアルゴリズムとその他のバージョンを理解したいと思います。

それで、あなたはこれをどのようにしますか?どんな毛羽が取り除けますか?

編集: 例として、長方形 1 の寸法が 256x256 で、長方形 2 が 44x167 であるとします。次に、長方形 2 を 67x256 にスケーリングし、長方形 1 に対して 94,0 の位置に配置して、長方形 1 の中央に最大化して配置する必要があります。

4

4 に答える 4

11

これが私がそれを行う方法です。

長方形の幅と高さの比率に等しい、太さという用語を定義しましょう。高さ 1、幅 10 の長方形の太さは 10 です。高さ 20、幅 10 の長方形の太さは 0.5 です。長方形のサイズを変更しても、太さは変わりません。

長方形 2 のサイズを拡大または縮小して、その幅が長方形 1 と等しくなるようにすると、長方形 2 が長方形 1 より太い限り、上部または下部からオーバーフローしません。1 が 2 よりも太い場合オーバーフローします。適切な幅または適切な高さのどちらにサイズ変更するかは、事前にわかっています。さらに、変換ロジックはどちらの場合も同じであるため、if/else ブロックの外側に移動できます。

擬似コード: (申し訳ありませんが、私は PHP を知りません)

fatness1 = w1 / h1
fatness2 = w2 / h2

#adjust scaling
if fatness2 >= fatness1:
    #scale for a snug width
    scaleRatio = w1 / w2
else:
    #scale for a snug height
    scaleRatio = h1 / h2
w3 = w2 * scaleRatio
h3 = h2 * scaleRatio


#adjust rectangle 3's center so it is the same as 1's center
xCenterOf1 = x1 + (w1 / 2)
yCenterOf1 = y1 + (h1 / 2)

x3 = xCenterOf1 - (w3 / 2)
y3 = yCenterOf1 - (h3 / 2)

return (x3, y3, w3, h3)

Python でテストすると、長方形 1 が (0,0) にあると仮定して、scale(256,256, 44, 167)が返されます(0.0, 94.3, 256.0, 67.4)

于 2012-11-14T18:31:13.183 に答える
7

Java で書かれた便利な関数を次に示します。

public static RectF fitRectWithin(Rect inner, Rect outer) {
    float innerAspectRatio = inner.width() / (float) inner.height();
    float outerAspectRatio = outer.width() / (float) outer.height();

    float resizeFactor = (innerAspectRatio >= outerAspectRatio) ?
    (outer.width() / (float) inner.width()) :
    (outer.height() / (float) inner.height());

    float newWidth = inner.width() * resizeFactor;
    float newHeight = inner.height() * resizeFactor;
    float newLeft = outer.left + (outer.width() - newWidth) / 2f;
    float newTop = outer.top + (outer.height() - newHeight) / 2f;

    return new RectF(newLeft, newTop, newWidth + newLeft, newHeight + newTop);
}
于 2014-02-22T21:17:58.823 に答える
2

これが私がやった方法です。(このアルゴリズムは画像でうまく機能します。) 長方形とコンテナー (長方形も) があるとします。

aspectRatio = screen.width / screen.height

if (rectangle.width >= rectangle.height)
{
   resizeFactor = container.width / rectangle.width
   rectangle.width = rectangle.width * resizeFactor
   rectangle.height = rectangle.height * resizeFactor * aspectRatio
}
else
{
   resizeFactor = container.height / rectangle.height
   rectangle.width = rectangle.width * resizeFactor / aspectRatio
   rectangle.height = rectangle.height * resizeFactor
}

6 行目を次のように変更することで、このアルゴリズムを少し最適化できます。

rectangle.width = container.width

必要に応じて、13行目まで同じです。

于 2013-10-25T04:16:38.820 に答える