上一篇我們用CABasicAnimation 來模擬了太陽(yáng)-地球-月球的天體運(yùn)動(dòng)。其中月球繞太陽(yáng)運(yùn)動(dòng)和月球繞地球運(yùn)動(dòng)都可以看做一個(gè)點(diǎn)繞另一個(gè)點(diǎn)作圓周運(yùn)動(dòng)。(當(dāng)然現(xiàn)實(shí)中是橢圓運(yùn)動(dòng),有遠(yuǎn)地點(diǎn)念赶,近地點(diǎn)疚察,這里我們看作圓周運(yùn)動(dòng))
一個(gè)點(diǎn)繞另一個(gè)點(diǎn)作圓周運(yùn)動(dòng),是不是很熟悉惊楼。對(duì),就是我們之前學(xué)習(xí)的數(shù)學(xué)知識(shí)秸讹,這里完全可以用數(shù)學(xué)知識(shí)做檀咙。
相關(guān)數(shù)學(xué)知識(shí)點(diǎn): 任意點(diǎn)a(x,y),繞一個(gè)坐標(biāo)點(diǎn)b(rx0,ry0)逆時(shí)針旋轉(zhuǎn)a角度后的新的坐標(biāo)設(shè)為c(x0, y0)璃诀,有公式:
x0= (x - rx0)*cos(a) - (y - ry0)*sin(a) + rx0 ;
y0= (x - rx0)*sin(a) + (y - ry0)*cos(a) + ry0 ;
OK弧可,有這些數(shù)學(xué)基礎(chǔ),那我們就很好做了劣欢,我們讓地月系統(tǒng)繞太陽(yáng)轉(zhuǎn)的效果用數(shù)學(xué)方法來實(shí)現(xiàn)侣诺。太陽(yáng)(sunNode)是b點(diǎn),地月系統(tǒng)(earthGroupNode)是a點(diǎn)氧秘,我們將地月系統(tǒng)添加到太陽(yáng)里面:
[_sunNode addChildNode:_earthGroupNode];
那么相對(duì)于a點(diǎn)來說年鸳,b點(diǎn)的坐標(biāo)就是(0,0),然后我們通過計(jì)算得到c點(diǎn)丸相,讓c點(diǎn)的坐標(biāo)重新賦值給earthGroupNode 的 position 就可以了搔确。代碼如下:
// custom Action
float totalDuration =10.0f;????//10s 圍繞地球轉(zhuǎn)一圈
float duration = totalDuration/360;????//每隔duration秒去執(zhí)行一次
SCNAction *customAction = [SCNAction customActionWithDuration:duration actionBlock:^(SCNNode * _Nonnull node, CGFloat elapsedTime){
????if(elapsedTime==duration){? ? ? ? ? ??
????????SCNVector3 position = node.position;
????????float rx0 =0;????//原點(diǎn)為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 去循環(huán)計(jì)算賦值,其實(shí)最主要的就是actionBlock 里面的代碼灭忠,你也可以完全用線程sleep 和 NSTimer 去實(shí)現(xiàn)膳算。
最終實(shí)現(xiàn)效果:
引出的問題:我們可以看到上面數(shù)學(xué)方法的局限性,y 軸的值一直沒變弛作,因?yàn)槿齻€(gè)天體都處于X-Z這一平面涕蜂,如果他們 y 值不一樣,沒有處于X-Z這一平面映琳。即一個(gè)三維點(diǎn)繞著另一個(gè)三維點(diǎn)做圓周運(yùn)動(dòng)机隙,數(shù)學(xué)方法該怎么實(shí)現(xiàn)?
demo 代碼已上傳到github