ブレッドボードの絵を描くコマンドを作る(ワイヤー編)

旧画像

ブレッドボードお絵描きの続きです。
スクリプトの引数で、ワイヤーの絵も描くように改造したいと思います。
座標は1始まりの数を使うことにしました。ブレッドボードに印刷されている数字が1始まりだからです。
bread2-001
以下のスクリプトになりました。
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	}

さっそく実行してみます。
bread2-002
さて、これをコマンドラインから指定して実行できるようにします。

     1	put_wire(split /,/,$ARGV[0]);
~$ . bread.sh 'red,1,9,6,10'

bread2-003
複数指定できない回路になりませんから、複数指定できるようにしておきます。

     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`

bread2-rand

コメント

タイトルとURLをコピーしました