如何确定一个3D旋转对象距离屏幕边缘的距离?

6
我使用Core Animation将一个视图围绕y轴旋转了50度。我希望视图的边缘能够触碰到屏幕的边缘。我知道视图的长度以及被旋转的角度(50度),所以起初,我认为可以使用三角函数来确定视图与边缘之间的距离。然而,相机的透视效果受到CATransform3D结构体的m34属性影响。那么,我该如何计算需要移动视图的距离才能将其与屏幕的边缘对齐?
CATransform3D rotation = CATransform3DIdentity;
rotation.m34  = -1.0/500.0;
rotation = CATransform3DRotate(rotation, 50.0 * M_PI / 180, 0.0, 1.0, 0.0);
view.layer.transform = rotation;
view.layer.zPosition = 200;

enter image description here


转换对象的框架的默认值保持不变。框架是可以包含相关视图的整个最小未转换矩形,那么为什么这仍然无法工作呢? - CodaFi
你真的需要将视图沿着Z轴进行翻译吗? - Jonathan Cichon
@CodaFi,我认为将框架与超级视图的边缘对齐不起作用,来自苹果公司的信息:如果此属性不是恒等变换,则框架属性的值未定义,因此应忽略它。 - marchinram
@marchinram 那么文档是错误的。当图层被转换时,frame是完全定义的。事实上,几个WWDC UIKit会话甚至有关于它如何工作的图表(请参见WWDC 2011 的 UIKit 渲染会话)。 - CodaFi
@CodaFi它被定义了,但我认为他们的意思是如果变换不是恒等变换,则不能依赖于它进行定位。为了测试,我创建了一个50个点宽的UIView,并将其完全转换为上述内容,之后边界宽度为50,框架宽度为32.139381。所以真正的未定义是错误的词,但框架受到变换的影响,而边界则没有,无论如何,我认为您不能使用框架来解决杰克的问题。 - marchinram
2个回答

1
如果我理解您的意思正确,您想要类似以下的内容:

Final view

为了方便计算,您需要调整CALayer的anchorPoint。anchorPoint是应用变换的位置,其效果在旋转中尤其明显。我们要做的是告诉CALayer围绕其中一个点旋转,而不是中心(这是默认值)。
这是我的loadView:
UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
view.backgroundColor = [UIColor whiteColor];

CGRect frame = CGRectMake(view.frame.size.width - 100.f,
                          view.frame.size.height / 2.f - 50.f,
                          100.f, 100.f);
UIView *red = [[UIView alloc] initWithFrame:frame];
red.backgroundColor = [UIColor redColor];
[view addSubview:red];

CATransform3D rotation = CATransform3DIdentity;
rotation.m34  = -1.0/500.0;
// Since the anchorPoint is displaced from the center, the position will move with
// it, so we have to counteract it by translating the layer half its width.
rotation = CATransform3DTranslate(rotation, 50.f, 0, 0);
rotation = CATransform3DRotate(rotation, 50.0 * M_PI / 180, 0.0, 1.0, 0.0);
// We tell the anchorPoint to be on the right side of the layer (the anchor point
// position is specified between 0.0-1.0 for both axis).
red.layer.anchorPoint = CGPointMake(1.f, 0.5f);
red.layer.transform = rotation;
red.layer.zPosition = 200;

我得到的是你在上面看到的图片。

希望能有所帮助!


0

您想将最终的变换矩阵(包括M34更改)应用于您正在尝试计算距离的视图边缘的端点。这将为您提供投影空间中您的点的最终位置。

iOS 5添加了GLKit,其中包括一整个库的函数来进行矩阵和向量计算。例如,请查看GLKMatrix4MultiplyVector3。该函数接受一个由3部分组成的向量,并将其乘以4x4矩阵,返回一个结果为3个分量的向量。

您可能需要GLKMatrix4MultiplyVector4,因为如果我记得正确,您希望您的向量比轴的数量多1个分量(因此对于3D向量,您需要一个4个分量的向量)。向量数学不是我的强项,所以当我需要使用它时,我必须查找这些内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接