ブレッドボードお絵描きの続きです。
スクリプトの引数で、ワイヤーの絵も描くように改造したいと思います。
座標は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`



コメント