p5.js臨摹旋轉(zhuǎn)愛(ài)心
運(yùn)用p5.js臨摹旋轉(zhuǎn)愛(ài)心,供大家參考,具體內(nèi)容如下
原圖

我的臨摹

效果不錯(cuò)的樣子,讓我們看看實(shí)現(xiàn)過(guò)程。
第一步、分析原圖GIF
因?yàn)樵瓐D中旋轉(zhuǎn)速度較快,無(wú)法用肉眼直觀地找到規(guī)律。所以我把gif分解,共90幀,一幀一幀的尋找旋轉(zhuǎn)規(guī)律。

從上往下順序,第一層到第六層。從簡(jiǎn)單的說(shuō)起。
第六層:逆時(shí)針勻速旋轉(zhuǎn)一圈。
第五層:先逆時(shí)針旋轉(zhuǎn)α,速度由v1變?yōu)?。再順時(shí)針旋轉(zhuǎn)180°+2α,速度由0變?yōu)関2,再變?yōu)?。最后逆時(shí)針旋轉(zhuǎn)α,速度由0變?yōu)関1。(觀察原圖,我將α設(shè)為30°0)
第四層:先逆時(shí)針旋轉(zhuǎn)α,再順時(shí)針旋轉(zhuǎn)3×180°+2α,最后逆時(shí)針旋轉(zhuǎn)α。速度規(guī)律與第五層相同。
第三層:先逆時(shí)針旋轉(zhuǎn)α,再順時(shí)針旋轉(zhuǎn)5×180°+2α,最后逆時(shí)針旋轉(zhuǎn)α。速度規(guī)律與第五層相同。
第二層:先逆時(shí)針旋轉(zhuǎn)α,再順時(shí)針旋轉(zhuǎn)7×180°+2α,最后逆時(shí)針旋轉(zhuǎn)α。速度規(guī)律與第五層相同。
第一層:先逆時(shí)針旋轉(zhuǎn)α,再順時(shí)針旋轉(zhuǎn)9×180°+2α,最后逆時(shí)針旋轉(zhuǎn)α。速度規(guī)律與第五層相同。
(注:使用時(shí)記得轉(zhuǎn)化為弧度制。)
第二步、繪制基本形狀
首先創(chuàng)建畫(huà)布,設(shè)置背景色
function setup() {
createCanvas(windowWidth, windowHeight,WEBGL);
}
function draw() {
background(220);
}
繪制第一層立方體
值得注意的是translate()函數(shù)使用的是偏移量,而不是坐標(biāo)值。
function drawHeart1(BoxSize,posX,posY,posZ,r,g,b) //第一排方塊
{
fill(r,g,b);
translate(posX-(10/9)*BoxSize,posY,posZ);
box(BoxSize);
translate(-(10/9)*BoxSize,0,0);
box(BoxSize);
translate(3*(10/9)*BoxSize,0,0);
box(BoxSize);
translate((10/9)*BoxSize,0,0);
box(BoxSize);
translate(0,0,(10/9)*BoxSize);
box(BoxSize);
translate(-(10/9)*BoxSize,0,0);
box(BoxSize);
translate(-2*(10/9)*BoxSize,0,0);
box(BoxSize);
translate(-(10/9)*BoxSize,0,0);
box(BoxSize);
}
在draw()函數(shù)中,添加代碼。
drawHearts()中第一個(gè)參數(shù)是立方體的邊長(zhǎng),第二到第四個(gè)參數(shù)是XYZ軸的偏移量,最后三個(gè)為立方體顏色RGB值。
push(); translate(0,0); drawHeart1(40*size1,0,-2*40*10/9,-20,251,68,104); pop();
以此類推畫(huà)出其余五層的立方體。

效果圖如上(此處調(diào)整了一下相機(jī)位置)
第三步、旋轉(zhuǎn)
在之前繪制每一層時(shí),要注意物體的X、Z為0,因?yàn)閞otateY()函數(shù)繞Y軸旋轉(zhuǎn),否則每一層在旋轉(zhuǎn)時(shí)不是以繞其中心旋轉(zhuǎn)。
第六層的旋轉(zhuǎn)
①設(shè)置旋轉(zhuǎn)角度變量

②在draw()函數(shù)中關(guān)于第六層代碼。其中theta6-=360*PI/180/90表示一幀旋轉(zhuǎn)的弧度增量。

②在draw()函數(shù)中關(guān)于第五層代碼。

