1.1 扇形变换
将如图1所示的上边长方形的图形变换为下边的扇形图形的变换称为扇形变换。
设长方形图形中任一点P1(X1,Y1)变换为扇形图形上的点P2(X2,Y2),长方形的长为X,扇形圆心坐标为(X0,Y0),扇形半径为L,扇形与X轴的最小夹角为B,扇形弧对应夹角为C,则点P2的坐标计算公式为:
X2=(L+Y1)*COS(θ)+X0
Y2=-(L+Y1)*SIN(θ)+Y0
其中: θ=C*(X-X1)/X1+B
图1 扇形变换
生成一个六瓣花型图案的基本数据,将长方形中的8个六瓣花型作为基本图案,进行指定层数的扇形变换。
编写如下的HTML代码。
function drawBase(id)
{
var canvas=document.getElementById(id);
if (canvas==null)
return false;
var context=canvas.getContext('2d');
context.fillStyle="#EEEEFF";
context.fillRect(0,0,700,100);
context.fillStyle="yellow";
context.strokeStyle="red";
context.lineWidth=2;
context.beginPath();
var dig=Math.PI/64;
var x=new Array();
var y=new Array();
var w=80;
// 生成一个六瓣花型图案的数据
for (var i=0;i<=128;i++)
{
d=w/2*(0.8+Math.sin(18*i*dig)/5)*1.2;
t=d*(0.5+Math.sin(6*i*dig)/2);
x[i]=t*Math.cos(i*dig);
y[i]=t*Math.sin(i*dig);
}
// 在水平一行中绘制8个六瓣花型图案
for (n=1;n<=8;n++)
{
px=(2*n-1)/2*w+30;
for (i=0;i<=128;i++)
{
x1=px+x[i];
y1=w/2-y[i];
if (i==0)
{
context.moveTo(x1,y1);
bx=x1; by=y1;
}
else
context.lineTo(x1,y1);
}
}
context.lineTo(bx,by);
context.closePath();
context.stroke();
context.fill();
}
function drawSector(id)
{
var canvas=document.getElementById(id);
if (canvas==null)
return false;
var context=canvas.getContext('2d');
context.fillStyle="#EEEEFF";
context.fillRect(0,0,700,500);
context.fillStyle="yellow";
context.strokeStyle="red";
context.lineWidth=2;
context.beginPath();
var dig=Math.PI/64;
w=80;
var x=new Array();
var y=new Array();
// 生成一个六瓣花型图案的数据
for (var i=0;i<=128;i++)
{
d=w/2*(0.8+Math.sin(18*i*dig)/5)*1.2;
t=d*(0.5+Math.sin(6*i*dig)/2);
x[i]=t*Math.cos(i*dig);
y[i]=t*Math.sin(i*dig);
}
var k=eval(document.myForm.levelNum.value);
if (k<1 || k>=6) {
alert("扇形层数需设定为1~5之一!");
return;
}
// 进行多重扇形变换
l=100; b=Math.PI/3; c=Math.PI/3; x0=350; y0=500;
for (m=1;m<=k;m++)
for (n=1;n<=8;n++)
for (var i=0;i<=128;i++)
{
px=(2*n-1)/2*w;
py=(2*m-1)/2*w;
x1=px+x[i];
y1=py-y[i];
th=c*(w*8-x1)/(w*8)+b;
x2=(l+y1)*Math.cos(th)+x0;
y2=-(l+y1)*Math.sin(th)+y0;
if (i==0)
{
context.moveTo(x2,y2);
bx=x2; by=y2;
}
else
context.lineTo(x2,y2);
}
context.lineTo(bx,by);
context.closePath();
context.stroke();
context.fill();
}
基本图案