利用三角函数生成计算机图形Word文档格式.docx
《利用三角函数生成计算机图形Word文档格式.docx》由会员分享,可在线阅读,更多相关《利用三角函数生成计算机图形Word文档格式.docx(20页珍藏版)》请在冰豆网上搜索。
1.3曲线修饰
1.3.1加修饰
如果定义一个常量x=Math.PI/n,循环变量i,可以写出他的绘图程序
for(i=0,i<
2*n,i++){
x=a1*Math.cos(b1*i*x)+a2*Math.cos(b2*i*x);
y=a1*Math.sin(b1*i*x)+a2*Math.sin(b2*i*x);
这里a1、a2为半径系数,是大于0的实数,b1、b2为周期系数,是大于0的正整数,且b2>
b1,则图形会在圆形图案上形成b2-b1个突起。
如果把x、y的赋值写成
x=a1*Math.cos(b1*i*x)+a2*Math.sin(b2*i*x);
y=a1*Math.sin(b1*i*x)+a2*Math.cos(b2*i*x);
或写成
x=a1*Math.cos(b1*i*x)-a2*Math.cos(b2*i*x);
y=a1*Math.sin(b1*i*x)-a2*Math.sin(b2*i*x);
则图案的突起是b1+b2个。
这里我们把
a1*Math.cos(b1*i*x)
a1*Math.sin(b1*i*x)
称之为主函数,把
a2*Math.cos(b2*i*x)
a2*Math.sin(b2*i*x)
称之为修饰函数。
修饰函数可随意增加,只要遵循突起规律,可以创造出无数个美丽图形,而且是对称图形。
如果把b1和b2换成b1,b2,b3,b4四个不等的正整数,生成的图形多数可能是不对称的。
图2通过加修饰生成的曲线
1.3.2乘修饰
可以写成
x=a*Math.cos(i*x)*Math.cos(b*i*x);
y=a*Math.sin(i*x)*Math.cos(b*i*x);
x=a*Math.cos(i*x)*(c+Math.cos(b*i*x));
y=a*Math.sin(i*x)*(c+Math.cos(b*i*x));
b=5,c=1b=5,c=1.5b=5,c=0.3b=6,c=0.3
图3通过乘修饰生成的曲线
1.3.3嵌入修饰
如果周期系数出现非整数,曲线可能会产生无规则穿插。
当把小数部分定义成1/m,即b2*(1+1/m),这样曲线经过b2*(m+1)次又形成重合,产生嵌入效果,即嵌入修饰,其循环周期是2*n*m(n在前面定义过)。
也可写成b2*(k+s/m),这里s允许是负整数,嵌入次数为b2*(k*m+s)。
这种嵌入方式加修饰、乘修饰都适合。
图4利用嵌入修饰生成的花篮
1.3.4藤编效果
利用正弦余弦的嵌入方式只改变b2,在曲线的交汇点处产生偏移,避免重合,就像用一条藤子编织而成。
图5藤编效果曲线
2着色
利用三角函数可以使着色产生渐变效果。
2.1简单渐变
这种着色界限不是很明显,没有纯红、纯绿和纯蓝色:
r=127.5*(1+Math.cos(t*p/n));
g=127.5*(1+Math.cos((t+c)*p/n));
b=127.5*(1+Math.cos((t+2*c)*p/n));
2.2三色渐变
直接滤除曲线小于0部分,突出红、绿和蓝三颜色:
Math.cos(t*p/n)<
0?
r=0:
r=255*Math.cos(t*p/n);
Math.cos((t+c)*p/n)<
g=0:
g=255*Math.cos((t+c)*p/n);
Math.cos((t+2*c)*p/n)<
b=0:
b=255*Math.cos((t+2*c)*p/n);
2.3组合渐变
组合渐变更细分一些,可以组合成红、黄、绿、青、蓝、紫色:
Math.cos(t*p/n)+0.5<
(Math.cos(t*p/n)+0.5>
1?
r=255:
r=255*(0.5+Math.cos(t*p/n)));
Math.cos((t+c)*p/n)+0.5<
(Math.cos((t+c)*p/n)+0.5>
g=255:
g=255*(0.5+Math.cos((t+c)*p/n)));
Math.cos((t+2*c)*p/n)+0.5<
(Math.cos((t+2*c)*p/n)+0.5>
b=255:
b=255*(0.5+Math.cos((t+2*c)*p/n)));
这里c=循环周期/3。
简单渐变着色曲线三色渐变着色曲线组合渐变着色曲线
图6三种渐变着色深度曲线
2.4周期渐变着色
有时动画涉及层深变化,采用周期渐变着色能增加透视效果(见图5)。
2.5uv渐变着色
有时曲线涉及交叉,为了使交叉处着色一致,需要uv方向渐变着色。
u向渐变着色也可理解成环形渐变着色,v向渐变着色可以理解成轴向渐变着色。
图7uv渐变着色效果
3模型
3.1简单模型
利用三角函数形成闭合曲线,填充颜色可以生成各种图形。
图8利用三角函数生成的多角星
3.2三维模型
利用三角函数生成点的三维坐标由相邻点构建平面生成三维图形。
图9利用三角函数生成的三维几何体
3.3螺旋线建模
螺旋线建模是选择螺旋线上四个或三个相邻的点,围城一个平面所构成的模型。
该模型说起来很简单,但如果生成一些比较复杂的模型,其意义也就显得非常重要了。
图10螺旋线原理图
图11利用螺旋线建模生成的几何体图形
3.4扭曲
有时需要扭曲,使效果更有变化,为了确保扭曲后交接处完全重合,其扭曲角度增量仍然遵循1/n规律,而且总面片数能被n整除。
图12扭曲与未扭曲效果比较
4动画
4.1旋转
很多旋转动画都需要三角函数,这里介绍一种乘修饰动画,只在主函数添加一个时间增量就可以产生旋转动画效果。
4.2变形
改变半径、周期、扭曲、弯曲,可以产生许多种变形动画。
4实例
最后用Flash的ActionScript编写的一段绘制小花程序,来揭示一下嵌入修饰和v向渐变着色,效果见图13。
图13用ActionScript代码编写的绘小花动画
ActionScript代码:
[SWF(backgroundColor=0x888888)]
varsp:
Sprite=addChild(newSprite())asSprite;
sp.x=275,sp.y=200;
vart:
uint,n:
uint=0,m:
uint=0,r:
uint,g:
uint,b:
uint;
varx1:
Number,z1:
Number,y1:
Number,z2:
Number,y2:
Number;
vark:
int=2,w:
int=4,h:
Number=w+1/k,s:
int=180,d:
int=2*s*k+1,c:
Number=(k*w+1)/k;
varf:
Number=900,p=Math.PI/s,angleX:
Number=-0.6,q:
Number=s/c;
varcosX:
Number,sinX:
Number,cosY:
Number,sinY:
varcos1:
Number,cos2:
Number,pp:
Array=[];
varbbb:
Boolean,dy:
for(t=0;
t<
d;
t++){
pp[t]=newMovieClip();
sp.addChild(pp[t]);
pp[t].zz=-1000;
addEventListener(Event.ENTER_FRAME,fff);
functionfff(e){
if(bbb){
angleX+=(dy-mouseY)/200;
dy=mouseY;
}
m=m+1>
d?
d:
m+1;
cosX=Math.cos(angleX);
sinX=Math.sin(angleX);
x1=13*Math.cos(n*p/3)*4;
z2=13*Math.sin(n*p/3)*4;
y2=-90;
y1=y2*cosX+z2*sinX;
z1=z2*cosX-y2*sinX;
for(t=0;
m;
pp[t].graphics.clear();
r=255*col(0.5+Math.cos(t*p*c),z1);
g=255*col(0.5+Math.cos((t+q)*p*c),z1);
pp[t].graphics.moveTo(x1*f/(f+z1),y1*f/(f+z1));
pp[t].zz=z1;
cos1=Math.cos(t*p*h),cos2=Math.cos(t*2*p*h);
x1=13*Math.cos((t+n/3)*p)*(5-5*cos1+4*cos2);
z2=13*Math.sin((t+n/3)*p)*(5-5*cos1+4*cos2);
y2=30*(1-cos1-cos2-Math.cos(t*3*p*h))-30;
y1=y2*cosX+z2*sinX;
z1=z2*cosX-y2*sinX;
pp[t].graphics.lineStyle(5*f/(f+z1),r<
<
16|g<
8|0);
pp[t].graphics.lineTo(x1*f/(f+z1),y1*f/(f+z1));
pp[t].zz+=z1;
pp.sortOn("
zz"
18);
sp.setChildIndex(pp[t],t);
n=(n+1)%(4*s);
functioncol(xx:
Number,xz:
Number):
Number{
varcz:
Number,cx:
xx>
cx=1:
(xx<
cx=0:
cx=xx);
200/(280+xz)>
cz=1:
cz=200/(280+xz);
returncx*cz;
stage.addEventListener(MouseEvent.MOUSE_UP,function(e){bbb=false;
});
stage.addEventListener(MouseEvent.MOUSE_DOWN,function(e){dy=mouseY,bbb=true;
鼠标跟随的鱼
[SWF(backgroundColor=0x00eeff,width=640,height=480)]
sp.y=-200,sp.x=320;
varpx:
Array=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],pp:
varpz:
Array=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],yur:
varx0:
Array=[[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]];
varz0:
vary0:
varr:
Array=[1,9,15,19.5,22,23,23.5,23,22,19.5,16.5,13,10,9,10,12,14,16];
varr1:
Array=[0,8,12,14.5,16,17,17.5,17,15.5,13,10,7.5,5,3,1,0.2,0,0];
for(i=0;
i<
281;
i++){
pp[i]=newMovieClip();
sp.addChild(pp[i]);
Number=1800,i:
uint,m:
int,t:
int,k:
int,h:
int,j:
int,c1:
uint,c2:
uint,c3:
uint,r2:
varmc:
Sprite=newSprite();
varbox:
Matrix=newMatrix();
box.createGradientBox(20,10,1.57,240,0);
mc.graphics.beginGradientFill("
linear"
[0xddaaaa,0x882211,0xddaaaa],[1,1,1],[150,200,250],box,"
reflect"
);
mc.graphics.drawRect(280,0,120,400);
36;
for(j=0;
j<
16;
j++){
c1=255<
16|Math.abs(j-7.5)*20+20<
8|40;
c2=255<
16|Math.abs(j-7.5)*20+60<
8|Math.abs(j-7.5)*20+30;
c3=255<
16|Math.abs(j-7.5)*20<
8|0;
r2=(5-Math.cos(i*Math.PI/40))/8;
box.createGradientBox(56,40,0,270-i*9*r2,j*25-20+(i%2)*12.5);
mc.graphics.beginGradientFill("
radial"
[c3,c1,c2],[1,1,1],[70,120,200],box);
mc.graphics.moveTo(275-i*9*r2,j*25+(i%2)*12.5);
mc.graphics.lineTo(315-i*9*r2,j*25-14+(i%2)*12.5);
mc.graphics.curveTo(315+(20-i*9)*r2,j*25+(i%2)*12.5,315-i*9*r2,14+j*25+i%2*12.5);
mc.graphics.lineTo(275-i*9*r2,j*25+(i%2)*12.5);
mc.graphics.endFill();
2;
box.createGradientBox(200,400,0,-30,i*400-200);
mc.graphics.beginGradientFill("
[0xffddaa,0xff6633,0xff2200],[1,1,1],[50,150,205],box);
mc.graphics.moveTo(0,i*200);
mc.graphics.lineTo(60+i*10,i*200);
mc.graphics.curveTo(125,110+i*180,70-i*10,200+i*200);
mc.graphics.lineTo(0,200+i*200);
mc.graphics.endFill();
box.createGradientBox(20,40,0,45,i*200+80);
[0,0xbbbbbb,0x555555],[1,1,1],[50,100,255],box);
mc.graphics.drawEllipse(45,80+i*200,20,40);
mc.graphics.lineStyle(3,0xee6622,0.6);
mc.graphics.moveTo(65+i*20,i*250+50);
mc.graphics.curveTo(85,60+i*280,85-i*20,100+i*250);
varbmp1:
BitmapData=newBitmapData(400,400);
bmp1.draw(mc);
functionfff(e:
Event){
pz[0]+=(200*f/sp.mouseY-f-pz[0])/15;
//高度坐标转换成深度坐标
px[0]+=(sp.mouseX*(f+pz[0])/f-px[0])/15;
yur[0]=Math.atan2(pz[0]-200*f/sp.mouseY+f,px[0]-sp.mouseX*(f+pz[0])/f);
for(i=1;
18;
i<
=4?
yur[i]=yur[0]:
yur[i]=Math.atan2(pz[i]-pz[i-1],px[i]-px[i-1]);
px[i]=px[i-1]+10*Math.cos(yur[i-1]);
pz[i]=pz[i-1]+10*Math.sin(yur[i-1]);
for(i=0;
for(m=0;
m<
17;
m++){
z0[i][m]=pz[i]-r1[i]*Math.sin(m*Math.PI/8)*Math.cos(yur[i]);
x0[i][m]=(px[i]+r1[i]*Math.sin(m*Math.PI/8)*Math.sin(yur[i]))*f/(f+z0[i][m]);
y0[i][m]=(r[i]*Math.cos(m*Math.PI/8)+200)*f/(f+z0[i][m]);
}
for(m=0;
z0[18][m]=z0[4][2+m*12]+10*Math.sin(yur[4]-h*Math.PI/20*Math.pow(-1,m));
x0[18][m]=x0[4][2+m*12]+10*Math.cos(yur[4]-h*Math.PI/20*Math.pow(-1,m))*f/(f+z0[18][m]);
y0[18][m]=217*f/(f+z0[18][m]);
z0[18][m+2]=z0[4][3+m*10]+5*Math.sin(yur[4]-h*Math.PI/20*Math.pow(-1,m));
x0[18][m+2]=x0[4][3+m*10]+5*Math.cos(yur[4]-h*Math.PI/20*Math.pow(-1,m))*f/(f+z0[18][m+2]);
y0[18][m+2]=207*f/(f+z0[18][m+2]);
z0[18][m+4]=z0[8][1+m*14]+10*Math.sin(yur[8]-(9-h)*Math.PI/20*Math.pow(-1,m));
x0[18][m+4]=x0[8][1+m*14]+10*Math.cos(yur[8]-(9-h)*Math.PI/20*Math.pow(-1,m))*f/(f+z0[18][m+4]);
y0[18][m+4]=221*f/(f+z0[18][m+4]);
z0[18][m+6]=z0[8][2+m*12]+5*Math.sin(yur[8]-(9-h)*Math.PI/20*Math.pow(-1,m));
x0[18][m+6]=x0[8][2+m*12]+5*Math.cos(yur[8]-(9-h)*Math.PI/20*Math.pow(-1,m))*f/(f+z0[18][m+6]);
y0[18][m+6]=214*f/(f+z0[18][m+6]);
t=0;
i++){//鱼体
varvArr:
Vector.<
Number>
=Vector.<
([x0[i][m],y0[i][m],x0[i][m+1],y0[i][m+1],x0[i+1][m+1],y0[i+1][m+1],x0[i+1][m],y0[i+1][m]]);
varuArr:
([i/17,m/16,i/17,(m+1)/16,(i+1)/17,(m+1)/16,(i+1)/17,m/16]);
pp[t].Z=z0[i][m]+z0[i][m+1]+z0[i+1][m+1]+z0[i+1][m];
fce(t,vArr,uArr,"
negative"
t++;
for(i=5;
9;
i++){//背鳍
vary2:
Number=(186+i-r[i+1])*f/(f+z0[i+1][7]),y3:
Number=(187+i-r[i+2])*f/(f+z0[i+2][7]);
vArr=Vector.<
([x0[i][8],y0[i][8],x0[i+1][8],y2,x0[i+2][8],y3,x0[i+1][8],y0[i+1][8]]);
uArr=Vector.<
Numbe