用 javascript 實現玫瑰花(一支)
阿新 • • 發佈:2020-12-13
玫瑰花的定義
玫瑰(學名:Rosa rugosa Thunb.):原產地中國。屬薔薇目,薔薇科落葉灌木,枝杆多針刺,奇數羽狀複葉,小葉5-9片,橢圓形,有邊刺。花瓣倒卵形,重瓣至半重瓣,花有紫紅色、白色,果期8-9月,扁球形。枝條較為柔弱軟垂且多密刺,每年花期只有一次,因此較少用於育種,近來其主要被重視的特性為抗病性與耐寒性。
直立灌木,高可達2米;莖粗壯,叢生;小枝密被絨毛,並有針刺和腺毛,有直立或彎曲、淡黃色的皮刺,皮刺外被絨毛。
小葉5-9,連葉柄長5-13釐米;小葉片橢圓形或橢圓狀倒卵形,長1.5-4.5釐米,寬1-2.5釐米,先端急尖或圓鈍,基部圓形或寬楔形,邊緣有尖銳鋸齒,上面深綠色,無毛,葉脈下陷,有褶皺,下面灰綠色,中脈突起,網脈明顯,密被絨毛和腺毛,有時腺毛不明顯;葉柄和葉軸密被絨毛和腺毛;托葉大部貼生於葉柄,離生部分卵形,邊緣有帶腺鋸齒,下面被絨毛。
花單生於葉腋,或數朵簇生,苞片卵形,邊緣有腺毛,外被絨毛;花梗長5 -22 5毫米,密被絨毛和腺毛;花直徑4-5.5釐米;萼片卵狀披針形,先端尾狀漸尖,常有羽狀裂片而擴充套件成葉狀,上面有稀疏柔毛,下面密被柔毛和腺毛;花瓣倒卵形,重瓣至半重瓣,芳香,紫紅色至白色;花柱離生,被毛,稍伸出萼筒口外,比雄蕊短很多。
效果圖
實現原理
- surface_patel 函式實際上就是圓方程的變形,類似蒙特卡洛隨機點返回變形的三維曲面。
- 然後根據角度增加,迴圈繪製畫素即可。
程式碼如下
<script> var c=document.getElementById("canvas1").getContext("2d"); perspective=700, cinemaZ=-500 ; function surface_patel(a,b){ var x=a*100,y=b*100,radius=50,x0=50,y0=50; if((x-x0)*(x-x0)+(y-y0)*(y-y0)<radius*radius) return {x:x,y:y*(2+b)/2.,z:25*(Math.cos(1.3*b*Math.PI)+1),r:100+Math.round((1-b)*155),g:50,b:50}; return null; } function surface_leaf(a,b){ var x=a*100,y=b*100,radius=50,x0=50,y0=50; if((x-x0)*(x-x0)+(y-y0)*(y-y0)<radius*radius) return {x:x/2,y:y*(3+b)/2.,z:25*(Math.cos(1.3*b*Math.PI)+1),r:50,g:150+Math.round((1-b)*100),b:50}; return null; } window.setInterval(function () { var rx,ry,rz, px,py, X0=500,Y0=200, sin=Math.sin, cos=Math.cos; //add stem for(t=0;t<10;t+=.002) { x=(1-t)*(1-t)*450+2*t*(1-t)*440+t*t*460; y=(1-t)*(1-t)*380+2*t*(1-t)*600+t*t*900; c.fillStyle="rgb("+0+","+(100+Math.round(155*(1-t)))+","+0+")"; c.fillRect(x,y,15,15); } //add stem //add petal for(angle=0;angle<2*3.15;angle+=2*3.15/8){ for(ii=0;ii<1000;ii++) { point=surface_patel(Math.random(),Math.random()) if(point!=null) { point.x-=50;point.z+=40; rx=point.x*cos(angle)-point.z*sin(angle); ry=point.y; rz=point.x*sin(angle)+point.z*cos(angle); //alert(1) px=perspective*rx/(rz-cinemaZ)+X0; py=perspective*ry/(rz-cinemaZ)+Y0; c.fillStyle="rgb("+point.r+","+point.g+","+point.b+")"; c.fillRect(px-50,py-50,2,2); } } } //add petal //add leaf for(ii=0;ii<1000;ii++) //for(a=0;a<=1;a+=.01) //for(b=0;b<=1;b+=.005) { //point=surface_leaf(a,b) point=surface_leaf(Math.random(),Math.random()) if(point!=null) { point.x-=30;//point.z+=50; rx=point.x*cos(.3)-point.y*sin(.3); ry=point.x*sin(.3)+point.y*cos(.3); rz=point.z; px=perspective*rx/(rz-cinemaZ)+X0+100; py=perspective*ry/(rz-cinemaZ)+Y0+230; c.fillStyle="rgb("+point.r+","+point.g+","+point.b+")"; c.fillRect(px-50,py-50,2,2); } } //add leaf },0); </script>