使用纵横比旋转 2D 矢量

Posted

技术标签:

【中文标题】使用纵横比旋转 2D 矢量【英文标题】:Rotate 2D Vector with an Aspect Ratio 【发布时间】:2018-09-02 22:57:16 【问题描述】:

我们中的许多人都熟悉在给定角度theta 的情况下围绕原点旋转二维矢量的方法:

newX = x * cos(theta) - y * sin(theta);
newY = x * sin(theta) + y * cos(theta);

我现在正在尝试旋转图像 UV 空间中的坐标,如下所示:

(图片借自this SO question。)

这里u 轴的单位比v 轴的单位宽,因此上述方法导致坐标围绕椭圆而不是圆旋转。我需要旋转矢量以使坐标看起来像正方形,这意味着需要考虑纵横比。我认为它就像将坐标拉伸到方形空间一样简单,旋转,然后向后拉伸,尽管看起来矢量仍然是椭圆旋转的:

newX = (x * cos(theta) * Aspect - y * sin(theta)) / Aspect;
newY = x * sin(theta) * Aspect + y * cos(theta);

任何帮助表示赞赏,在此先感谢!

【问题讨论】:

您的方法看起来不错。也许您对 Aspect 使用了错误的值?尝试使用 1/你现在使用的值。 所以你想要“0.5 |顶部 1 英寸点与矩形边的水平中线相交? 【参考方案1】:

旋转和纵横比的通用版本是:

(center_c, center_y) 为旋转中心

(aspect_x, aspect_y) 是 aspect_ratio

tmp_x = (x-center_x)/aspect_x
tmp_y = (y-center_y)/aspect_y
tmp_x = tmp_x * cos(theta) - tmp_y * sin(theta)
tmp_x = tmp_x * sin(theta) + tmp_y * cos(theta)
new_x = aspect_x*tmp_x-center_x
new_y = aspect_y*tmp_x-center_y

希望对您有所帮助。

【讨论】:

尝试将纵横比部分移动到 sin/cos 部分之外,就像您的示例中一样,它似乎仍然是椭圆形移动 你的旋转中心是 (0,0) 吗?选择你的一个点说 (x1, y1) 并旋转 pi/2 你应该得到一个坐标为 (-y1, x1) 如果这不是你得到的点,请提供数值。 我发现了这个问题,结果我笨拙地使用错误的值来计算我的纵横比。现在这两种方法(问题中的原始方法以及您提出的方法)都可以完美运行。感谢您的帮助!

以上是关于使用纵横比旋转 2D 矢量的主要内容,如果未能解决你的问题,请参考以下文章

旋转 UIView 并在旋转后保持纵横比

XCode:调整图像大小使用纵横比并向下移动图像下方的元素

Javascript - 旋转画布导致拉伸[重复]

使用纵横比和空白区域裁剪图像

android相机预览错误的纵横比

html5视频android:全屏保持纵横比