canvas 上绘制正多边形函数

这是我自己通过计算得出的函数,由于我数学没学好,可能计算过程有点儿复杂,导致代码冗长。


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


压缩后的代码:

【function strokeZhengDuoBianXing(k,b,d,f,e,j,g,m,h){a(k,b,d,f,e,j,g,m,h);function a(z,o,q,s,r,y,t,B,x){var n=[];var w;var v;var p;var C;var A;if(o=="t"){A=q;p=360/q}else{A=q*2;p=360/(q*2);if(t){x=i(s,r,B,q)}}for(var u=0;u180){y=-180+y%180}}C=B;if(o=="a"){if(u%2==0){C=B}else{C=x}}switch(y){case 90:n[u]=s+","+(r-C);break;case -90:n[u]=s+","+(r+C);break;default:w=Math.sqrt(Math.pow(C,2)/(Math.pow(Math.tan(y*2*Math.PI/360),2)+1));v=Math.abs(w*Math.tan(y*2*Math.PI/360));n[u]=l(s,r,w,v,y);break}y-=p}z.beginPath();for(var u=0;u<=n.length;u++){if(u==0){z.moveTo(n[0].split(",")[0],n[0].split(",")[1])}else{if(u==n.length){z.lineTo(n[0].split(",")[0],n[0].split(",")[1])}else{z.lineTo(n[u].split(",")[0],n[u].split(",")[1])}}}z.stroke();z.closePath()}function l(p,o,c,q,n){if(n>=0&&n<90){return(p+c)+","+(o-q)}else{if(n>90&&n<=180){return(p-c)+","+(o-q)}else{if(n<0&&n>-90){return(p+c)+","+(o+q)}else{if(n<-90&&n>=-180){return(p-c)+","+(o+q)}}}}}function i(s,r,o,q){var n=-(90-(180-360/q*2)/2);if(q<5){n=-72}var u=90-360/(q*2);var p=r-o-Math.tan(n*2*Math.PI/360)*s;var t=(p-(r-Math.tan(u*2*Math.PI/360)*s))/(Math.tan(u*2*Math.PI/360)-Math.tan(n*2*Math.PI/360));return Math.sqrt(Math.pow(t-s,2)+Math.pow(Math.tan(n*2*Math.PI/360)*t+p-r,2))}};】


代码方法名为:strokeZhengDuoBianXing,共有 9 个参数,或许这有点儿多,但是为了能够更加灵活的控制绘制,这是必要的。

9 个参数分别代表:

1、canvas.getContext("2d") , canvas 的上下文

2、“a”    或者 “t”   ,"a" 代表正多边形是凹进去的;"t" 代表正多边形是凸出来的

3、多边形的边数

4、中心点的横坐标

5、中心点的纵坐标

6、起始点连接中心点的直线相对于 x 正半轴的夹角度数

7、true 或者 false ,适用于凹正多边形,表示  正的凹正多边形,如果为 true ,第 9 个参数无效且第 9 个参数之由函数自定

8、正多边形中凸出来的部分到中心点的长度

9、正多边形中凹进去的部分到中心点的长度,只适用于凹正多边形


图例:

canvas 上绘制正多边形函数_第1张图片




------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


未压缩的源代码:


//绘制正多边形 九个参数 分别是:
//1、canvas.getContext("2d"),
//2、凹正多边形a or 凸正多边形t ,
//3、边数,
//4、中心点横坐标,
//5、中心点纵坐标,
//6、开始的角度/相对于x轴正半轴,
//7、如果是凹多边形,是否是正多边形
//8、如果是凹正多边形,中心点到凸出来点连线的长度
//9、如果是凹正多边形,中心点到凹进去点连线的长度
function strokeZhengDuoBianXing(c,aOrt,bianCount,centerX,centerY,startAngle,isZheng,longLength,shortLength) {

start(c,aOrt,bianCount,centerX,centerY,startAngle,isZheng,longLength,shortLength)


function start(c,aOrt,bianCount,centerX,centerY,startAngle,isZheng,longLength,shortLength) {
var dianArray = [];
var offsetX;
var offsetY;
var averageAngle;
var temp;
var xunHuanCount;
if (aOrt == "t") {
xunHuanCount = bianCount;
averageAngle = 360/bianCount
}else {
xunHuanCount = bianCount*2;
averageAngle = 360/(bianCount*2);
if (isZheng){
shortLength = getShortLength(centerX,centerY,longLength,bianCount);
}
}



for (var i = 0; i < xunHuanCount ; i++) {
if (startAngle < -180) {
startAngle = 180-Math.abs(startAngle)%180;
}else if (startAngle > 180) {
startAngle = -180+startAngle%180;
}
temp = longLength;
if (aOrt == "a") {
if (i%2 == 0) {
temp = longLength;
}else {
temp = shortLength;
}
}
switch (startAngle) {
case 90:
dianArray[i] = centerX+","+(centerY-temp);
break;
case -90:
dianArray[i] = centerX+","+(centerY+temp);
break;
default:
offsetX = Math.sqrt(Math.pow(temp,2)/(Math.pow(Math.tan(startAngle*2*Math.PI/360),2)+1));
offsetY = Math.abs(offsetX*Math.tan(startAngle*2*Math.PI/360));
dianArray[i] = accordingAngleReturnXY(centerX,centerY,offsetX,offsetY,startAngle);
break;
}
startAngle -= averageAngle;
}
//根据数组中保存的点坐标,开始绘制
c.beginPath();
for (var i = 0; i <= dianArray.length ; i++ ) {
if (i == 0) {
c.moveTo(dianArray[0].split(",")[0],dianArray[0].split(",")[1]);
}else if (i == dianArray.length) {
c.lineTo(dianArray[0].split(",")[0],dianArray[0].split(",")[1]);
}else {
c.lineTo(dianArray[i].split(",")[0],dianArray[i].split(",")[1]);
}
}
c.stroke();
c.closePath();
}


function accordingAngleReturnXY(centerX,centerY,offsetX,offsetY,startAngle) {
if (startAngle >= 0 && startAngle < 90) {
return (centerX+offsetX)+","+(centerY-offsetY);
}else if (startAngle > 90 && startAngle <= 180) {
return (centerX-offsetX)+","+(centerY-offsetY);
}else if (startAngle < 0 && startAngle > -90) {
return (centerX+offsetX)+","+(centerY+offsetY);
}else if (startAngle < -90 && startAngle >= -180) {
return (centerX-offsetX)+","+(centerY+offsetY);
}
}
function getShortLength(centerX,centerY,longLength,bianCount) {
//a 是相对于 x 正半轴的角度
var a = -(90-(180-360/bianCount*2)/2);
//当边数小于 5 时
if (bianCount < 5) {
a = -72;
}
var c = 90-360/(bianCount*2);
//y = kx+b;
var b1 = centerY-longLength - Math.tan(a*2*Math.PI/360)*centerX;
var jiaoDianX = (b1-(centerY - Math.tan(c*2*Math.PI/360)*centerX))/(Math.tan(c*2*Math.PI/360)-Math.tan(a*2*Math.PI/360));
return Math.sqrt(Math.pow(jiaoDianX-centerX,2)+Math.pow(Math.tan(a*2*Math.PI/360)*jiaoDianX+b1-centerY,2));
}
}



------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


欢迎关注我

你可能感兴趣的:(canvas 上绘制正多边形函数)