编程与数学 | 一维空间的中心缩放

零 Flutter教程评论60字数 1321阅读4分24秒阅读模式

编程与数学 | 一维空间的中心缩放

0. 问题描述:

最近在研究一个功能,期间演化出一些比较有趣的小知识。我把它们整理成独立的问题,来分享给大家。首先来解释一下,什么叫 一维区域空间的中心缩放

比如,现在有一个刻度尺,视口区域是 [4,12] ,现在求:文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17431.html

若以 8 为缩放中心,将尺子放大两倍。求前视口的刻度区域。文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17431.html

image.png文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17431.html


缩放中心,就是在缩放变换过程中的不动点。我们可以把尺子放大两倍后,将区域对应的缩放中心和 8 对齐。下面可以从图中看出,当前视口区域的在 [6,10]:文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17431.html

image.png文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17431.html

于是,就可以抛出本文研究的目标:文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17431.html

一维空间中的 [a,b] 区域,以 c 点为缩放中心,缩放 s 倍,求区域此的范围。文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17431.html


1. 解决思路

现在先分析一下上面案例中的细节,从数学的角度上理解一下,为什么结果是 [6,10]文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17431.html

[4,12] 以 8 为中心放大两倍。文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17431.html

  • 原区域刻度长度: 12 - 4 = 8
  • 当刻度尺放大两倍,而视口区域不变。则视口刻度长度将会减半。
  • 缩放中心的刻度保持不变。

image.png文章源自灵鲨社区-https://www.0s52.com/bcjc/flutterjc/17431.html

根据上面三点特征,我们就可以将模型简化为,求解区域前后刻度的问题。如下所示,两个问号分别是多少:

image.png

小学毕业了的朋友应该可以很轻松地报出答案:

左侧: 8 - 4/2 = 6
右侧: 8 + 4/2 = 10

我们真的将尺子放大两倍,然后观测效果,对规律进行总结,这是 物理学。而对于 数学 来说,根据已知条件,通过逻辑进行推演,就能得到答案。


2. 缩放执行非中点

如下所示,如果此时将缩放中心设置为 10 ,通过真实的缩放观察可以看出结果是 [7~11]。此时缩放中心左侧空间的占比是 (10-4)/(12-4)。尺子放大之后,区域总刻度是 4 ,则左侧空间程度 (12-4)/2 * (10-4)/(12-4) = 3 
于是缩放后左侧刻度 10-3 = 7,右侧自然也就是 10+(4-3) = 11

image.png


3. 一般化的一维空间中心缩放

现在我们可以根据推演的逻辑,将这个规律适用于一般化的场合

一维空间中的 [a,b] 区域,以 c 点为缩放中心,缩放 s 倍,求区域此的范围。

  • 原区域刻度长度: b - a
  • 当刻度尺放大 s 倍,而视口区域不变。则视口刻度长度将缩小 s 倍。
  • 缩放中心的刻度保持不变。

image.png

左侧坐标: c - (b-a)/s * [(c-a)/(b-a)]
右侧坐标: c + (b-a)/s * [(b-c)/(b-a)]


4. 演算的编程实现

如下所示,定义一个 Area 类型标识区间左右刻度;scale 方法将用于对 Area 对象以 c 为中心,缩放 s 倍:

image.png

dart

代码解读
复制代码
void main() {
  Area area = Area(4, 12);
  double center = 10;
  double s = 2;

  Area ret = scale(area, center, s);
  print(ret);
}

Area scale(Area area, double c, double s) {
  double len = area.b - area.a;
  double lenL = c - area.a;
  double lenR = area.b - c;
  return Area(
    c - len / s * (lenL / len),
    c + len / s * (lenR / len),
  );
}


class Area {
  final double a;
  final double b;

  Area(this.a, this.b);

  @override
  String toString() {
    return 'Area[$a ~ $b]';
  }
}

零
  • 转载请务必保留本文链接:https://www.0s52.com/bcjc/flutterjc/17431.html
    本社区资源仅供用于学习和交流,请勿用于商业用途
    未经允许不得进行转载/复制/分享

发表评论