ブレッドボードお絵描きの続きです。
スクリプトの引数で、ワイヤーの絵も描くように改造したいと思います。
座標は1始まりの数を使うことにしました。ブレッドボードに印刷されている数字が1始まりだからです。
以下のスクリプトになりました。
1始まりの数指定をするために、このサブルーチンの中では、-1して扱いやすくしています。
8行目で$yを0にしているのは、両端の4列分は穴が少ないので、穴数を超えた指定をされたら0に矯正するようにしています。
1 sub get_board_xxyy{ 2 my($x,$y) = @_; 3 $x-=1; 4 $y-=1; 5 if($x < 4){ 6 my $w = 20; 7 $xx = $x * $w + 15 + ($x >= 2)*285; 8 $y = 0 if($y >= 25); 9 $yy = $y * 20 + 35 + int($y /5) * 20; 10 }else{ 11 my $w = 19; 12 $xx = $x * $w + 10 + ($x >= 9)*32; 13 $yy = $y * 20 + 30; 14 } 15 return ($xx,$yy); 16 }
座標変換のサブルーチンができたので、せっかくなので、ブレッドボードの穴もこれを使って描くように書き直しました。
1 for($x=1;$x<=14;$x++){ 2 for($y=1;$y<=30;$y++){ 3 my($xx,$yy) = get_board_xxyy($x,$y); 4 print qq#<rect x="$xx" y="$yy" width="9" height="9" fill="black" 5 if($x == 5 or $x == 14){ 6 $xx -=10 if($x == 5); 7 $xx +=20 if($x == 14);; 8 $yy +=10; 9 print qq#<text x="$xx" y="$yy" font-size="13" text-ancho 10 } 11 } 12 }
さて、ワイヤーを描くためのサブルーチンを作りますが、先に呼び出し方を決めておきます。
1 put_wire("red",1,1, 5,1);
第1引数は色
第2,3は、始点x1,y1
第4,5は、終点x2,y2とします。
配線用として別途座標変換サブルーチンを別途つくりました。
1 sub get_xxyy{ 2 my($x,$y) = get_board_xxyy(@_); 3 return ($x+4,$y+4); 4 }
ワイヤー処理です。
1 sub put_wire{ 2 my($color,$x1,$y1, $x2,$y2) = @_; 3 my($xx1,$yy1) = get_xxyy($x1,$y1); 4 my($xx2,$yy2) = get_xxyy($x2,$y2); 5 print qq#<circle cx="$xx1" cy="$yy1" r="3" fill="white" />#; 6 print qq#<circle cx="$xx2" cy="$yy2" r="3" fill="white" />#; 7 print qq#<line x1="$xx1" y1="$yy1" x2="$xx2" y2="$yy2" stroke="$color" s 8 9 }
さっそく実行してみます。
さて、これをコマンドラインから指定して実行できるようにします。
1 put_wire(split /,/,$ARGV[0]);
~$ . bread.sh 'red,1,9,6,10'
複数指定できない回路になりませんから、複数指定できるようにしておきます。
1 2 3 a=`perl -e ' 4 foreach(split / /, "0,60 62,125 197,125 324,60"){ 5 my($x,$w) = split /,/,$_; 6 print qq#<rect x="$x" y="0" width="$w" height="650" stroke="black" fill="none"></rect>#; 7 } 8 foreach(split / /, "8:red 50:blue 334:red 376:blue"){ 9 my($x,$c) = split /:/,$_; 10 print qq#<line x1="$x" y1="25" x2="$x" y2="620" stroke="$c" stroke-width="2"/>#; 11 } 12 13 $x=90; 14 foreach $ch (split //,"abcdefghij"){ 15 print qq#<text x="$x" y="20" font-size="15" text-anchor="middle">$ch</text>#; 16 print qq#<text x="$x" y="638" font-size="15" text-anchor="middle">$ch</text>#; 17 $x += 20; 18 $x += 25 if($ch eq "e"); 19 } 20 21 for($x=1;$x<=14;$x++){ 22 for($y=1;$y<=30;$y++){ 23 my($xx,$yy) = get_board_xxyy($x,$y); 24 print qq#<rect x="$xx" y="$yy" width="9" height="9" fill="black"></rect>#; 25 if($x == 5 or $x == 14){ 26 $xx -=10 if($x == 5); 27 $xx +=20 if($x == 14);; 28 $yy +=10; 29 print qq#<text x="$xx" y="$yy" font-size="13" text-anchor="middle">$y</text>#; 30 } 31 } 32 } 33 foreach(@ARGV){ 34 put_wire(split /,/,$_); 35 } 36 37 sub put_wire{ 38 my($color,$x1,$y1, $x2,$y2) = @_; 39 my($xx1,$yy1) = get_xxyy($x1,$y1); 40 my($xx2,$yy2) = get_xxyy($x2,$y2); 41 print qq#<circle cx="$xx1" cy="$yy1" r="3" fill="white" />#; 42 print qq#<circle cx="$xx2" cy="$yy2" r="3" fill="white" />#; 43 print qq#<line x1="$xx1" y1="$yy1" x2="$xx2" y2="$yy2" stroke="$color" stroke-width="8"/>#; 44 45 } 46 47 sub get_xxyy{ 48 my($x,$y) = get_board_xxyy(@_); 49 return ($x+4,$y+4); 50 } 51 52 sub get_board_xxyy{ 53 my($x,$y) = @_; 54 $x-=1; 55 $y-=1; 56 if($x < 4){ 57 my $w = 20; 58 $xx = $x * $w + 15 + ($x >= 2)*285; 59 $y = 0 if($y >= 25); 60 $yy = $y * 20 + 35 + int($y /5) * 20; 61 }else{ 62 my $w = 19; 63 $xx = $x * $w + 10 + ($x >= 9)*32; 64 $yy = $y * 20 + 30; 65 } 66 return ($xx,$yy); 67 } 68 ' $@` 69 70 71 cat <<EOL > /tmp/tmp.svg 72 <svg width="384" height="650"> 73 <rect x="0" y="0" width="384" height="650" fill="white"></rect> 74 $a 75 </svg> 76 EOL 77 inkscape -z -e out.png /tmp/tmp.svg
行数がもう面倒なレベルになってきましたが、使ってみましょう。
~$ r(){ > perl -e '@col=("brown","red","orange","yellow","green","blue"); > printf"%s,%d,%d,%d,%d",@col[int rand(6)], > 1+int rand(4), > 1+int rand(25), > 4+int rand(10), > 1+int rand(30);' > } ~$ ~$ . bread.sh `r` `r` `r` `r` `r` `r` `r` `r` `r`
コメント