おもこん

おもこんは「思いつくままにコンピュターの話し」の省略形です

pregnuplot を作ってみた(3)

pregnuplot を作ってみた(3)

プログラムファイルの続きを示します。

プログラムファイルの続き

このプログラムファイルにバグがありましたので、修正しました。
(2013/3/7 17:38)
#------ gnuplotファイルの出力 ------
$gpfile = $pgpfile;
$gpfile =~ s/.pgp$/.gnu/;
open(OUT, '> '.$gpfile);

print (OUT "#% !TEX TS-program = gnuplot\n");     #gnuplotが%のコメントをサポートしていないため、
print (OUT "#% !TEX encoding = UTF-8 Unicode\n"); #事実上意味ない出力になっている。
print (OUT "#\n");
print (OUT "#グラフ(Pregnuplotにより作成)\n");
print (OUT "#\n");
print (OUT "\n");
print (OUT "#グラフの範囲を設定\n");
foreach $i ('XMIN', 'XMAX', 'YMIN', 'YMAX') {
  if ($pgpdata{$i} eq "") {
    print "$iは必須項目なので入力し直してください\n";
    close OUT;
    exit 1;
  }else {
  print (OUT "$i = $pgpdata{$i}\n");
  }
}

print (OUT "\n");
print (OUT "#座標系(coordinate system)の幅と高さ\n");
print (OUT "CWIDTH = XMAX-XMIN\n");
print (OUT "CHEIGHT = YMAX-YMIN\n");
$CWIDTH = $pgpdata{'XMAX'} - $pgpdata{'XMIN'};
$CHEIGHT = $pgpdata{'YMAX'} - $pgpdata{'YMIN'};
print (OUT "\n");
print (OUT "#軸に書き込む文字の軸からの距離\n");
print (OUT "XDCA = 0.05*CWIDTH\n");
print (OUT "YDCA = 0.05*CHEIGHT\n");
print (OUT "\n");
print (OUT "#出力先\n");
print (OUT "set terminal $pgpdata{'TERMINAL'}\n");
if ($pgpdata{'OUTFILE'} ne ""){
  print (OUT "set output \"$pgpdata{'OUTFILE'}\"\n");
}
print (OUT "\n");
print (OUT "#デフォルトの外側に書かれる座標軸は表示しない\n");
print (OUT "unset border\n");
print (OUT "unset tics\n");
print (OUT "\n");
print (OUT "#矢印の座標軸\n");
print (OUT "set arrow 1 from $pgpdata{'XMIN'},0 to $pgpdata{'XMAX'},0 linestyle -1\n");
print (OUT "set arrow 2 from 0,$pgpdata{'YMIN'} to 0,$pgpdata{'YMAX'} linestyle -1\n");
print (OUT 'set label 1 "$x$" at XMAX-XDCA, -YDCA'."\n");
print (OUT 'set label 2 "$y$" at -XDCA, YMAX-2*YDCA'."\n");
#原点
@temp012 = split(",",&ENWS($pgpdata{'LABELO'}));
print (OUT "set label 3 \"O\" at ($temp012[0])*XDCA, ($temp012[1])*YDCA\n");
#x=a型直線
print (OUT "#x=a型の直線\n");
foreach $i ('XEA0', 'XEA1', 'XEA2', 'XEA3', 'XEA4', 'XEA5', 'XEA6', 'XEA7', 'XEA8', 'XEA9'){
  if ($pgpdata{$i} ne ""){
    print (OUT "set arrow from $pgpdata{$i},YMIN to $pgpdata{$i},YMAX nohead lw 2 lt -1\n");
  }
}
#その他の点のラベル
print (OUT "#点の座標を表すラベル\n");
# 名前、その点のx座標、その点のy座標、ずらす方向、倍率
foreach $i ('LB0', 'LB1', 'LB2', 'LB3', 'LB4', 'LB5', 'LB6', 'LB7', 'LB8', 'LB9') {
  next if ($pgpdata{$i} eq "");
  @tempL = split(",",$pgpdata{$i});
  @temp012 = split(",",&ENWS($tempL[3]));
  print (OUT "set label \"$tempL[0]\" at $tempL[1]+$tempL[4]*($temp012[0])*XDCA, $tempL[2]+$tempL[4]*($temp012[1])*YDCA\n");
}
#点の位置を示す点線
print (OUT "#点の位置を示す座標軸までの点線\n");
# その点のx座標、その点のy座標、点線の行き先(x軸、y軸、両方)
foreach $i ('PL0', 'PL1', 'PL2', 'PL3', 'PL4', 'PL5', 'PL6', 'PL7', 'PL8', 'PL9') {
  next if ($pgpdata{$i} eq "");
  @tempP = split(",",$pgpdata{$i});
  if ($tempP[2] eq "x" || $tempP[2] eq "xy") {
    print (OUT "set arrow from $tempP[0],$tempP[1] to $tempP[0],0 nohead lt 0 lw 3\n");
  }
  if ($tempP[2] eq "y" || $tempP[2] eq "xy") {
    print (OUT "set arrow from $tempP[0],$tempP[1] to 0,$tempP[1] nohead lt 0 lw 3\n");
  }
}
#縦横比
print (OUT "\n");
print (OUT "#縦横比(縦/横)\n");
if ($pgpdata{'RATIO'} ne "") {
  print (OUT "set size ratio $pgpdata{'RATIO'}\n");
}
print (OUT "\n");
#曲線のプロット
print (OUT "#プロット\n");
  print (OUT "plot [XMIN:XMAX] [YMIN:YMAX] \\\n");

