perl de Heptagon (七角形)
七角形を描画
とりあえず描画してみる
#!/usr/bin/env perl use Mojolicious::Lite; app->types->type(data => 'application/octet-stream'); app->types->type(mem => 'application/octet-stream'); app->types->type(wasm => 'application/wasm'); get '/:n' => {n => 7} => sub { my $c = shift; $c->render(template => 'index'); }; app->start; __DATA__ @@ index.html.ep % layout 'default'; % title '七角形'; <h1><a href="http://park15.wakwak.com/~k-lovely/cgi-bin/wiki/wiki.cgi?page=perl+de+Heptagon+%28%BC%B7%B3%D1%B7%C1%29">perl de Heptagon (七角形)</a></h1> @@ layouts/default.html.ep <!DOCTYPE html> <html> <head><title><%= title %></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="webperl.js"></script> <script type="text/perl"> use WebPerl qw/js/; use List::Util qw/reduce/; use Data::Dumper; my $canvas = js('document')->getElementById('canvas'); my $ctx = $canvas->getContext("2d"); my ($w,$h) = (500,300); my ($cx,$cy) = ($w/2, $h/2) ; my $r = ($cy<$cx ? $cy : $cx) / 1.1; my $pi = 3.141592; ($canvas->{width},$canvas->{height}) = ($w,$h); my $n = <%= $n %> + 0; $n = $n > 100 || $n < 2 ? 7 : $n; my @paricles = (); push(@paricles,particle($_,$n)) for (1 .. $n); draw(); print Dumper(@paricles); sub particle{ my ($i,$n) = @_; return { x => $r * cos($i*2*$pi/$n-($pi/2)), y => $r * sin($i*2*$pi/$n-($pi/2)), rgba => 'rgba(' . join(',',map{rand_rgb()}(1..3)) . ',' . rand() . ')', }; } sub draw{ $ctx->{lineWidth} = 5; reduce {draw_line($a,$b),$b} (@paricles,$paricles[0]); } sub draw_line{ my ($s,$e) = @_; $ctx->beginPath(); $ctx->moveTo($s->{x} + $cx,$s->{y} + $cy); $ctx->lineTo($e->{x} + $cx,$e->{y} + $cy); $ctx->{strokeStyle} = $s->{rgba}; $ctx->stroke(); } sub rand_rgb{ my $r = shift||255; return int(rand()*$r); } </script> <script> window.addEventListener("load", function () { document.getElementById('output') .appendChild( Perl.makeOutputTextarea() ); }); </script> </head> <body><%= content %><canvas id="canvas"></canvas><div id="output"></div> </body> </html>
LINE ART
LINE ARTで書いた七角形をperlで書いてみた。webperl+mojoliciousでcanvasに七角形を描画してみた。
webperl de canvas
- getElementByIdメソッドでHTMLと関連付けて、getContextメソッドで描画機能を有効にする
- getElementByIdメソッドでid名を指定してHTML側と関連付けます。 次に、getContextメソッドで描画機能を有効にします。JavaScriptとほぼ同じ書き方です。
my $canvas = js('document')->getElementById('canvas'); my $ctx = $canvas->getContext("2d");
- canvasのメソッドには $object->Method()でアクセスする。
$ctx->stroke();
- canvasのプロパティには$object->{Property}でアクセスする。
$ctx->{strokeStyle} = 'rgba(0,0,100,0.5)';
mojolicious de webperl
mojoliciousでwebperlを使ってみる。まずは雛形をつくる。
$ mojo generate lite_app polygon.pl
pubulicの下にhttps://webperl.zero-g.net/よりダウンロードしたファイルを展開する。
$ tree . . ├── polygon.pl └── public ├── emperl.data ├── emperl.js ├── emperl.wasm ├── LICENSE_artistic.txt ├── LICENSE_gpl.txt ├── lineArt.css ├── mini_ide │ ├── emscr_ide.css │ ├── emscr_ide.js │ └── webperl_mini_ide.html ├── README.md ├── regex_tester.html ├── runtests.html ├── webperl_demo.html ├── webperl.js └── webperl.psgi
雛形にMIMEを追加する
app->types->type(data => 'application/octet-stream'); app->types->type(mem => 'application/octet-stream'); app->types->type(wasm => 'application/wasm');
テンプレートにwebperl.jsを追加してperlを書く
<script src="webperl.js"></script> <script type="text/perl"> use WebPerl qw/js/; my $canvas = js('document')->getElementById('canvas'); my $ctx = $canvas->getContext("2d"); ・ ・ ・ </script>
perl de Heptagon
- 多角形を書くために頂点の位置を計算する。
- 半径1の円を考えると、座標 ( Cos(radian) , Sin(radian) ) が頂点になる(【Unity】Texture2Dに多角形を描くより)
- ラジアン
- 180°= π[rad]
- 正n角形の各頂点は、単位円の中心をn等分しているので、等分した1コ当りの中心角は
- 中心角 = 2π÷n
my $n = 7; my @paricles = (); push(@paricles,particle($_,$n)) for (1 .. $n); sub particle{ my ($i,$n) = @_; my $ret = {}; $ret->{x} = $r * cos($i*2*$pi/$n); $ret->{y} = $r * sin($i*2*$pi/$n); return $ret; }
- 度(deg)からラジアン(rad)を求める計算式
- rad=deg*(π/180)
- ラジアン(rad)から度(deg)を求める計算式
- deg=rad*(180/π)
- https://ja.wikipedia.org/wiki/%E4%B8%83%E8%A7%92%E5%BD%A2
正七角形とは、各辺と全ての内角の大きさがそれぞれ等しい七角形。ひとつの内角の大きさはラジアン角で5π/7(約128.57度)である。
正七角形をコンパスと定規(長さの計測が不可能なもの)で作図することは不可能であるが、コンパスと目盛り付の定規(長さの計測が可能なもの)を用いたり、あるいは折り紙を用いるなどすれば描画可能である。
辺をa、対角線をb,cとすると 1/a=1/b+1/c が成り立つ
webperl
CDNからwebperlコードをロードすれば自身のサーバーでこれをホストする必要すらありません。よってhtmlだけ配置すればwebperlが使えます。
[polygon.html] <html> <head> <title>perl de 七角形</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="https://webperlcdn.zero-g.net/v0.07-beta/webperl.js" integrity="sha256-jL8SB7St5ou4+hb0frK0k6VCQXsWQ1wolDrdU7i4juc=" crossorigin="anonymous"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script> <script type="text/perl"> use WebPerl qw/js/; use List::Util qw/reduce/; use Data::Dumper; my $canvas = js('document')->getElementById('canvas'); my $ctx = $canvas->getContext("2d"); my ($w,$h) = (500,300); my ($cx,$cy) = ($w/2, $h/2) ; my $r = ($cy<$cx ? $cy : $cx) / 1.1; my $pi = 3.141592; ($canvas->{width},$canvas->{height}) = ($w,$h); my $n = 7; my @paricles = (); draw_once($n); sub draw_once{ $n = shift; @paricles = (); push(@paricles,particle($_,$n)) for (1 .. $n); draw(); print Dumper(@paricles); } sub particle{ my ($i,$n) = @_; return { x => $r * cos($i*2*$pi/$n-($pi/2)), y => $r * sin($i*2*$pi/$n-($pi/2)), rgba => 'rgba(' . join(',',map{rand_rgb()}(1..3)) . ',' . rand() . ')', }; } sub draw{ $ctx->{fillStyle} = "white"; $ctx->fillRect(0, 0, $w, $h); $ctx->{lineWidth} = 5; reduce {draw_line($a,$b),$b} (@paricles,$paricles[0]); } sub draw_line{ my ($s,$e) = @_; $ctx->beginPath(); $ctx->moveTo($s->{x} + $cx,$s->{y} + $cy); $ctx->lineTo($e->{x} + $cx,$e->{y} + $cy); $ctx->{strokeStyle} = $s->{rgba}; $ctx->stroke(); } sub rand_rgb{ my $r = shift||255; return int(rand()*$r); } </script> <script> window.addEventListener("load", function () { document.getElementById('output') .appendChild( Perl.makeOutputTextarea() ); }); </script> </head> <body> <h1><a href="http://park15.wakwak.com/~k-lovely/cgi-bin/wiki/wiki.cgi?page=perl+de+Heptagon+%28%BC%B7%B3%D1%B7%C1%29">perl de Heptagon (七角形)</a></h1> <input id="in" value="7" type="number" min="1" max="49">角形を書く<br> <script type="text/perl"> my $jq = js('jQuery'); $jq->('#in')->on('change', sub { draw_once( $jq->('#in')->val ); }); </script> <canvas id="canvas"></canvas><div id="output"></div> </body> </body> </html>
- 無精・短気・傲慢