如何使给定的新坐标与旧坐标成比例

How to make new given coordinates proportional to old ones?

本文关键字:坐标 成比例 何使 新坐标      更新时间:2023-10-16

我有一个对象。它有一些原始的宽度和高度。我给出了新的宽度和高度。如何采用新的给定宽度和高度的对象原始的?(假设我们有一个正方形1000x1000,并给出了一些期望的最大可能坐标,比如1900x1200什么算法可以从中产生1200x1200 ?或者在其他情况下,我们有1000x1000原件,并给予400x600,它应该返回400x400…)

所以我开始尝试创建一些代码来删除它,但是失败了:
void resize_coefs(const int & original_w, const int & original_h, int & new_w, int & new_h)
{
    double VW = new_w; 
    double VH =  new_h;
    double rw = original_w/VW;
    double rh = original_h/VH;
    if (rw>=rh){
        new_h = VH;
        new_w = rh*new_w + 2;
    }
    else
    {
        new_w = VW;
        new_h= rw*new_h;
    }
}

这样做:

  1. 计算宽度的比例因子
  2. 计算高度的比例因子
  3. 使用最小的缩放因子来缩放宽度和高度。

示例代码:

void resize_coefs(const int original_w, const int original_h, int & new_w, int & new_h)
{
    double scale = std::min(
        ((double) new_w) / original_w ,
        ((double) new_h) / original_h );
    new_w = std::min( scale * original_w, new_w );
    new_h = std::min( scale * original_h, new_h );
}

由于可能存在舍入误差,建议检查new_wnew_h在缩放后是否仍在边界内。

编辑:这里有一个版本,使用Kerrek在他的回答中提供的提示,只对整数算术做同样的事情。很难看出它们遵循的是完全相同的逻辑。

void resize_coefs(const int original_w, const int original_h, int & new_w, int & new_h)
{
    int num, den;
    if (new_w * original_h < new_h * original_w) {
        num = new_w;
        den = original_w;
    } else {
        num = new_h;
        den = original_h;
    }
    new_w = original_w * num / den;
    new_h = original_h * num / den;
}

计算出原边界和新边界的宽高比。然后比较,并适当地横向或纵向缩放:

const double orig_width, orig_height;
const double max_new_width, max_new_height;
const double orig_ar = orig_width / orig_height;
const double new_ar = max_new_width / max_new_height;
const double scale = new_ar < orig_ar ? max_new_width / orig_width : max_new_height / orig_height;
const double new_height = orig_height * scale;
const double new_width  = orig_width  * scale;

如果你愿意,你可以完全用整数来做这个。请记住,a/b == c/d等同于a*d == b*c(您甚至不必担心分母为零)。

Update:这是我要使用的具体整数函数:

void scale(unsigned int orig_width, unsigned int orig_height,
           unsigned int max_new_width, unsigned int max_new_height)
{
  const bool scale_width = max_new_width * orig_height < orig_width * max_new_height;
  const unsigned int new_height = scale_width ?
                                  orig_height * max_new_width / orig_width :
                                  orig_height * max_new_height / orig_height;
  const unsigned int new_width  = scale_width ?
                                  orig_width  * max_new_width / orig_width :
                                  orig_width  * max_new_height / orig_height;
  std::cout << "New dims: " << new_width << " x " << new_height << std::endl;
}