2
0

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-03-05

仕組み

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

図にするとこんな感じ。
1583417842156.jpg

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

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

作例例

1583418314284.jpg
オーソドックスな六芒星。

1583416971266.jpg
第三引数(intersection)を0にすれば通常の正多角形も作図できる。

1583418677837.jpg
同じ7角形だが、第三引数を2にしてある。

1583417002963.jpg
こんな複雑なのも可能。ちなみに、400角形で頂点を188個飛ばしにつないでいる。

1583418439057.jpg
1024角形。邪神アバター呼ばわりされた。

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

コード本体

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>

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0