トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

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

  • 多角形を書くために頂点の位置を計算する。
  • ラジアン
    • 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;
   }

正七角形とは、各辺と全ての内角の大きさがそれぞれ等しい七角形。ひとつの内角の大きさはラジアン角で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>