gpt4 book ai didi

iphone - 尝试在核心动画中使用透视变换失败

转载 作者:行者123 更新时间:2023-12-03 19:15:11 26 4
gpt4 key购买 nike

我正在尝试创建一个简单的 iPhone 应用程序,该应用程序显示下面带有反射的图片,并且我想使用 Core Animation 绕 X 轴旋转图片。

我首先使用“基于 View 的应用程序”模板创建一个新的 iPhone 应用程序。我添加了一个“Picture.jpg”图像文件,然后将其添加到 View Controller 中:

- (void)awakeFromNib {
CGFloat zDistance = 1500.0f;

// Create perspective transformation
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0f / -zDistance;

// Create perspective transform for reflected layer
CATransform3D reflectedTransform = CATransform3DMakeRotation(M_PI, 1.0f, 0.0f, 0.0f);
reflectedTransform.m34 = 1.0f / -zDistance;

// Create spinning picture
CALayer *spinningLayer = [CALayer layer];
spinningLayer.frame = CGRectMake(60.0f, 60.0f, 200.0f, 300.0f);
spinningLayer.contents = (id)[UIImage imageNamed:@"Picture.jpg"].CGImage;
spinningLayer.transform = transform;

// Create reflection of spinning picture
CALayer *reflectionLayer = [CALayer layer];
reflectionLayer.frame = CGRectMake(60.0f, 360.0f, 200.0f, 300.0f);
reflectionLayer.contents = (id)[UIImage imageNamed:@"Picture.jpg"].CGImage;
reflectionLayer.opacity = 0.4f;
reflectionLayer.transform = reflectedTransform;

// Add layers to the root layer
[self.view.layer addSublayer:spinningLayer];
[self.view.layer insertSublayer:reflectionLayer below:spinningLayer];

// Spin the layers
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
anim.fromValue = [NSNumber numberWithFloat:0.0f];
anim.toValue = [NSNumber numberWithFloat:(2 * M_PI)];
anim.duration = 3.0f;
anim.repeatCount = 1e100f;
[spinningLayer addAnimation:anim forKey:@"anim"];
[reflectionLayer addAnimation:anim forKey:@"anim"];
}

几乎有效。问题在于主图像和反射的旋转并不完全同步。它非常接近完美,但图片底部的边缘和反射顶部的边缘相距几个像素。它们似乎存在一些程度的差异。

在屏幕左侧,倒影似乎位于图片的“前方”,而在右侧,倒影则位于图片的“前方”。换句话说,看起来顶部图像的底角被推向屏幕,而反射的顶角被拉向观看者。当图像旋转时观察图像的正面和背面时都是如此。

如果我增加zDistance,效果就不那么明显了。如果我通过将两个层的 transform.m34 都设置为零来完全消除透视变换,那么图片和反射看起来会完美同步。所以我不认为这个问题与时间同步问题有关。

我怀疑我的视角转换遗漏了一些东西,但我不确定如何确定哪里出了问题。我想我基本上正在做 this related Stack Overflow question 中描述的相同转换.

有人可以帮忙吗?

最佳答案

我想我可能已经找到了我的问题的答案。在我的原始代码中,我通过将其放置在图片下方并应用翻转和透视来创建反射。正确的方法似乎是将反射放置在与图片相同的位置,应用平移和旋转变换以使其到达正确的位置,然后应用透视变换。

当旋转动画时,需要以与图片动画相反的方向旋转反射。

所以,这是有效的代码:

- (void)awakeFromNib {
CGFloat zDistance = 1500.0f;

// Create perspective transformation
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0f / -zDistance;

// Create perspective transform for reflected layer
CATransform3D reflectedTransform = CATransform3DMakeTranslation(0.0f, 300.0f, 0.0f);
reflectedTransform = CATransform3DRotate(reflectedTransform, M_PI, 1.0f, 0.0f, 0.0f);
reflectedTransform.m34 = 1.0f / -zDistance;

// Create spinning picture
CALayer *spinningLayer = [CALayer layer];
spinningLayer.frame = CGRectMake(60.0f, 60.0f, 200.0f, 300.0f);
spinningLayer.contents = (id)[UIImage imageNamed:@"Picture.jpg"].CGImage;
spinningLayer.transform = transform;

// Create reflection of spinning picture
CALayer *reflectionLayer = [CALayer layer];
reflectionLayer.frame = CGRectMake(60.0f, 60.0f, 200.0f, 300.0f);
reflectionLayer.contents = (id)[UIImage imageNamed:@"Picture.jpg"].CGImage;
reflectionLayer.opacity = 0.4f;
reflectionLayer.transform = reflectedTransform;

// Add layers to the root layer
[self.view.layer addSublayer:spinningLayer];
[self.view.layer insertSublayer:reflectionLayer below:spinningLayer];

// Spin the layers
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
anim.fromValue = [NSNumber numberWithFloat:0.0f];
anim.toValue = [NSNumber numberWithFloat:(2 * M_PI)];
anim.duration = 3.0f;
anim.repeatCount = 1e100f;
[spinningLayer addAnimation:anim forKey:@"anim"];

CABasicAnimation *reflectAnim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
reflectAnim.fromValue = [NSNumber numberWithFloat:0.0f];
reflectAnim.toValue = [NSNumber numberWithFloat:(-2 * M_PI)];
reflectAnim.duration = 3.0f;
reflectAnim.repeatCount = 1e100f;
[reflectionLayer addAnimation:reflectAnim forKey:@"reflectAnim"];
}

我不确定为什么会这样。对我来说,将反射放置在与原始图像相同的位置,然后以某种方式对其进行变换,将两个图像放入相同的“变换空间”中,这是很直观的,但如果有人能够解释其背后的数学原理,我将不胜感激。

完整项目可在 GitHub 上获取:https://github.com/kristopherjohnson/perspectivetest

关于iphone - 尝试在核心动画中使用透视变换失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2262994/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com