最近做Box2dWeb開發時,想寫個建立正多邊形的功能,可是由于學識尚淺,我在草稿紙上畫了,想了一個上午也沒有研究出什麼好方法。後來翻抽屜的時候,找出了以前哥哥畫的一張用同心圓畫橢圓的示意圖。看到這幅畫,我不禁在想橢圓不就是一個N邊形嗎?圓不就是一個正N邊形嗎?如果把兩個同心圓的半徑設定為相等,畫出來的橢圓不就是一個圓嗎?是以,我立刻開始實驗。原本我以為比較難,會用到圓的解析式之類的,沒想到就45行代碼就搞定了,主要用到的數學知識就是sin和cos。
也許有人不明白如何用同心圓畫橢圓,我就借用網上找的一張圖檔給大家展示吧

這個畫法很經典,做法簡要概括一下就是:
畫一個同心圓,然後以圓心為原點畫一個二維坐标系;接着用N條過圓心的直線将圓等分,圖中所示就是4條,把圓等分為了12份。每條直線都會與兩個圓有交點,這時候我們就可以确定橢圓上的一個點——設直線與小圓的交點為(a, b),與大圓的交點為(c, d),确定的那個點的坐标則為(c, b);我們有N條直線就會得出2 * N + 4這樣的點。可以看出,得到的點的坐标通式為:(與大圓的交點的x坐标, 與小圓的交點的y坐标)。要得到這些坐标,我們隻用知道直線的條數N和大圓小圓的半徑(或直徑),然後用sin和cos進行計算即可。得到這些點後,把這些點連接配接起來就大緻是個橢圓了;如果你把N的數目設定的越大,那麼畫出來的圖形就更接近于橢圓。
與畫橢圓不同的是,畫正多邊形不需要這麼複雜,隻需要一個圓就夠了。而且也不要什麼坐标系了,你要N 邊形就畫N條過圓心的直線,然後這些直線與圓的交點就是多變形的頂點。把頂點連接配接起來就是多變形。
現在,我們可以上代碼了:
<!DOCTYPE html>
<html>
<head>
<title>Make Regular Polygon</title>
<meta charset="utf-8" />
<script type="text/javascript">
window.onload = function () {
var canvasTag = document.getElementById("mycanvas");
var c = canvasTag.getContext("2d");
var vertices = getPolygonVertices(7, 100);
c.beginPath();
c.fillStyle = "lightgray";
c.fillRect(0, 0, canvasTag.width, canvasTag.height);
c.translate(canvasTag.width / 2, canvasTag.height / 2);
c.moveTo(vertices[0][0], vertices[0][1]);
for (var i = 1; i < vertices.length; i++) {
c.lineTo(vertices[i][0], vertices[i][1]);
}
c.lineWidth = 5;
c.closePath();
c.stroke();
};
function getPolygonVertices (edges, r) {
var ca = 0, aiv = 360 / edges, ata = Math.PI / 180, list = new Array();
for (var k = 0; k < edges; k++) {
var x = Math.cos(ca * ata) * r,
y = Math.sin(ca * ata) * r;
list.push([x, y]);
ca += aiv;
}
return list;
}
</script>
</head>
<body>
<canvas id="mycanvas" width="800" height="450"></canvas>
</body>
</html>
包括canvas渲染和html tag部分,一共45行。真正意義上的算法部分就隻在getPolygonVertices函數裡。 這個getPolygonVertices有兩個參數,第一個參數是edges邊數,第二個參數是圓的半徑,決定多變形的大小。
算法在前面已經講解過了,很簡單很基礎吧~
運作代碼,畫出七邊形:
大家可以試着将getPolygonVertices的第一個參數改一改,畫出其他多邊形。
Ok,搞定收工~
本文到此結束,歡迎大家交流~
----------------------------------------------------------------
歡迎大家轉載我的文章。
轉載請注明:轉自Yorhom's Game Box
http://blog.csdn.net/yorhomwang
歡迎繼續關注我的部落格