NSRect vs CGRect:y轴反转

Posted

技术标签:

【中文标题】NSRect vs CGRect:y轴反转【英文标题】:NSRect vs CGRect: y-axis inversion 【发布时间】:2013-06-12 04:38:33 【问题描述】:

所以我正在尝试将 NSRect 转换为 CGRect。我使用了NSRectToCGRect(),它可以很好地复制所有内容,但没有考虑 y 原点轴。

问题:(0,0) 的 CGRect 原点在左上角。 NSRect 原点 (0,0) 在左下角。

因此,NSRect (0,0,100,100) 框位于屏幕左下方,而CGRect (0,0,100,100) 框位于屏幕左上方。

我有一个通过基本数学修正 y 原点的 hack:

fixedOriginY = screenHeight - NSRect.size.height - NSRect.origin.y

因此,NSRect (0,0,100,100) 的等价物实际上是 CGRect (0,800,100,100)(在我的 900 像素高度 MBA 上)。但是我不喜欢这样,我感觉它会破裂/出现视网膜问题或未来的并发症。

有没有人有关于如何正确地将 NSRect 转换为 CGRect 的解决方案或想法?

【问题讨论】:

是什么让您认为 CoreGraphics 的原点位于左上角?我只能立即找到对它的间接引用,但请参阅 developer.apple.com/library/ios/#documentation/2DDrawing/… — 搜索文本“Core Graphics 框架使用的默认坐标系是基于 LLO 的”。 (LLO = 左下原点) NSWindow 框架属性是一个 NSRect,所以我把它放在 0,0(屏幕左下角)。我将该帧转换为 CGRect,使用 CGDisplayCreateImageForRect(displays[0], windowCGRect) 截取屏幕截图。屏幕截图是屏幕左上角的。 不要认为这是CGRectNSRect 之间的区别。它们都只是简单的结构,它们的值仅相对于某个坐标系(提供或使用矩形的代码的坐标系)有意义。在这种情况下,AppKit 的屏幕坐标系和 CG 的显示空间坐标系之间存在差异,如this answer 中所述。 如果你只想截取一个窗口,你可以使用CGWindowListCreateImage()而不是CGDisplayCreateImageForRect() 【参考方案1】:

矩形的原点是在左上角还是左下角取决于您使用矩形的坐标系。它不取决于您使用的是CGRect 还是NSRect

通常,AppKit 使用以左下角为原点的坐标系。同样,您创建的 CGContext 将原点放在左下方。

另一方面,Quartz Event Services 和 Quartz Display Services 将原点放在左上角。 UIKit(在 iOS 上)将原点放在左上角。您可以在 NSView 子类(在 OS X 上)中覆盖 isFlipped,使其原点位于左上角。

当您将矩形从传统(左下原点)转换为翻转(左上原点)坐标系时,您的基本数学是必要且正确的。

【讨论】:

窗口框架(例如-[NSWindow frame])位于屏幕坐标空间,其原点是左下角。 Quartz Display Services 使用全局或局部桌面坐标空间,其原点是对应的左上角。

以上是关于NSRect vs CGRect:y轴反转的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Octave 中反转 x 和 y 轴?

在 PyPlot 中反转 Y 轴

停止相机中的Y轴反转

配置 Kivy > y 轴反转输入

OpenGL:切换和反转轴

PyQwt 反转轴(或,设置 PyQwt 属性)