web-dev-qa-db-ja.com

ある長方形を別の長方形内で可能な最大サイズにスケーリングするにはどうすればよいですか?

ソース長方形とデスティネーション長方形があります。宛先の四角形内に収まり、元のアスペクト比を維持しながら、ソースをスケーリングできる最大のスケールを見つける必要があります

グーグルはそれを行うための one 方法を見つけましたが、それがすべてのケースで機能するかどうかはわかりません。これが私の自家製のソリューションです:

  • 各長方形の高さ/幅を計算します。これにより、対角線の勾配msrcおよびmdestが得られます。
  • msrc < mdst、宛先widthに合わせてソースwidthをスケールします(そしてスケールします)同じ比率で高さ)
  • それ以外の場合は、宛先heightに合わせてソースheightをスケールします(およびスケール幅同じ比率で)

この問題の他の可能な解決策を探しています。私のアルゴリズムがすべてのケースで機能するかどうかさえわかりません!

58
Agnel Kurian
scale = min( dst.width/src.width, dst.height/src.height)

これはあなたのアプローチですが、よりきれいに書かれています。

115
tom10

別のオプションは、最大幅にスケーリングしてから、スケーリングされた高さが最大許容高さより大きいかどうかを確認し、そうであれば高さでスケーリングする(またはその逆):

scale = (dst.width / src.width);
if (src.height * scale > dst.height)
 scale = dst.height / src.height;

このソリューションは、短く、速く、理解しやすいと思います。

10
Guss

すべての次元がゼロ以外の場合、次のコードを使用します(コードは基本的にあなたのコードと一致します)。

scaleFactor = (outerWidth / outerHeight > innerWidth / innerHeight) 
    ? outerHeight / innerHeight
    : outerWidth / innerWidth

これを変更して、必要に応じて任意の次元をゼロにすることもできます。

1
  1. destWidth / srcWidthdestHeight / srcHeightの小さい方を計算する
  2. それでスケーリング

編集もちろん、これはメソッドと同じですが、数式の一部が移動します。私のopinionは、これは意味的に明確であるということですが、それだけです-意見です。

1
AakashM

他の回答には、sourceWidthまたはsourceHeightのいずれかがゼロになると、ゼロ除算例外が生成されるリスクがあります。これを防ぐには、比較を数学的に等価な複数の式に書き直す必要があります。また、無限スケールのシナリオをキャッチするための追加のEdge条件。

スケール以外にも、ターゲットの四角形の寸法が本当に欲しかったので、ここでスケールの計算とターゲットの四角形の計算を提供します。

無限のエッジ条件のため、ターゲットの四角形はより堅牢/便利になると思います:

    if (sourceWidth == 0 && sourceHeight == 0) {
        // scale = Infinity;
        outputWidth = 0;
        outputHeight = 0;
        outputX = destWidth / 2;
        outputY = destHeight / 2;
    } else if (destWidth * sourceHeight > destHeight * sourceWidth) {
        scale = destHeight / sourceHeight;
        outputWidth = sourceWidth * destHeight / sourceHeight;
        outputHeight = destHeight;
        outputX = (destWidth - outputWidth) / 2;
        outputY = 0;
    } else {
        scale = destWidth / sourceWidth;
        outputWidth = destWidth;
        outputHeight = sourceHeight * destWidth / sourceWidth;
        outputX = 0;
        outputY = (destHeight - outputHeight) / 2;
    }
0
Stephen Quan