【问题标题】:How do I scale one rectangle to the maximum size possible within another rectangle?如何将一个矩形缩放到另一个矩形内可能的最大尺寸?
【发布时间】:2010-11-25 06:34:46
【问题描述】:

我有一个源矩形和一个目标矩形。我需要找到源可以缩放到的最大比例,同时适合目标矩形并保持其原始纵横比

Google 找到了 one 的方法,但我不确定它是否适用于所有情况。这是我自制的解决方案:

  • 计算每个矩形的高度/宽度。这给出了对角线 msrcmdest 的斜率。
  • 如果msrc < mdst,缩放源宽度以适应目标宽度(并以相同比例缩放高度)
  • 否则,缩放源 height 以适应目标 height(并按相同比例缩放宽度)

寻找其他可能的解决方案来解决这个问题。我什至不确定我的算法是否适用于所有情况!

【问题讨论】:

    标签: algorithm scaling


    【解决方案1】:
    scale = min(dst.width/src.width, dst.height/src.height)
    

    这是你的方法,但写得更干净。

    【讨论】:

    • 甜蜜!一旦你有了比例,使用这些来获得最终尺寸:width = src.width * scaleheight = src.height * scale
    • 如果要覆盖整个目标区域,请将 min 更改为 max。
    • 相同的解决方案,但名称对我来说更清楚:scale = min(maxWidth/actualWidth, maxHeight/actualHeight)newWidth = actualWidth*scalenewHeight = actualHeight*scale
    【解决方案2】:

    另一个选项可能是缩放到最大宽度,然后检查缩放高度是否大于最大允许高度,如果是,则按高度缩放(反之亦然):

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

    我认为这个解决方案更短、更快、更容易理解。

    【讨论】:

    • 我认为你的第三行中的比率被颠倒了。
    【解决方案3】:
    1. 计算出destWidth / srcWidthdestHeight / srcHeight 中较小的一个
    2. 按比例缩放

    edit 当然和你的方法一样,只是移动了公式的各个部分。我的意见是,这在语义上更清晰,但仅此而已 - 意见。

    【讨论】:

      【解决方案4】:

      如果所有维度都不为零,我将使用以下代码(基本上与您的代码匹配)。

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

      如果需要,这也可以修改为允许任何维度为零。

      【讨论】:

      • 我认为零维度的矩形称为“线”。 :P
      • 这个解决方案在数学上与我的相同:将你的不等式乘以 (innerHeight * outerHeight / innerWidth),你就会得到我的不等式。我的代码的优点是,如果不等式失败,则不需要重新计算解决方案。
      • 三元运算符也只会计算一次条件。而且,当然,所有解决方案都应该是数学等价的……或者错误的……
      • 三元运算符只会对条件进行一次评估,但通过对条件进行不同的格式化,条件计算的一部分可能是答案之一。请注意,您在计算中始终有 3 个乘法运算。我的解决方案在最坏的情况下有 3 个操作,否则它只有 2 个,因为在测试之前已经完成了正确的计算。因此,性能提高了 1/6(假设值的随机分布)。
      【解决方案5】:

      当 sourceWidth 或 sourceHeight 变为零时,其他答案存在产生除以零异常的风险。为了防止这种情况,我们应该将比较重写为数学上等价的多重表达式。此外,还有额外的边缘条件来捕捉无限规模的场景。

      除了有比例尺之外,我真的很想要目标矩形的尺寸,所以,这里我将提供比例尺计算和目标矩形计算。

      由于无限边缘条件,我认为目标矩形会更健壮/有用:

          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;
          }
      

      【讨论】:

        猜你喜欢
        • 2011-10-18
        • 2011-11-24
        • 1970-01-01
        • 2020-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多