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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在缩放和旋转后计算点的坐标?相关的知识,希望对你有一定的参考价值。

我在图像中有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个点的新坐标?

非常感谢您的帮助。

答案

Mathematics

数学方法是将这些数据表示为从中心到图像点的矢量,将这些矢量转换为原点,应用变换并将它们重新定位在中心点周围。让我们来看看它的工作原理。

Representation as vectors

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

Representation of the given points as vectors around the center point

此图像提供了查看这些点的好方法,因此我们可以看到我们的行为以可视方式发生。中心点在所有箭头的开头标有一个点,每个箭头的末尾是问题中提供的一个点的位置。

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

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

可以是python中矢量的表示,它只保存一个点的坐标,因此问题中的格式可以按原样使用!请注意,在我的答案中,我将使用位置0作为x坐标,使用1作为y坐标。

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

Translation to origin

第一次计算发生在这里。我们需要将所有这些向量转换为原点。例如,我们可以通过从所有其他点减去中心点的位置来轻松完成此操作(可以在一个简单的循环中完成):

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

现在可以围绕原点旋转结果点并相对于原点进行缩放。新点(作为向量)看起来像这样:

The same vectors as above, but translated around the origin

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

Why the origin

那么为什么要将这些点转换为原点呢?好吧,旋转和缩放动作很容易(在数学上)围绕原点进行,而不是在其他点周围容易。

此外,从现在开始,我将只在这些图像中包含第1,第2和第4点以节省一些空间。

Scaling around the origin

缩放操作在原点周围非常容易。只需将点的坐标乘以缩放系数:

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

以可视方式,看起来像这样(全部缩放1.5):

Scaled vectors and original vectors

其中蓝色箭头是原始矢量,红色箭头是缩放矢量。

Rotating

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

要乘以的矩阵如下

rotation matrix

(来自wikipedia: Rotation Matrix

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

因为在问题中只需要90°的倍数,矩阵变得几乎无足轻重。对于逆时针旋转90°,矩阵为:

Rotation matrix for 90° counterclockwise

这基本上是代码:

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

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

rotation 90° counterclockwise

在哪里我匹配了矢量的颜色。

顺时针旋转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的比例缩放,这基本上是相同的。

作为这些操作的最后一点,我可以补充说,您可以按顺序缩放和/或旋转,以获得所需的结果。

Translating back to the center point

在缩放动作和/或旋转之后,剩下的唯一事情是将向量重新转换到中心点。

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

一切都完成了。

Just a recap

所以回顾这篇长篇文章:

  1. 从图像点的坐标中减去中心点的坐标
  2. 通过简单地乘以坐标来缩放因子
  3. 使用矩阵乘法的思想来考虑旋转(你可以在Google或维基百科上轻松找到这些东西)。
  4. 将中心点的坐标添加到图像点的新坐标

我现在意识到我可以给出这个回顾,但是现在这篇文章中至少有一些视觉辅助和一些轻微的数学背景,这也很好。我真的相信这些问题应该从数学角度来看,数学描述可以帮助很多。

以上是关于如何在缩放和旋转后计算点的坐标?的主要内容,如果未能解决你的问题,请参考以下文章

JS中canvas画布绘制中如何实现缩放,位移,旋转

颤动 - 如何使用画布围绕中心旋转图像

java drawImage 如何实现旋转和缩放

2D图像处理:2D Shape_Base_Matching_缩放_旋转_ICP_显示ROI

推导坐标旋转公式

unity 3D 实现场景旋转平移缩放