首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS CATransform3D坐标

iOS CATransform3D坐标
EN

Stack Overflow用户
提问于 2012-01-04 16:35:25
回答 1查看 3.5K关注 0票数 3

会非常感谢你在这方面的帮助。我已经在视图上应用了3D转换,并且需要识别渲染视图的边缘坐标,这样我就可以显示与其相邻的另一个视图(没有任何像素间隙)。具体地说,我想要一系列的视图(“页面”)折叠起来像一个传单,通过动画的角度。

代码语言:javascript
复制
    int dir = (isOddNumberedPage ? 1 : -1);
    float angle = 10.0;

    theView.frame = CGRectMake(pageNumber * 320, 0, 320, 460);        
    CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
    rotationAndPerspectiveTransform.m34 = -1.0 / 2000; // Perspective
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 
           dir * angle / (180.0 / M_PI), 0.0f, 1.0f, 0.0f);
    theView.layer.transform = rotationAndPerspectiveTransform;

    // Now need to get the top, left, width, height of the transformed view to correct the view's left offset

我已经尝试了很多方法来做到这一点,通过检查CALayer,一个失败的尝试使用我发现的一些矩阵数学代码片段,但无法破解它,甚至无法接近它(取决于角度,20个像素)。有没有办法让我不用花两周的时间阅读矩阵数学教科书就能做到这一点?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-05 03:05:09

视图的框架是superview坐标系中的轴对齐矩形。框架完全包围了视图的边界。如果视图被转换,框架将调整为紧密包围视图的新边界。

对视图应用Y轴旋转和透视时,视图的左右边缘将朝向其锚点(通常是视图的中心)移动。左边缘也会变得更高或更短,而右边缘则相反。

因此,视图的框架(在应用转换之后)将为您提供转换后视图的左侧坐标和宽度,以及较高边缘(可能是左侧边缘或右侧边缘)的顶部和高度。下面是我的测试代码:

代码语言:javascript
复制
NSLog(@"frame before tilting = %@", NSStringFromCGRect(self.tiltView.frame));
float angle = 30.0;
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = -1.0 / 2000; // Perspective
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 
       1 * angle / (180.0 / M_PI), 0.0f, 1.0f, 0.0f);
self.tiltView.layer.transform = rotationAndPerspectiveTransform;
NSLog(@"frame after tilting = %@", NSStringFromCGRect(self.tiltView.frame));

下面是输出:

代码语言:javascript
复制
2012-01-04 12:44:08.405 layer[72495:f803] frame before tilting = {{50, 50}, {220, 360}}
2012-01-04 12:44:08.406 layer[72495:f803] frame after tilting = {{62.0434, 44.91}, {190.67, 370.18}}

您还可以使用convertPoint:fromView:convertPoint:toView:在superview的坐标空间中获取视图各个角的坐标。测试代码:

代码语言:javascript
复制
    CGRect bounds = self.tiltView.bounds;
    CGPoint upperLeft = bounds.origin;
    CGPoint upperRight = CGPointMake(CGRectGetMaxX(bounds), bounds.origin.y);
    CGPoint lowerLeft = CGPointMake(bounds.origin.x, CGRectGetMaxY(bounds));
    CGPoint lowerRight = CGPointMake(upperRight.x, lowerLeft.y);
#define LogPoint(P) NSLog(@"%s = %@ -> %@", #P, \
    NSStringFromCGPoint(P), \
    NSStringFromCGPoint([self.tiltView.superview convertPoint:P fromView:self.tiltView]))
    LogPoint(upperLeft);
    LogPoint(upperRight);
    LogPoint(lowerLeft);
    LogPoint(lowerRight);

输出:

代码语言:javascript
复制
2012-01-04 13:03:00.663 layer[72635:f803] upperLeft = {0, 0} -> {62.0434, 44.91}
2012-01-04 13:03:00.663 layer[72635:f803] upperRight = {220, 0} -> {252.713, 54.8175}
2012-01-04 13:03:00.663 layer[72635:f803] lowerLeft = {0, 360} -> {62.0434, 415.09}
2012-01-04 13:03:00.663 layer[72635:f803] lowerRight = {220, 360} -> {252.713, 405.182}

请注意,在superview的坐标系中,upperLeft和upperRight点的Y坐标是不同的。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8724031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档