Javascriptでいろいろな正星型図形（n芒星)を生成する




#仕組み

図形生成の仕組みは、[こちらのページの技術](https://mail.conifer.jp/csstest/css-circle-text.html)を応用したもの　+　高校で習った三角関数。
そもそも六芒星をはじめとする星型図形には**どれだけ複雑なものであっても、線の本数と傾きは正多角形の時と変わらない**という法則がある。つまり、線の長さと位置さえ調整してやれば、煩雑な多角形であっても生成可能なのである。
で、その線の位置と長さを求めるときに使うのが、いわゆるsin、cos、tanなのだ。

図にするとこんな感じ。
![1583417842156.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416995/7f0291ca-46e1-4ec5-694a-ae9a7b72a8db.jpeg)

赤線の部分がいわゆる「斜辺」と呼ばれるもの。斜辺の長さは50%=0.5で、赤線と赤線の間の角（中心角）は今回の場合５等分（赤い点＝円の中心から接線に向けて伸びる直線、つまり半径なのだ）。これにsinやcosをかけてやれば値がwidthとheightの長さが求まるという寸法だ。

高校を卒業したての人に向けて言えば、「width=弦の長さ」。と言えばイメージしやすいのではないだろうか。
ちなみに、sin、cos、tanは**角度をもとに線の長さを求める**式である。

#作例例

![1583418314284.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416995/7c0ac3cb-1aef-bb57-7b97-890c3a39cc4b.jpeg)
オーソドックスな六芒星。

![1583416971266.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416995/ac6d2ef7-a1e1-c627-a595-80d73e954db2.jpeg)
第三引数（intersection）を0にすれば通常の正多角形も作図できる。

![1583418677837.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416995/e1deeb2a-d940-480d-409d-fc3150258b26.jpeg)
同じ７角形だが、第三引数を２にしてある。


![1583417002963.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416995/37162ee3-cc6e-920a-ed4f-4622c8417f70.jpeg)
こんな複雑なのも可能。ちなみに、400角形で頂点を188個飛ばしにつないでいる。

![1583418439057.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416995/68ff991f-41fa-50cb-63af-785fa292f807.jpeg)
1024角形。**邪神アバター**呼ばわりされた。

ちなみに、星型多角形は頂点の数が増えてゆくごとに、作れる"星"の種類も増えてゆく。
最大数は（頂点数÷２)-1 **以下**の数。たとえば、7角形なら、7÷2=3.5、3.5-1=2.5なので、2つ作れることになる。


#コード本体

```html:html

<style>
/* position:relative、position:absolute、position:fixedのいずれか+タテヨコの高さが決まっていないと崩れるので注意。 */
#torirobyte{
    position: relative;
    width: 600px;
    height: 600px;
}	
/* border-bottomで線を表現しているので、線の太さや色はここをいじれば制御できる。 */
#torirobyte div{
    border-bottom: 1px solid black;
}
</style>


<div id="torirobyte">
</div>

<script type="text/javascript">
(function(){

var target = document.getElementById('torirobyte');
CreateGrams(target, 12, 3);

function CreateGrams(parantelm, vertex, intersection){
	// vertexは頂点数。
	// intersectionは点と点をつなぐ直線が何個飛ばしに線を作るか。0の場合、普通の正多角形ができあがります。
	// elementの中に整形されます。

	// 図形のパラメーターの設定
	var radius = 50; // 半径（widthとheightはパーセント指定するので一律50）
	var slope_per_one = 360 / vertex; // 線の傾き
	var center_angle = slope_per_one * (intersection + 1); // 中心角。この値によって、完成する星型図形が変化します。
	var radian_slope = ((180 - center_angle) / 2) * (Math.PI / 180); // sin、cosに使う角(ラジアン単位)
	var width_rate = Math.cos(radian_slope) * radius * 2; // 線に設定するwidth（単位は％）
	var height_rate = Math.sin(radian_slope) * radius * 2; // 線に設定するheight（単位は％）
	var leftposision = (100 - width_rate) / 2; // positionのleftに付ける値。これで横位置を要素内におさめる

	// 図形の生成
	parantelm.innerHTML = '';
	for(var int = 0; int < vertex; int++){
		var childs = document.createElement('div');

		// 図形逆向き化防止
		if(intersection % 2 == 0){
			var slope_current = (slope_per_one * int);
		}else{
			var slope_current = (180 + (slope_per_one * int));
		}

		childs.style.margin = 'auto';
		childs.style.position = 'absolute';
		childs.style.top = 0;
		childs.style.bottom = 0;
		childs.style.left = leftposision + '%';
		childs.style.transform = 'rotate(' + slope_current + 'deg)';
		childs.style.width = width_rate + '%';
		childs.style.height = height_rate + '%';
		parantelm.appendChild(childs);
	}
	return parantelm;
}

})();
</script>

```