無精・短気・傲慢

perlの事 いろいろ

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 が成り立つ