foreach $i ('FX0', 'FX1', 'FX2', 'FX3') {
  if($pgpdata{$i} ne ""){
    print (OUT "$pgpdata{$i} lw 2 lt -1 notitle, \\\n");
  }
}

#
#領域描画
#
#除数(divisor)
#  一応30位が適当かと...
# 多くすると斜線の間隔が狭くなる。
$DIV = 30;
#加数(addend)
$ADD = $CHEIGHT / $DIV;
#傾き(inclination)
$INC = $CHEIGHT / $CWIDTH;
if ($pgpdata{'DOMAIN'} ne ""){
  for ($i = $pgpdata{'YMIN'}-$CHEIGHT+$ADD ; $i < $pgpdata{'YMAX'}; $i+=$ADD) { 
    $DOMAIN0 = $pgpdata{'DOMAIN'};
    $DOMAIN0 =~ s/y/(($INC)*(x-XMIN)+($i))/g;
    print (OUT "$DOMAIN0 ? ($INC)*(x-XMIN)+($i) : 1/0 notitle lw 1 lt -1,\\\n");
  }
}
#ダミーのプロット(この前がコンマで終わっているための調整)
print (OUT "1/0 notitle \n");
print (OUT "\n");
close(OUT);

$ecode = system("gnuplot ".$gpfile);
if ($ecode != 0) {
  print "system(gnuplot) returned error code $ecode.\n";
  exit $ecode;
}
exit 0;

#------ ENSW情報から、(x,y)=(0,0)~(-1,-2)を出力 ------
sub ENWS { 
  if    ($_[0] eq "E")   { return '1,0'; }
  elsif ($_[0] eq "N")   { return '0,1'; }
  elsif ($_[0] eq "W")   { return '-1,0'; }
  elsif ($_[0] eq "S")   { return '0,-1'; }
  elsif ($_[0] eq "NE")  { return '1,1'; }
  elsif ($_[0] eq "NW")  { return '-1,1'; }
  elsif ($_[0] eq "SW")  { return '-1,-1'; }
  elsif ($_[0] eq "SE")  { return '1,-1'; }
  elsif ($_[0] eq "NEE") { return '2,1'; }
  elsif ($_[0] eq "NNE") { return '1,2'; }
  elsif ($_[0] eq "NNW") { return '-1,2'; }
  elsif ($_[0] eq "NWW") { return '-2,1'; }
  elsif ($_[0] eq "SWW") { return '-2,-1'; }
  elsif ($_[0] eq "SSW") { return '-1,-2'; }
  elsif ($_[0] eq "SSE") { return '1,-2'; }
  elsif ($_[0] eq "SEE") { return '2,-1'; }
}