如何确定哪些纵横比最接近

10
给定一个长宽比为sx/sy的矩形S,和另外两个长宽比分别为ax/ay和bx/by的矩形A和B,如何确定哪个形状的长宽比与S最接近?这些形状的大小不重要。
是不是只需要比较(sx/sy)/(ax/ay)和(sx/sy)/(bx/by)哪个更接近1呢?
实际上,我想要做的是找到在PPTX幻灯片中最适合调整大小并裁剪以适应该形状的图像。我想另一种方法是计算哪个形状会导致丢失最少的像素,但在我的代码中,如果可以通过比较长宽比来完成,则更容易实现。
最终,我采用了以下算法,并按以下方式实施(感谢Matt Ball的反馈):
ShapeInPPTXLocation closest;
double imageAR = a_imageDim.getWidth()/a_imageDim.getHeight();
double aspectRatioCandidateA = a_candidateA.getWidth()/a_candidateA.getHeight();
double aspectRatioCandidateB = a_candidateB.getWidth()/a_candidateB.getHeight();
double closenessScoreA=1-(imageAR/aspectRatioCandidateA);
double closenessScoreB=1-(imageAR/aspectRatioCandidateB);

if (Math.abs(closenessScoreA) <= Math.abs(closenessScoreB))
{
    closest=a_candidateA;
}
else
{
    closest=a_candidateB;
}
2个回答

3

这是不是只需要判断哪一个比例 (sx/sy)/(ax/ay) 和 (sx/sy)/(bx/by) 更接近1呢?

这听起来很合理。你也可以通过最小化差异来实现:

let target_ratio = sx/sy
let a_ratio = ax/ay
let b_ration = bx/by

if |target_ratio - a_ratio| < |target_ratio - b_ratio|
    a_ratio is closer to target
else
    b_ratio is closer to target

更新: 此答案中的算法并不完全可行,如下面的评论所述。 OP更新了他的问题,包括他使用的算法,看起来好像能正常工作。


我最初也考虑了这个问题,但我认为只有在我们假设所有形状的X>Y(或反之亦然)时才起作用。例如,对于纵向图像,宽高比始终是一个分数;对于横向图像,则是一个整数。不过,如果我对此有所错误,请告诉我 - 谢谢。 - Martin Wilson
1
刚在我的代码中实现了这个,它完美地工作了 - 谢谢 :-) - Martin Wilson
话虽如此,这个算法存在一个边缘情况无法处理,与我上面的评论有关。 - Martin Wilson
嗯,也许比较比率的比率(正如您最初提到的)比差异更好 - 毕竟,0.0000001 5 更接近于 2 - Matt Ball
现在已经完成了 - 对我投入的所有情况都有效。感谢您的帮助。 - Martin Wilson
显示剩余2条评论

3

看到上面的建议,我并不确定:

想象以下例子: A = 1:2 B = 2:1 还有

targetRatio = 1:1

显然,A和B都应该同样适用,但按照建议的比较方式:

(1 - GoalAR/CandiateAR)

aspectRatioCandidateA = 0.5 [1:2]

aspectRatioCandidateB = 2 [2:1]

你会得到:

closenessScoreA = 1

closenessScoreB = 0.5

比较宽高比最好的方法是将其看作定义角度的方式:

tan(o) = h/w

o = atan(h/w)

然后,您可以直接比较角度的差异。


可接受的答案并未奏效,正如你的示例所展示的。如果你阅读了该回答的评论线程,就会看到我最终采用了什么方法——即使用我在问题中提出的算法。无论如何,感谢你的贡献 :-) - Martin Wilson
嗨。现在有点困惑了。据我理解,您正在使用问题中打印的代码(在您的编辑后),是吗?我用我的反例来参考它。以两个比率A=3:4=0.75和B=17:10=1.7为例。哪一个更接近G=5:4=1.25?根据您的代码,得分为0.66的是A,而得分为0.735的是B。然而,如果您比较角度,您会发现B更“接近”目标。B的θ为59.53,A的θ为36.869,而目标位于51.34。 - BmyGuest
1
你的方法可能更准确(看起来很合理)。然而,使用“我的”算法,B也赢了A,其中 (sx/sy)/(ax/ay) = 1.67;B的 (sx/sy)/(ax/ay) = 0.74;A的得分(接近1)= 1-1.67 = 0.67;B的得分 = 1-0.74 = 0.26。除非我犯了一个错误;-) - Martin Wilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接