CGAffineTransform 文档中可能存在错误
Possible error in CGAffineTransform documentation
在 CGAffineTransform 文档中 https://developer.apple.com/documentation/coregraphics/cgaffinetransform the equations that transform point (x, y) to point (x’,y’) are as follows: x'=ax+cy+t_x, y'=bx+dy+t_y. Consider the case where we have scaling on a view. Then the equations become x'=ax, y'=dy. This means that according to the equations the point that remains at the same position after the scaling is (0,0). However, the point that remains at the same position is the center of the view. This can be seen in practice, as well as here: https://developer.apple.com/documentation/quartzcore/calayer/1410817-anchorpoint。
我的问题是:CGAffineTransform 文档中提供的方程是否确实不正确?
我不确定你从哪里得到 This means that according to the equations the point that remains at the same position after the scaling is (0,0).
。
如果您只是缩放视图,中心点本身不会改变,因此 t_x
和 t_y
不会改变,只有您看到的缩放比例,即系数 a
x 和 d
y 改变;因此,当缩放 x' = ax
和 y' = dy
.
例如,如果您在图像上缩放,假设您当前的中心点是图像的中心。如果缩放,您将缩放图像的中心。如果用户滑动图像,那将不再是视图上的唯一缩放。
此外,(0,0)
点不一样;唯一保持不变的点是中心。假设您可以看到 (0,0,400,400)
的完整图像 - 点 (0,0)
位于左上角,(200,200)
位于中心。如果您放大 DOUBLE,您现在将在左上角看到 (100,100)
,在中间看到 (200,200)
。注:(0,0)
没有保持不变,但中心保持不变。
答案:否
您基本上是在对术语 x 和 y 模棱两可。给出的公式是抽象的仿射变换的正确线性代数公式。但是没有说明如何将其应用于特定视图。
其实,“保持在同一位置的点”是任意的。您可以将其设置为任何 视角。默认情况下它是边界中点,但您可以更改它(通过更改视图底层的锚点)。
所以您只需要了解,为了转换的目的,“原点”就是您所说的任何地方。默认情况下,它是边界中点。
为了更清楚地看到这一点,请使用 CGPoint 的 applying
方法,它实际上为您执行转换:
let p = CGPoint.zero
let pprime = p.applying(CGAffineTransform(scaleX: 2, y: 2))
print(pprime)
结果是.zero
。因此,可以肯定的是,无论我们认为是变换目的的原点,都不会因为变换而移动。但是这里没有关于特定视图 的哪个点 是出于转换目的的原点。没有上下文,它只是纯数学——你开始使用的方程式也是如此。
This means that according to the equations the point that remains at the same position after the scaling is (0,0).
没错。但是 (0,0) 是锚点,而不是我相信您期望的“视图边界原点”。
However, the point that remains at the same position is the center of the view.
没错。因为那是锚点所在。
您甚至 link 阅读对此进行解释的文档。变换应用于基于锚点的坐标 space。默认锚点位于视图的中心。这与 bounds
.
的坐标 space 无关
CALayer 在从 (0,0) 到 (1,1) 的坐标 space 中工作,以 (0.5, 0.5) 为中心。默认锚点为中心,但可以移动
文档对此非常清楚。他们没有误导或不正确:
This property [transform] is set to the identity transform by default. Any transformations you apply to the layer occur relative to the layer’s anchor point.
为了使变换“相对于图层的锚点”,可以应用缩放和平移。没关系;这就是仿射变换的工作原理。它们可以自由组合,在坐标space之间移动。如果你想让坐标space锚定在左上角,移动锚点。
在 CGAffineTransform 文档中 https://developer.apple.com/documentation/coregraphics/cgaffinetransform the equations that transform point (x, y) to point (x’,y’) are as follows: x'=ax+cy+t_x, y'=bx+dy+t_y. Consider the case where we have scaling on a view. Then the equations become x'=ax, y'=dy. This means that according to the equations the point that remains at the same position after the scaling is (0,0). However, the point that remains at the same position is the center of the view. This can be seen in practice, as well as here: https://developer.apple.com/documentation/quartzcore/calayer/1410817-anchorpoint。
我的问题是:CGAffineTransform 文档中提供的方程是否确实不正确?
我不确定你从哪里得到 This means that according to the equations the point that remains at the same position after the scaling is (0,0).
。
如果您只是缩放视图,中心点本身不会改变,因此 t_x
和 t_y
不会改变,只有您看到的缩放比例,即系数 a
x 和 d
y 改变;因此,当缩放 x' = ax
和 y' = dy
.
例如,如果您在图像上缩放,假设您当前的中心点是图像的中心。如果缩放,您将缩放图像的中心。如果用户滑动图像,那将不再是视图上的唯一缩放。
此外,(0,0)
点不一样;唯一保持不变的点是中心。假设您可以看到 (0,0,400,400)
的完整图像 - 点 (0,0)
位于左上角,(200,200)
位于中心。如果您放大 DOUBLE,您现在将在左上角看到 (100,100)
,在中间看到 (200,200)
。注:(0,0)
没有保持不变,但中心保持不变。
答案:否
您基本上是在对术语 x 和 y 模棱两可。给出的公式是抽象的仿射变换的正确线性代数公式。但是没有说明如何将其应用于特定视图。
其实,“保持在同一位置的点”是任意的。您可以将其设置为任何 视角。默认情况下它是边界中点,但您可以更改它(通过更改视图底层的锚点)。
所以您只需要了解,为了转换的目的,“原点”就是您所说的任何地方。默认情况下,它是边界中点。
为了更清楚地看到这一点,请使用 CGPoint 的 applying
方法,它实际上为您执行转换:
let p = CGPoint.zero
let pprime = p.applying(CGAffineTransform(scaleX: 2, y: 2))
print(pprime)
结果是.zero
。因此,可以肯定的是,无论我们认为是变换目的的原点,都不会因为变换而移动。但是这里没有关于特定视图 的哪个点 是出于转换目的的原点。没有上下文,它只是纯数学——你开始使用的方程式也是如此。
This means that according to the equations the point that remains at the same position after the scaling is (0,0).
没错。但是 (0,0) 是锚点,而不是我相信您期望的“视图边界原点”。
However, the point that remains at the same position is the center of the view.
没错。因为那是锚点所在。
您甚至 link 阅读对此进行解释的文档。变换应用于基于锚点的坐标 space。默认锚点位于视图的中心。这与 bounds
.
CALayer 在从 (0,0) 到 (1,1) 的坐标 space 中工作,以 (0.5, 0.5) 为中心。默认锚点为中心,但可以移动
文档对此非常清楚。他们没有误导或不正确:
This property [transform] is set to the identity transform by default. Any transformations you apply to the layer occur relative to the layer’s anchor point.
为了使变换“相对于图层的锚点”,可以应用缩放和平移。没关系;这就是仿射变换的工作原理。它们可以自由组合,在坐标space之间移动。如果你想让坐标space锚定在左上角,移动锚点。