③RotateCubes5()函數(shù)。第一個(gè)參數(shù)表示逆時(shí)針旋轉(zhuǎn)角度,第二個(gè)參數(shù)表示順時(shí)針旋轉(zhuǎn)角度的二分之一,第四、五、六個(gè)參數(shù)用來(lái)判斷旋轉(zhuǎn)時(shí)幀的范圍,并用于計(jì)算旋轉(zhuǎn)角度。
以第一個(gè)if語(yǔ)句為例
在第一幀到第f1幀時(shí),theta5減小,即實(shí)現(xiàn)逆時(shí)針繞Y軸旋轉(zhuǎn)。其中,frameCount表示當(dāng)前第幾幀。frameCount%90,因?yàn)樵瓐D有90幀。(f1-frameCount%90)* delta1 * PI *180/Summation(0,f1-1)實(shí)現(xiàn)1到f1范圍內(nèi)當(dāng)前幀數(shù)越大,旋轉(zhuǎn)弧度越小。
function RotateCubes5(delta1,delta2,f1,f2,f3){
if(frameCount%90>=1&&frameCount%90<=f1)
{
theta5-=(f1-frameCount%90)*delta1*PI/180/Summation(0,f1-1);
}
if(frameCount%90>=f1+1&&frameCount%90<=f2)
{
theta5+=(frameCount%90-f1-1)*delta2*PI/180/Summation(0,f2-f1-1);
}
if(frameCount%90>=f2+1&&frameCount%90<=f3)
{
theta5+=(f3-frameCount%90)*delta2*PI/180/Summation(0,f2-f1-1);
}
if(frameCount%90>=f3+1&&frameCount%90<=89)
{
theta5-=(frameCount%90-f3-1)*delta1*PI/180/Summation(0,f1-1);
}
if(frameCount%90==0)
{
theta5-=(90-f3-1)*delta1*PI/180/Summation(0,f1-1);
}
return theta5;
}
③Summation()函數(shù),即高斯求和。
function Summation(n1,n2)
{
return (n1+n2)*(n2-n1+1)/2;
}
第一到四層的旋轉(zhuǎn)
第一到四層的旋轉(zhuǎn)與第五層一致,修改傳入?yún)?shù)即可。
其實(shí)RotateCubes()的內(nèi)容是一致的,最后返回一個(gè)theta。但當(dāng)我為theta賦值后return(如下圖),產(chǎn)生效果發(fā)生錯(cuò)誤 ,分配數(shù)據(jù)發(fā)生錯(cuò)誤。第一次接觸p5.js,感覺(jué)代碼寫得比較冗余,后續(xù)學(xué)習(xí)中優(yōu)化。

以上,即完成了對(duì)原圖的臨摹。
拓展作品
讓立方體的大小隨幀數(shù)變化,90幀一循環(huán)。

隨幀數(shù)增加,深粉立方體變小,淺粉立方體變大。并在一瞬間,深粉立方體和淺粉立方體大小相同,形成一個(gè)完整的愛(ài)心。

if(frameCount%200>=0&&frameCount%200<=99) //擴(kuò)展作品2
{
size1=frameCount%100*0.02;
size2=(100-frameCount%100)*0.02;
size3=frameCount%100*0.02;
size4=(100-frameCount%100)*0.02;
size5=frameCount%100*0.02;
size6=(100-frameCount%100)*0.02;
}
if(frameCount%200>=100&&frameCount%200<=199)
{
size1=(100-frameCount%100)*0.02;
size2=frameCount%100*0.02;
size3=(100-frameCount%100)*0.02;
size4=frameCount%100*0.02;
size5=(100-frameCount%100)*0.02;
size6=frameCount%100*0.02;
}
體會(huì):
三維圖形比起二維圖像要多一個(gè)z參數(shù),所以在排布位置的時(shí)候難度增大,且translate()函數(shù)的參數(shù)是偏移量,又為圖形繪制增加了難度。
本GIF又一難點(diǎn)在于運(yùn)動(dòng)規(guī)律不能用肉眼直接獲得,需要把GIF分解到每一幀,逐幀觀察。運(yùn)動(dòng)規(guī)律相對(duì)復(fù)雜,且每一層運(yùn)動(dòng)規(guī)律都不同,需要控制的變量較多。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于chosen插件實(shí)現(xiàn)人員選擇樹(shù)搜索自動(dòng)篩選功能
這篇文章主要介紹了基于chosen插件實(shí)現(xiàn)人員選擇樹(shù)搜索自動(dòng)篩選功能的相關(guān)資料,需要的朋友可以參考下2016-09-09
webpack HappyPack實(shí)戰(zhàn)詳解
這篇文章主要介紹了webpack HappyPack實(shí)戰(zhàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
MUI 解決動(dòng)態(tài)列表頁(yè)圖片懶加載再次加載不成功的bug問(wèn)題
這篇文章主要介紹了MUI 解決動(dòng)態(tài)列表頁(yè)圖片懶加載再次加載不成功的bug問(wèn)題,解決方法很簡(jiǎn)單的,需要的朋友可以參考下2017-04-04
JS監(jiān)聽(tīng)變量改變的實(shí)現(xiàn)
本文主要介紹了JS監(jiān)聽(tīng)變量改變的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
使用webpack-dev-server處理跨域請(qǐng)求的方法
本篇文章主要介紹了使用webpack-dev-server處理跨域請(qǐng)求的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
僅Firefox中鏈接A無(wú)法實(shí)現(xiàn)模擬點(diǎn)擊以觸發(fā)其默認(rèn)行為
偶然發(fā)現(xiàn)之前寫的事件模塊在Firefox5中無(wú)法觸發(fā)A的默認(rèn)行為了。IE/Opera/Firefox5中A具有click方法,因此模擬點(diǎn)擊直接調(diào)用click方法即可。2011-07-07

