ios 3D引擎 SceneKit 开发(5) --关于旋转的几点问题(2)
2016-05-07 15:31
246 查看
如果还没看前一篇,可以移驾看看:ios 3D引擎 SceneKit 开发(4) –关于旋转的几点问题(1)
上一篇我们用CABasicAnimation 来模拟了太阳-地球-月球的天体运动。其中月球绕太阳运动和月球绕地球运动都可以看做一个点绕另一个点作圆周运动。(当然现实中是椭圆运动,有远地点,近地点,这里我们看作圆周运动)
一个点绕另一个点作圆周运动,是不是很熟悉。对,就是我们之前学习的数学知识,这里完全可以用数学知识做。
相关数学知识点: 任意点a(x,y),绕一个坐标点b(rx0,ry0)逆时针旋转a角度后的新的坐标设为c(x0, y0),有公式:
OK,有这些数学基础,那我们就很好做了,我们让地月系统绕太阳转的效果用数学方法来实现。太阳(sunNode)是b点,地月系统(earthGroupNode)是a点,我们将地月系统添加到太阳里面:
那么相对于a点来说,b点的坐标就是(0,0),然后我们通过计算得到c点,让c点的坐标重新赋值给earthGroupNode 的 position 就可以了。代码如下:
从上面可以看出我们用了SceneKit 的API SCNAction 去循环计算赋值,其实最主要的就是actionBlock 里面的代码,你也可以完全用线程sleep 和 NSTimer 去实现。
最终实现效果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/04/49f746e601e236280d01a152ce874f71)
引出的问题:我们可以看到上面数学方法的局限性,y 轴的值一直没变,因为三个天体都处于X-Z这一平面,如果他们 y 值不一样,没有处于X-Z这一平面。即一个三维点绕着另一个三维点做圆周运动,数学方法该怎么实现?
demo 代码已上传到github
https://github.com/pzhtpf/SceneKitRoationDemo
上一篇我们用CABasicAnimation 来模拟了太阳-地球-月球的天体运动。其中月球绕太阳运动和月球绕地球运动都可以看做一个点绕另一个点作圆周运动。(当然现实中是椭圆运动,有远地点,近地点,这里我们看作圆周运动)
一个点绕另一个点作圆周运动,是不是很熟悉。对,就是我们之前学习的数学知识,这里完全可以用数学知识做。
相关数学知识点: 任意点a(x,y),绕一个坐标点b(rx0,ry0)逆时针旋转a角度后的新的坐标设为c(x0, y0),有公式:
x0= (x - rx0)*cos(a) - (y - ry0)*sin(a) + rx0 ; y0= (x - rx0)*sin(a) + (y - ry0)*cos(a) + ry0 ;
OK,有这些数学基础,那我们就很好做了,我们让地月系统绕太阳转的效果用数学方法来实现。太阳(sunNode)是b点,地月系统(earthGroupNode)是a点,我们将地月系统添加到太阳里面:
[_sunNode addChildNode:_earthGroupNode];
那么相对于a点来说,b点的坐标就是(0,0),然后我们通过计算得到c点,让c点的坐标重新赋值给earthGroupNode 的 position 就可以了。代码如下:
// custom Action float totalDuration = 10.0f; //10s 围绕地球转一圈 float duration = totalDuration/360; //每隔duration秒去执行一次 SCNAction *customAction = [SCNAction customActionWithDuration:duration actionBlock:^(SCNNode * _Nonnull node, CGFloat elapsedTime){ if(elapsedTime==duration){ SCNVector3 position = node.position; float rx0 = 0; //原点为0 float ry0 = 0; float angle = 1.0f/180*M_PI; float x = (position.x - rx0)*cos(angle) - (position.z - ry0)*sin(angle) + rx0 ; float z = (position.x - rx0)*sin(angle) + (position.z - ry0)*cos(angle) + ry0 ; node.position = SCNVector3Make(x, node.position.y, z); } }]; SCNAction *repeatAction = [SCNAction repeatActionForever:customAction]; [_earthGroupNode runAction:repeatAction];
从上面可以看出我们用了SceneKit 的API SCNAction 去循环计算赋值,其实最主要的就是actionBlock 里面的代码,你也可以完全用线程sleep 和 NSTimer 去实现。
最终实现效果:
引出的问题:我们可以看到上面数学方法的局限性,y 轴的值一直没变,因为三个天体都处于X-Z这一平面,如果他们 y 值不一样,没有处于X-Z这一平面。即一个三维点绕着另一个三维点做圆周运动,数学方法该怎么实现?
demo 代码已上传到github
https://github.com/pzhtpf/SceneKitRoationDemo
相关文章推荐
- ios开发学习笔记--数据持久化之Core Data
- [置顶] iOS的开发中的错误解决方案
- iOS 多线程学习
- 【转】DSP/BIOS中的SEM
- iOS 集成环信(四)
- iOS 视图抖动动画
- iOS 正则表达式 NSRegularExpression
- IOS 数据存储
- iOS开发中常见的宏
- IOS开发:截取当前视图
- iOS多线程
- 大家好,我是筱鹏,日后我将会在我的博客不定期更新IOS开发的自定实用小功能
- iOS - 定时器
- iOS动画大全
- 在MAC上为ios交叉编译mono的AOT工具
- 如何集成百度地图ApI?
- iOS学习笔记——数据请求
- IOS轻松入门一
- XIB、Storyboard操作小技巧
- IOS遍历网页获取网页中<img>标签中的图片url