用 javascript 实现玫瑰花(一支)

玫瑰花的定义

玫瑰(学名: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厘米;花瓣倒卵形,重瓣至半重瓣,芳香,紫红色至白色;花柱离生,被毛,稍伸出萼筒口外,比雄蕊短很多。

效果图

实现原理

  1. surface_patel 函数实际上就是圆方程的变形,类似蒙特卡洛随机点返回变形的三维曲面。
  2. 然后根据角度增加,循环绘制像素即可。

代码如下

<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>

转载请署名,谢谢

posted on 2020-12-13 17:40  mirancy  阅读(1008)  评论(0编辑  收藏  举报

导航