1. 程式人生 > >canvas 上繪製正多邊形函式

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;u<A;u++){if(y<-180){y=180-Math.abs(y)%180}else{if(y>180){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、正多邊形中凹進去的部分到中心點的長度,只適用於凹正多邊形

圖例:


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

未壓縮的原始碼:

//繪製正多邊形 九個引數 分別是:
//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));
}
}


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

歡迎關注我