如何在缩放和旋转后重新计算点的坐标?

How to recalculate the coordinates of a point after scaling and rotation?

我有一张图片中6个点的坐标

(170.01954650878906, 216.98866271972656)
(201.3812255859375, 109.42137145996094)
(115.70114135742188, 210.4272918701172)
(45.42426300048828, 97.89037322998047)
(167.0367889404297, 208.9329833984375)
(70.13690185546875, 140.90538024902344)

我有一个点作为中心[89.2458, 121.0896]。我正在尝试使用 4 个旋转度(从 0,90,-90,180)和 6 个缩放因子(0.5,0.75,1,1.10,1.25,1.35,1.5)重新计算 python 中的点的位置。
我的问题是如何相对于中心点旋转和缩放上述点并获得这6个点的新坐标?

非常感谢您的帮助。

数学

一种数学方法是将此数据表示为从中心到 image-points 的向量,将这些向量平移到原点,应用变换并将它们重新定位到中心点周围。让我们详细看看它是如何工作的。

表示为向量

我们可以在网格中显示这些向量,这将产生下图

这张图片提供了一个很好的方式来查看这些点,因此我们可以以视觉方式看到我们的动作发生。中心点在所有箭头的开头用一个点标记,每个箭头的结尾是问题中提供的点之一的位置。

向量可以看作是点坐标值的列表所以

my_vector = [point[0], point[1]]

可能是python中向量的表示,它只是保存一个点的坐标,所以问题中的格式可以按原样使用!请注意,在我的整个回答中,我将使用位置 0 表示 x-coordinate 和 1 表示 y-coordinate。

我只是添加了这种表示作为视觉辅助,我们可以将任何两点的集合视为向量,不需要计算,这只是查看这些点的不同方式。

原文翻译

第一次计算发生在这里。我们需要将所有这些向量平移到原点。我们可以很容易地通过从所有其他点中减去中心点的位置来做到这一点,例如(可以在一个简单的循环中完成):

point_origin_x = point[0] - center_point[0] # Xvalue point - Xvalue center
point_origin_y = point[1] - center_point[1] # Yvalue point - Yvalue center

生成的点现在可以绕原点旋转并相对于原点缩放。新点(作为向量)如下所示:

在这张图片中,我故意保持比例不变,因此很明显这些是完全相同的矢量(箭头),在大小和方向上,只是移动到 (0, 0) 附近。

缘由

那么为什么要将这些点翻译成原点呢?好吧,围绕原点旋转和缩放操作很容易(在数学上),而围绕其他点则不那么容易。

另外,从现在开始,我将只在这些图像中包含第 1、2、4 个点,以节省一些 space。

围绕原点缩放

围绕原点进行缩放操作非常容易。只需将点的坐标乘以缩放因子即可:

scaled_point_x = point[0] * scaling_factor
scaled_point_y = point[1] * scaling_factor

在视觉上,它看起来像这样(全部缩放 1.5):

其中蓝色箭头是原始向量,红色箭头是缩放后的向量。

旋转

现在轮换。这有点难,因为旋转通常通过与该向量的矩阵乘法来描述。

要相乘的矩阵如下

(来自 wikipedia: Rotation Matrix

因此,如果 V 是向量,那么我们需要执行 V_r = R(t) * V 以获得旋转向量 V_r。这个旋转永远是逆时针!为了顺时针旋转,我们只需要使用 R(-t).

因为问题中只需要90°的倍数,所以矩阵变得几乎微不足道。逆时针旋转90°,矩阵为:

基本上在代码中:

rotated_point_x = -point[1]    # new x is negative of old y
rotated_point_y = point[0]     # new y is old x

同样,这可以很好地以视觉方式显示:

我匹配矢量颜色的地方。

顺时针旋转90°会

rotated_counter_point_x = point[1]    # x is old y
rotated_counter_point_y = -point[0]   # y is negative of old x

旋转 180° 将只是取负坐标,或者,您可以只缩放 -1 倍,这在本质上是相同的。

作为这些操作的最后一点,我可以补充一点,您可以根据需要在序列中缩放 and/or 旋转以获得所需的结果。

平移回中心点

在缩放操作 and/or 旋转之后,唯一剩下的就是将向量重新平移到中心点。

retranslated_point_x = new_point[0] + center_point_x
retranslated_point_y = new_point[1] + center_point_y

一切都完成了。

只是回顾一下

所以回顾一下这篇长文post:

  1. image-point
  2. 坐标减去中心点坐标
  3. 通过坐标的简单乘法按比例缩放
  4. 利用矩阵乘法的思想来思考旋转(你可以在Google或维基百科上轻松找到这些东西)。
  5. 将中心点的坐标添加到image-point
  6. 的新坐标

我现在意识到我本可以只做这个回顾,但现在至少有一些视觉帮助和轻微的数学背景post,这也很好。我真的认为这样的问题应该从数学的角度来看,数学描述可以帮助很多。