C# 与纵横比匹配的最小大小

C# 与纵横比匹配的最小大小,c#,.net,algorithm,C#,.net,Algorithm,我需要找到长宽比正好(或在0.001范围内)某个值的最小尺寸。有没有什么快速的数学技巧或框架技巧 下面是我在O(n^2)中运行的当前坏主意的伪代码: epsilon=0.001; 从x=1到最大值x { 从y=1到最大y { 如果(Abs(x/y-aspectRatio)纵横比是x和y之间的比率。您可以将纵横比定义为x/y或y/x 最小纵横比为0/0 必须定义其他一些最小值,最小值x或最小值y 最小x=(最小y*x)/y min y=(min x*y)/x您可以将aspectRatio写成分数(

我需要找到长宽比正好(或在0.001范围内)某个值的最小尺寸。有没有什么快速的数学技巧或框架技巧

下面是我在
O(n^2)
中运行的当前坏主意的伪代码:

epsilon=0.001;
从x=1到最大值x
{
从y=1到最大y
{

如果(Abs(x/y-aspectRatio)纵横比是x和y之间的比率。您可以将纵横比定义为x/y或y/x

最小纵横比为0/0

必须定义其他一些最小值,最小值x或最小值y

最小x=(最小y*x)/y


min y=(min x*y)/x

您可以将aspectRatio写成分数(如果您希望其精度达到0.001,则可以使用round(aspectRatio,3)/1000)


然后,。得到的分数就是您要查找的x/y。

一种更快的方法,但仍然不是公式化的方法是只查看可能的y值,而不是迭代到最大值。例如:

    static Size FindMinSize(double requiredRatio, double epsilon)
    {
        int x = 1;
        do
        {
            int y = (int)(x * requiredRatio);
            if (Test(x, y, requiredRatio, epsilon))
            {
                return new Size(x, y);
            }

            y = (int)((x + 1) * requiredRatio);
            if (Test(x, y, requiredRatio, epsilon))
            {
                return new Size(x, y);
            }
            x++;
        } while (x != int.MaxValue);

        return new Size(0, 0);
    }

    static bool Test(int x, int y, double requiredRatio, double epsilon)
    {
        double aspectRatio = ((double)y)/x;
        return Math.Abs(aspectRatio - requiredRatio) < epsilon;
    }
静态大小findminize(双需求比率,双ε)
{
int x=1;
做
{
int y=(int)(x*所需比率);
if(测试(x,y,所需比率,ε))
{
返回新的大小(x,y);
}
y=(整数)((x+1)*所需比率);
if(测试(x,y,所需比率,ε))
{
返回新的大小(x,y);
}
x++;
}而(x!=int.MaxValue);
返回新的大小(0,0);
}
静态布尔测试(整数x,整数y,双要求比,双ε)
{
双纵横比=((双)y)/x;
返回Math.Abs(aspectRatio-requiredRatio)
不要测试所有可能的组合,只需增加使您更接近纵横比的一侧:

public static Size GetSizeFromAspectRatio(double aspectRatio) {
  double epsilon = 0.001;
  int x = 1;
  int y = 1;
  while (true) {
    double a = (double)x / (double)y;
    if (Math.Abs(aspectRatio - a) < epsilon) break;
    if (a < aspectRatio) {
      x++;
    } else {
      y++;
    }
  }
  return new Size(x, y);
}
公共静态大小GetSizeFromAspectRatio(双aspectRatio){
双ε=0.001;
int x=1;
int y=1;
while(true){
双a=(双)x/(双)y;
if(Math.Abs(aspectRatio-a)
不寻常。你需要找到最大公约数,并用它除以宽度和高度。该算法由欧几里德提出,已有2300年的历史。详细信息。

为什么
Abs(…)
?这个数字从来都不是负数……基本上你想要找到十进制值的最小分数(=最小纵横比)我肯定这是一道GCSE数学题,但我记不起来了,首先,我认为你的伪代码是错的,除非我误解了,它在任何时候都不涉及纵横比值。你现在做的是,再看一眼,找到一个等于
0.001
(例如,x=1和y=1000)的分数但是根据你的描述,我想说你有一个比率,比如说
3.8
,然后找到等于这个比率的x和y,即x=38和y=10(假设只需要整数),最大偏差为
epsilon
(即38001和1000也是一个很好的答案).对吗?如果是这样,一个问题是偏差与因子无关。我认为它应该是一个百分比。我认为你需要寻找的一点是,他想要的是产生纵横比值的最小整数(参见所用的
大小
).
0/0
在我看来像是被零除法;)这不一定能得到最小的结果。例如,对于
aspectRatio=0.3333333333
,你将取整为
333/1000
,并且不能简化它。但是,
1/3
是一个更好的解决方案。@steve-是的,这是我在测试他的想法时遇到的问题。什么值的GCD?宽度和高度?
public static Size GetSizeFromAspectRatio(double aspectRatio) {
  double epsilon = 0.001;
  int x = 1;
  int y = 1;
  while (true) {
    double a = (double)x / (double)y;
    if (Math.Abs(aspectRatio - a) < epsilon) break;
    if (a < aspectRatio) {
      x++;
    } else {
      y++;
    }
  }
  return new Size(x, y);
}