将矩形适合另一个矩形

zaf*_*zaf 5 algorithm geometry function pseudocode

我经常将一个矩形装入另一个矩形,以便它很好地适合并且居中.我会在白板上画一些东西,然后拍摄一下逻辑是什么,但它变得越来越暗,烛光使它变得不那么有趣.

无论如何,它非常简单易懂.这是我刚刚从头开始编写的函数(这次是在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);

}
Run Code Online (Sandbox Code Playgroud)

我想了解这个算法和它的其他版本,以便我的大脑可以理解基础,这样我就不必再依赖笔和纸(或白板)了.

那么,你会怎么做?绒毛可以去除什么?

编辑:举个例子 - 假设我们有矩形1,尺寸为256x256,矩形2为44x167.然后我们需要将矩形2缩放到67x256并将其相对于矩形1定位在94,0,以使其最大化并集中在矩形1中.

Kev*_*vin 10

我就是这样做的.

让我们定义一个术语,肥胖,它等于矩形宽度与高度的比值.高度为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)
Run Code Online (Sandbox Code Playgroud)

在python中进行测试,假设矩形1位于(0,0),则scale(256,256, 44, 167)返回(0.0, 94.3, 256.0, 67.4).

  • 我喜欢'肥胖'的想法. (2认同)

Mik*_*ler 5

这是一个用 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);
}
Run Code Online (Sandbox Code Playgroud)